sql注入漏洞复现
0x00 sql注入
SQL注入是用户从正常的www访问通过全局变量POST和GET提交一些sql语句对数据库的数据进行操作。
0x01 环境搭建
安装MariaDB、PHP、Apache环境:
安装MariaDB:
1 |
|
安装apache:
1 |
|
安装php:
1 |
|
安装php的一些组件:
1 |
|
安装完成后编辑配置文件,然后重启httpd和mariadb。
0x02 搭载存在SQL注入的php页面
首先输入mysql -u root -p
然后输入密码进入数据库,创建一个test的数据库,然后在test里创建一个名为users的表单,表单中写入如下三组数据作为测试数据。
然后在/var/www/html目录创建select.php
在select.php中写入一个存在SQL注入的代码段
1 |
|
这段代码的作用是读取一个输入的变量id,然后通过id查询数据库中这个id对应的username。
测试一下效果,通过读入x=1出现下面结果说明成功。
0x03 手工注入
(1)判断是否存在SQL注入
与一个正确的式子时,结果不变。
与一个错误的式子,结果改变,说明存在注入点。
(2)当前数据库权限判断
提交and ord(mid(user(),1,1))=114如果页面正常则为root权限,下图可以看出是root权限
(3)判断字段数
提交union select * from users order by 数字填猜测的字段数,下图可见,填4可以正常显示,填5不能,所以字段数是4个。
(4)获取数据库库名
获取字段数之后,我们就构造 and 1=2 union select 1,schema_name,3,4 from information_schema.schemata来查询所有数据库名
这里的1一直到4,就是之前找到的四个字段,然后information_schema库的schemata表中的schema_name字段就存着数据库名。
(5)获取数据库表名
获取数据库名之后,我们就构造 and 1=2 union select 1,table_name,3,4 from information_schema.tables where table_schema=0x76657374来查询test数据库下的所有表名
这里的1一直到4,就是之前找到的四个字段,然后information_schema库的tables表中的table_name字段就存着表名,where后面的限定条件用来选择数据库,等号后面填数据库ascii编码的十六进制(如test是0x76657374)。
(6)获取数据库字段名
获取数据库名和表名之后,我们就构造 and 1=2 union select 1,column_name,3,4 from information_schema.columns where table_name=0x7573657273 and table_schema=0x76657374来查询test数据库下users表中的所有字段名。
这里的1一直到4,就是之前找到的四个字段,然后information_schema库的columns表中的column_name字段就存着字段名,where后面的限定条件用来选择数据库和对应表,等号后面填数据库和表的ascii编码的十六进制(如test是0x76657374,users是0x7573657273)。
(7)获取数据
已经获取了字段名和其顺序,我们知道了之前输出的位置是1,2号位的id和username,然后我们需要输出password和email到1,2号位,所以构造
and 1=2 union select email,password,3,4 from test.users
来查询test数据库下users表的email和password,获取这些数据。
0x04 sqlmap注入
使用sqlmap时我们有以下几种探测方式
参数:–technique
这个参数可以指定sqlmap使用的探测技术,默认情况下会测试所有的方式。
支持的探测方式如下:
- B: Boolean-based blind SQL injection(布尔型注入)
- E: Error-based SQL injection(报错型注入)
- U: UNION query SQL injection(可联合查询注入)
- S: Stacked queries SQL injection(可多语句查询注入)
- T: Time-based blind SQL injection(基于时间延迟注入)
我们先用默认方式测试一下:
先查看有哪些数据库:
sqlmap -u “192.168.0.104/select.php?x=1” –dbs
然后查看test数据库中的所有表:
sqlmap -u “192.168.0.104/select.php?x=1” -D test –tables
然后查看users表中所有字段:
sqlmap -u “192.168.0.104/select.php?x=1” –D test -T users –columns
然后查看password字段中所有值:
sqlmap -u “192.168.0.104/select.php?x=1” –D test -T users -C password –dump
0x05 抓包分析
我们再对其中几种注入方式进行抓包分析:
sqlmap Union注入
可联合查询注入,通过UNION查询获取到所有想要的数据。
使用场景:请求返回后能输出SQL执行后查询到的所有内容。
sqlmap -u “192.168.43.63/select.php?x=1” -D test –tables –technique=U
从wireshrak抓包可以看到,只通过http请求从返回的信息中获取数据。
sqlmap Boolean Based注入
布尔型注入,可以根据返回页面判断条件真假的注入。
使用场景:我们无法根据应用程序的返回页面得到我们需要的数据库信息。但是可以通过构造逻辑判断(比较大小)来得到我们需要的信息。
sqlmap -u “192.168.43.63/select.php?x=1”–dbs –technique=B
从wireshark抓包我们可以看到,sqlmap一直在构造逻辑,然后通过反回的Error(500)或者ok(200)来得到信息。
sqlmap Time Based注入
基于时间的盲注,即不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断。
应用场景 : 页面不会返回错误信息,不会输出UNION注入所查出来的泄露的信息。类似搜索这类请求,boolean注入也无能为力,因为搜索返回空也属于正常的,这时就得采用time-based的注入了,即判断请求响应的时间,但该类型注入获取信息的速度非常慢。
sqlmap -u “192.168.43.63/select.php?x=1” –dbs –technique=T –flush-session
因为之前已经抓取到了数据库,为了防止结果影响,在这里加入–flush-session参数来清空之前的session,重新测试该目标。
从wireshark中可以看出,sqlmap在构造sleep函数,不通过返回来判断结果,而是通过返回的时间是否在预期内来判断是否存在注入点。
0x08 危害
- 入侵者可以通过网页来提交mysql语句对公司数据库敏感数据进行读取,配合python脚本可以获取整个数据库的数据。
- 入侵者可以对公司数据库数据进行篡改,造成巨大损失。
- 入侵者可以私自添加系统账号或是数据库使用者账号,拿到webshell,然后进而控制整个web服务器。
0x09 应对方案
1.对输入参数进行验证
2.特殊字符过滤
3.使用参数化语句,不要拼接sql
4.编码输出
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!