sql注入的题目每次CTF必考几乎,虽然我们说起来sql注入好像是通过占位符就不存在了.不过万能的php总是会留下后门的…..唔
0x00. 回顾
之前我们已经会熟练(/菜鸡/) 使用了sqlmap以及简单的万能密码…..然而这个几乎是没有卵用的其实.因为不可能有这么baga的题给你注了….所以重点有二 (这次必须满满都是干货了,)
- 手注
- 自动化脚本 & sqlmap 的tamper
我们在dvwa上可以看到有两个sql injection ,其中有一个加了blind.
盲注,与一般注入的区别在于,一般的注入攻击者可以直接从页面上看到注入语句的执行结果,而盲注时攻击者通常是无法从显示页面上获取执行结果,甚至连注入语句是否执行都无从得知,因此盲注的难度要比一般注入高。
目前网络上现存的SQL注入漏洞大多是SQL盲注。
0x01. 手工实战
1.确定存在注入点
第一个是可显示结果的sql注入(回显式sql注入). low等级直接可以使用 'or 1=1 # 注入.结果如图.
源代码如下:
1 |
|
从sql语句可以看出 SELECT first_name, last_name FROM users WHERE user_id = $id; 那么我们注入 or 1=1 之后就会显示所有数据.成功实现,但是这里要注意. php是有点过分的,这里的poc是可能有三种写法的.单双引号不注意是会疯狂失败的.
mysql 常见的三种注释符号如下:
#(最常见,最不会考…)--(注意两短线后面必须跟空格)/**/(绕过常见,很喜欢考.)
2. order by获取字段数
刚才发现查询到所有用户的信息,难道手注就只能获取这个么? 这个手动输入id也可以呀. 那么我们常见的是获取字段数. (order by)
1 | select * from user where id = $id order by 1; |
构造语句 1'order by 1 # 发现返回正常.说明是字段>=1.然后尝试order by 10 发现报错,说明字段数大于10,然后手动二分. 尝试5 – >尝试3,最后发现2是返回正常. 所以字段数就是2
3. 确定回显点 (union select)
1 | select * from user where id = $id union select 1,2 #; |
union select 联合查询是非常常见的一种常用注入语法,它会返回联合查询的结果集.这样我们可以查询很多数据库的信息,表等等.
这里要注意的是,不能一次查超过字段数的union select ,会提示column 多了. 也注意# 注释可能会不生效….蛋疼
最后根据字段跟表名可以联合查询我们想要的关键信息.
1 | union select user,password from users-- |
如果发现密码是md5加密后的,可以去看看md5反查的网站.
4.文件读取(load_file(), 更新已实现)
CTF先下载本质是为了获取某个文件的flag,那么除了最常见的文件上传/文件包含. sql注入怎么快速获取磁盘文件呢,load_file() 就是一个常见利用. (注意union select 字段数需要保持一致,不能多或少.)
1 | union select 1,load_file('C:\\flag.txt')-- |
然后测试发现….失败了,唔……陷入江局.gif. 尝试过 D:\\ .尝试过D:\ 也尝试过…查询官网定义,都没问题呀,怎么就是不显示文件内容呢? 难道说是因为没有权限?
尝试了20分钟还是没出来…醉了先跳一下吧.
更新: 果然都是因为文件权限的问题,但是这里不报错简直是醉了. 也已经OK.直接读取本地文件的信息了.
5.webshell来了
上面的渗透都是一些边角的信息,那么真正渗透来说,肯定是希望有整个网站的权限的.这样想做什么就可以做什么了. 也就是我们俗称的webshell. 比如之前最经典的一句话eval(); 就是一个webshell.
之前的php文件都是利用上传丢进去的,这样实在太暴力.也太容易被发现. 上一个部分有个利用失败的load_file()…..它还有个好兄弟,那就是outfile.
1 | select .... into outfile ..... |
擦,终于知道为什么我的file上传下载都是失败的了….. mysql开启了文件安全的权限,我的命令都被ban了…….捂头…
很好,发现问题所在就好说了,打开mysql的配置文件my.ini 然后在末尾加上secure-file-priv="" 重启就行了. 不过注意这里phpStduy直接重启很容易端口占用,建议手动结束先. 然后成功之后的效果是这样.
可以发现文件已经成功写入到目录文件下了,尝试执行一下.ok.命令跟提示都成功.
不过上面应该稍微修改一下…把 union select 的前面改成一个不存在的,这样就不会把id=1 时admin 写进去了..
然后我们回到之前没有成功的文件读取以及sqlmap的自动shell看看能不能成功.
0x02. 自动化注入
sqlmap引入了,之前用的太蠢…. 其实sqlmap有很多高级语法,一般我们使用它的level 或者tamper可以绕过很多的屏蔽.
1 | sqlmap.py -u "http://localhost/dvwa/vulnerabilities/sqli/?id=2&Submit=Submit#" -p "id" |
这里-p是指定注入的参数,因为传入的GET请求中还有个submit. 提快速度. 这里直接输入会发现提示302重定向,因为要求登录,如果不登录当然是不行的,请求会一直卡住. 然后就是参数可以一次传入多个,不需要一次次的去获取.
1 | sqlmap.py -u "http://localhost/dvwa/vulnerabilities/sqli/?id=2&Submit=Submit#" -p "id" |
可以发现还自带贴心的普通md5解密噢~ 所以不用大小写英文+数字的朋友们注意了普通的md5其实是非常脆弱的.
然后sqlmap当然也是支持获取webshell的. 通过–os-shell参数自动上传. 但是这里也失败了,提示可能没有文件权限?? excu me?
1 | sqlmap.py -u "http://localhost/dvwa/vulnerabilities/sqli/?id=2&Submit=Submit#" -p "id" |
更新: 从上面手注发现的文件权限然后修改完后再来试试,发现可以了.自动化脚本虽好,但是必须一定要懂得手注的原理.
我们看看sqlmap写的webshell~~
1 | //Gordon Brown ,这里用了一下代码还原...原本是压缩了的,看起来爆炸.. |
可以简单看出,这是什么玩意啊?…… 大量的字符操作,可能是为了掩饰一些危险的函数被waf干掉了直接.那之后有空再拉研究吧….
这里命令跑起来简单,但是我们要开始分析一下背后自动的payload在做什么了.
- 错误回显 (页面报错)
- 延时盲注
- 联合查询注入
- boolean盲注(这里没写,但是常见)
这四种利用手段也是我们常见的四大注入类型










