MoLing
- 关注
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
作为一个才入门的Web安全小玩家,今天来总结一下我的SQL注入学习之路。。。。如果其中有什么错误,望各位小哥哥小姐姐指正,小女子不胜感激。
0x00 SQL注入是什么?
SQL注入通过输入一些恶意的sql语句来修改后台数据库操作语句,执行注入语句已达到对数据库的增删改查(CRUD),甚至于数据库提权等。所以很多书籍或者机构的课程都会花较大篇幅去讲解SQL注入模块,学习SQL注入原理有利于后期的sqlmap以及waf绕过的学习。
0x01 SQL注入的危害?
猜解后台数据库 ==》 这是利用最多的方式,通过猜解数据库,可盗取网站的敏感信息。
绕过验证 ==》 绕过验证登录网站后台
后台登陆语句:SELECT * FROM admin WHERE Username='user' and Password='pass'
万能密码:’ or '1'='1' #
数据库提权 ==》注入可借助数据库的存储过程进行提权等操作
植马(即传入木马),dos(造成拒绝服务攻击)
0x02 SQL注入的基本流程
判断是否存在注入并判断是字符型还是数字型注入
判断查询列数,回显位置
获取数据库信息
破解加密数据
提升权限
内网渗透
0x03 SQL注入的分类
根据注入变量类型分类:
- 数字型 ==》 http://127.0.0.1/sqli/Less-2/?id=1 and 1=2 --+
- 字符型 ==》 http://127.0.0.1/sqli/Less-1/?id=1' # 也可以 ?id=1' and ‘1’=‘1 来闭合
根据注入请求方式分类:
- Get 方式 ==》 使用hackbar修改url,进行sql注入
- POST 方式 ==》 可通过burpsuite抓包,修改post的数据进行传值的修改和sql注入
根据注入方式分类:
- 联合查询注入 ==》 union操作符用于合并两个或多个select语句的结果集
- 报错型注入 ==》 即页面不会回显注入数据,只能通过页面报错来判断语句的正确与否
- 堆查询注入 ==》
- 盲注 ==》 盲注既不能看到数据的回显,也没有报错
1.布尔盲注 通过sql的函数来逐个读取字符串,通过页面是否正常显示来判断猜解内容是否正确
2.时间盲注 通过sleep函数来判断猜解内容是否正确(sleep()内的数值建议设置在5-10s)
根据编码问题:
- 宽字节注入 ==》 由于网站会设置一些对用户输入内容的转义,通过编码,能够使我们注入语句中的单引号等符号得到正确显示
0x04 Union联合查询
UNION操作符用于合并两个或多个select语句的结果集,注意:UNION内部的SELECT语句前后必须有相同数量的列,列也必须有相似的数据类型,同时每条SELECT语句中的列的顺序必须相同。
SQL UNION 语法:
SELECT column_name FROM tables1 UNION SELECT column_name FROM tables2
注释:默认的,UNION操作符选取不同的值,如果允许重复,请使用UNION ALL
以sql-labs-master靶场第一关为例:
0x05 报错注入
1.原理:
这是一种页面响应形式,响应过程如下:用户在前台页面上输入检索内容时,后台将前端页面上输入的内容不加区别的拼接成sql语句在数据库执行。数据库将执行结果返回给后台。后台将数据库执行结果不加区别的显示到前台页面。
2.条件:
MySQL报错信息必须能够在页面回显:区分php报错和mysql报错。报错注入页面没有显示位,但有sql语句执行错误信息,输出-1' and extractvalue(1, concat( '~' ,(select version() limit 0,1))) --+
3.要求:
4.报错注入步骤:(判断闭合后)
可以引入substr( )函数和ascii( )函数进行单个字符的比较以及ASCII码的判断。注意:updatexml读取字符的长度只能是32位。若读取数据太长需要切片儿,如下:
5.报错注入的各种姿势:
0x06 盲注
1.布尔盲注
http://127.0.0.1/webug/control/sqlinject/bool_injection.php?id=1' and (select count(schema_name) from information_schema.schemata)=15 --+
功能:截取字符串功能
返回值:为截取后的字符串
参数:string为操作字符串, start为开始位置, length为截取长度
举例1:
$ret = substr("hello kali'",2,4);
ret= "ello";
举例2:
substr(database(),1,1)>'a' //判断数据库名第一位是否大于a; 再查看其他位进行判断
功能: 返回字符串string最左边的n个字符串
返回值: string最左边的n个字符串
参数:string为操作字符串,n为截取长度
举例1:
$ret = left("redhat",3);
ret= "red";
举例2:
left(database(),2)='sa' #判断数据库名前2个字符是否位sa;再查看其他位进行判断
功能:截取字符串功能==substr( )
返回值:为截取后的字符串
参数:string为操作字符串,start为开始位置, length为截取长度
举例1:
$ret = mid("hello kali",2,4);
ret=“ello";
举例2:
mid(database0,1,1)>'a' #判断数据库名第一位是否大于a;再查看其他位进行判断
功能: str为字符或者字符串,用于返回字符或字符串最左边的ascii码,有时候服务器会对单引号进行转义,使用ASCII码就不用使用单引号参数:(功能和ord-样)
参数: char为操作;
返回值:返回字符char的asi码
举例1:
$ret = ascii('a');
ret= 97;
举例2:
ascii(mid(database(),1,1))> 114 #意为检测database()的第一-位ASCI码是否大于114,即是'r'
2. 时间盲注
判断闭合方式
http://127.0.0.1/pikachu/vul/sqli/sqli_blind_t.php?username=kobe' and sleep(5) #&submit=%E6%9F%A5%E8%AF%A2
判断数据库名(pikachu)
http://127.0.0.1/pikachu/vul/sqli/sqli_blind_t.php?name=vince' and if(ascii(substr((select database()),1,1))=112,sleep(5),1) --+&submit=%E6%9F%A5%E8%AF%A2
数据表(httpinfo)
http://127.0.0.1/pikachu/vul/sqli/sqli_blind_t.php?name=vince' and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='pikachu'),1,1))=104,sleep(5),1) --+ &submit=%E6%9F%A5%E8%AF%A2
列名(id userid ipiddress useragent httpaccep )
http://127.0.0.1/pikachu/vul/sqli/sqli_blind_t.php?name=vince' and if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='httpinfo' and table_schema='pikachu'),1,1))=104,sleep(5),1) --+
②使用到的函数
0x07 常见四种注入分析
0x08 宽字节注入
1.注入原理:
一个GBK汉字占两个字节,每个字节有自己的取值范围,如果设置GBK编码后,遇到连续两个字节,都符合GBK取值范围,会自动解析为一个汉字。Addslashes函数防止sq|注入,将传入参数值进行转义。例如将’转义为\ ,这样我们在注入的时候闭合单引号就会变成id= '1\' 这样会导致闭合失败从而注入失败。
2.涉及的函数
mixed preg_ replace( mixed $pattern, mixed $replacement, mixed $subject[, int $limit = -1[, int &$count]] )
3.宽字节注入防御
②使用mysql_real _escape_string进行转义
原理是,mysql_real_escape_ string与addslashes的不同之处在于其会考虑当前设置的字符集,不会出现前面e5和5c拼接为一个宽字节的问题,但是这个“当前字符集"如何确定呢?就是使用mysql_set_charset进行指定。上述的两个条件是”与”运算的关系,少一条都不行。
0x09 堆查询注入
1.什么是堆叠注入?
在SQL中,分号( ; )是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sq|语句后继续构造下一条语句,会不会一 起执行?因此这个想法也就造就了堆叠注入。而union injection (联合注入)也是将两条语句合并在一-起,两者之间有什么区别么? 区别就在于union或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。
2.堆叠注入局限性
局限1:堆叠注入的局限性在于并不是每一个环境下都可以执行,可能受到API或者数据库引擎不支持的限制,权限不足也可以解释为什么攻击者无法修改数据或者调用一些程序。
局限2:虽然堆叠查询可以执行任意的sql 语句,但这 种注入方式并不是十分完美。在web系统中,因为代码通常 只返回一个查询结果,因此,堆叠注入第二个语句产生错误或者结果只能被忽略,我们在前端界面是无法看到返回结果的。因此,在读取数据时, 建议使用 union (联合)注入。同时 在使用堆叠注入之前,我们也是需要知道一些数据库相关信息的,例如表名,列名等信息。
0x0A 其他类型注入
1.二次注入
二次注入可以理解为,攻击者构造的恶意数据存储在数据库后,恶意数据被读取并进入到SQL查询语句所导致的注入。防御者可能在用户输入恶意数据时对其中的特殊字符进行了转义处理,但在恶意数据插入到数据库时被处理的数据又被还原并存储在数据库中,当Web程序调用存储在数据库中的恶意数据并执行SQL查询时,就发生了SQL二次注入。二次注入 也称为存储型注入。
二次注入,可以概括为以下两步:
第一步:插入恶意数据
进行数据库插入数据时,对其中的特殊字符进行转义处理,在写入数据库时又保留了原来的数据。
第二步:引用恶意数据
开发者默认存入数据库的数据都是安全的,在进行查询时,直接从数据库中取出恶意数据,没有进行进一步的检验的处理。
2.二次编码注入(部分函数可见前宽字节注入)
现通常Web应用程序大多都会进行参数过滤,来防止注入。如果某处使用了urldecode或者 rawurldecode 函数,则会导致二次解码生成单引号二引发注入,即二次注入。
Web应用程序通常使用addslashes() 、mysql_real_escape_string()、mysql_escape_string()函数或者开启GPC来防止注入,也就是给单引号(‘’)、双引号(“”)、反斜杠(\)和NULL加上反斜杠转义。
原理:由于我们提交id参数到webserver时,webserver会自动解码一次,假设目标程序开启了GPC,我们提交参数id=1%2527 ,经过第一次解码后,%25解码结果为%,则参数为id=1%27,第二次程序使用了urldecode 或者 rawurldecode 函数来解码id参数,则解码后结果为id=1’ ,这时单引号成功出现引发注入。
3.dnslog注入
0x0B 参考文章
https://blog.csdn.net/qq_36711453/article/details/83714363 关于二次注入部分
https://xz.aliyun.com/t/2869 其他注入方式
0x0C 小结
在写这个文章得过程中仍然发现自己在很多知识的理解和使用上存在欠缺,希望在日后的生活中能够慢慢练熟,摸透。。。如果文中哪些知识点存在问题,请您指正,不甚感激。。。学安全,菜是原罪,只能好好努力啦。。
然后我这里有关于sql,xss,dvwa,webug,pikachu,文件上传等一些靶场,还有大佬总结的sql-labs-master的通关宝典,有需要私信我。。。加油啦,终于知道学安全的女娃儿为啥这么少了。。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)





