OverTheWire Natas 0-27

Level0

查看页面源码,可以看到

Level1

同Level0,可从菜单内打开开发者工具查看源码

Level2

源码内原来放密码的地方变成了一张图

图片本身没有什么特殊的,但是访问/files可以看到一个users.txt,里面存着natas3的密码

sJIJNW6ucpu6HPZ1ZAchaDtwd7oGrD14

Level3

这次信息变成了

注意后一句话,查看/robots.txt可以看到一个被禁止的目录

进去只有一个users.txt,里面存着natas4的密码

Z9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ

Level4

提示信息

修改HeaderReferer: http://natas5.natas.labs.overthewire.org/之后访问,得到natas5的密码

iX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq

Level5

提示信息

查看Cookie可以看到loggedin=0,修改成1后访问,得到natas6的密码

aGoY4q2Dc6MgDq4oL4YtoKtyAg9PeHa1

Level6

PHP源码

于是访问/includes/secret.inc,得到$secret = "FOEIUWGHFEEUHOFUOIU";

提交后得到natas7的密码

7z3hEENjQtflzgnT29q7wAvMNfZdh0i9

Level7

提示信息

注意到主页的uri是/index.php?page=home

尝试访问/index.php?page=/etc/natas_webpass/natas8,得到natas8的密码

DBfUBfqQG69KvJvJ1iAbMoIpwSNQ9bWe

Level8

PHP源码

于是运行以下python代码算出原始secret

得到oubWYf2kBq,提交后得到natas9的密码

W0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl

Level9

PHP源码

参考Level7,猜测可以从/etc/natas_webpass/natas10得到密码

于是提交. /etc/natas_webpass/natas10;,得到natas10的密码

nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu

Level10

PHP源码

可见过滤了;|&,于是去掉Level9末尾的;,提交. /etc/natas_webpass/natas11

只查看/etc/natas_webpass/natas11的部分,得到natas11的密码

U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK

Level11

PHP源码核心部分

根据key做了一个简单的xor加密

加密后的数据为ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw=

加密前的数据为{"showpassword":"no","bgcolor":"#ffffff"}

于是运行以下python代码尝试得到key

算出qw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jq,得到keyqw8J

将data修改为{"showpassword":"yes","bgcolor":"#ffffff"}

用算出的key加密得到新的cookieClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK

用新的cookie访问得到natas12的密码

EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3

Level12

PHP源码核心部分

未对扩展名做检测,于是将表单中 filename 项改为.php结尾,上传如下文件

之后访问上传上去的php页面得到natas13的密码

jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY

Level13

PHP源码,与Level12不同的部分

这次加了一个文件头的检测,于是我们加一个假的文件头,变成

之后访问上传上去的php页面得到natas14的密码

Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1

Level14

PHP源码

只需要这个SQL语句有结果就行了,于是username里填上" OR 1=1;#,让这个语句返回所有结果,password随便打点什么上去。得到natas15的密码

AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J

Level15

PHP源码

总之先测试一下用户名,发现natas16确实存在;从代码里可以看出,我们只能知道这个语句返回的结果是否大于0,那么下一步只有盲注密码了…

看了看数据库定义,password最长为64,字符范围根据之前的密码应该是[0-9A-Za-z],然后写个脚本慢慢跑吧…

最后拿到natas16的密码

WaIHEacj63wnNIBROHeqi3p9t0m5nhmh

Level16

PHP源码

把大部分特殊字符都过滤了,不过$key是包在双引号里的,所以可以用$(statements)的方式来执行语句返回一个结果到$key里,其余的思路跟上一题差不多

最后拿到natas17的密码

8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw

Level17

PHP源码

基本思路跟Level15一样,但是不能靠返回的内容判断了,所以只有靠sleep来盲注了,碰到网络波动就比较尴尬了…保险一点的话sleep的时间得设长一点

先试试natas18" AND SLEEP(10)#,确定用户名确实是natas18,剩下的部分就跟Level15大同小异了,因为二分在这里太慢,这里就直接判断了,并且各个位并行请求

最后拿到natas18的密码

xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP

Level18

PHP源码核心部分

大概就是读了下cookie里的PHPSESSID,然后就当你是这个session对应的用户了,猜测这640个id里肯定有一个是admin的,于是直接穷举吧…

最后拿到natas19的密码

4IwIrekcuZlA9OsjOkoUtwU6lhokCPYs

Level19

没有给源码

总之先弄几个ID看看吧,拿到了

3433302d61646d696e
3130302d61646d696e
3237342d61646d696e

大概是3x3x3x2d61646d696e的感觉,剩下的部分跟上一题一样了

最后拿到natas20的密码

eofm3Wsshxc5bwtVnEuGIlr7ivb9KABF

Level20

PHP源码核心部分

注意到读session的函数里是直接按照\n切割,而保存的时候没有对value做任何检查,于是在value里插一个换行符就可以了,拿到natas21的密码

IFekPyrQXftziDEsUr3x21sYuahypdgJ

Level21

按他的指示去隔壁,PHP源码核心部分

直接在表单里加个admin项,填1就行了…拿到natas22的密码

chG9fbe1Tq2eWVMgjYYD1MsfIvN461kJ

Level22

PHP源码

url里加个?revelio=1就行,Postman/Burp或者写脚本不自动跟随重定向就可以看到密码。拿到natas23的密码

D0vlad33nQF0Hz2EP255TP5wSW9ZsRSE

Level23

PHP源码

尴尬的隐式类型转换…填11iloveyou就好。拿到natas24的密码

OsRmXFguozKpTZZ5X14zNO43379LZveg

Level24

PHP源码

看看文档,发现这么一句strcmp("foo", array()) => NULL + PHP Warning,然后就把passwd改成passwd[],不填内容提交,会出现Warning和密码。拿到natas25的密码

GHF6X7YwACaYYssHVY05cFq83hRktl4c

Level25

PHP源码

注意到网页内容是include进来的,而且logRequest内有一个可以让我们填任意字符的地方,那么下一步就是想办法让它include进来这个log文件。

检查目录遍历的函数里只替换了一次../,所以如果我们输入....//的话,替换之后就变成了../,多重复几次就可以到达根目录,然后访问到log文件了。

最后在UA里插一段<?php include('/etc/natas_webpass/natas26') ?>就可以拿到密码了。

拿到natas26的密码

oGgWAJ7zcGT28vYazGo4rkhOPDhBu34T

Level26

PHP源码核心部分

发现用到了unserialize,代码里还有个奇怪的Logger。于是自己试了试,发现serialize会把实例内部属性给dump出来,然后unserialize的时候会去读属性,这样构造函数不一定能用上,不过析构函数是肯定可以用得上的…于是写了下面的php代码来试图往img目录里写一个php文件

然后访问img/yoooo.php,拿到natas27的密码

55TBjpPZUUJgVP5b3BnbG6ON9uDPVzCJ

Level27

PHP源码

大概是看一下有没有这个用户名,有的话检测用户名和密码这一对数据是否存在,如果存在就去拿用户名对应的数据;如果没有这个用户名就创建一个新的。

那么下一步要做的应该是自己插一个natas28用户进去了…然而这代码并没有可以让我们注入的地方…尴尬…

看了看开头的注释,username长度只有64,然后翻了翻MySQL的文档,注意到

Before MySQL 5.0.3, trailing spaces are removed from values when they are stored into a VARCHAR column; this means that the spaces also are absent from retrieved values.

也就是说后面的空格会被删掉,于是尝试令username=natas28+57个空格,发现此时还是会当natas28处理。

然后尝试令username=natas28+57个空格+1个任意字符,password留空,这时validUser返回了False,于是系统会尝试插入这个用户,首先末尾超出的字符被截断,只留下natas28+57个空格,然后末尾空格被删掉,只留下natas28。这样就成功插入了一个新的natas28用户。

最后拿到natas28的密码

JWwR438wkgTsNKBbcJoowyysdM82YjeF
comments powered by Disqus