HackTheBox October Ovrflw

by Vince
in Blog
Hits: 1241

I started playing with the HackTheBox October machine and during my enumeration process, I discovered something and I ended up in a Python rabbit hole.  Before I continue, let me say that I'm jumping straight to a spoiler -- so if you're looking for some subtle hints on entry, I'm past that point with respect to the direction of this post.  Assuming you've ended up here for some other reason, I'm going straight to to the ovrflw file which is vulnerable to a buffer overflow.  If you execute the binary, we see the following:

root@c2:~/hackthebox/October# ./ovrflw
Syntax: ./ovrflw <input string>

If we input a few characters, we get no response.  We assume that we can exceed a certain number of characters to get it to crash.  With buffer overflows, we want to get the exact byte count of the crash so that we can insert our shell code just after that point.  There are any number of ways to get the byte count for this buffer overflow, we could do something like:

root@c2:~/hackthebox/October# ./ovrflw `python -c 'print "A"*112'`
Segmentation fault

The byte count is small enough that you could literally paste a bunch of A's, get it to break, and count the number.  But I wanted to script this in Python.  I thought it would be easy -- feed it a bunch of A's and wait for it to break.  But it didn't break.  Or at least I didn't see it break.  What I expected was stdout to return an error which is a lack of understanding on my part.  And then so began the process of hunting for what I actually wanted which is the returncode.  

After some searching, I discovered that a returncode of -11 is a segmentation fault.  So we're essentially doing the same thing as we're doing above.  We're feeding a bunch of A's, incrementally though, and we're looking for the -11 returncode.  The script looks like this:

#!/usr/bin/python
import time
import subprocess

buffer=["1"]
counter=10
while len(buffer) <= 200:
    buffer.append("A"*counter)
    counter=counter+1

for string in buffer:
    print "Fuzzing with %s bytes" % len(string)
    process = subprocess.Popen(['./ovrflw',string], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = process.communicate()
    print out, err, process.returncode
    time.sleep(.05)
    if process.returncode == -11:
        print "[*] Segmentation fault at %s bytes" % len(string)
        break


I like to slow down the process with the sleep function because I enjoy the anticipation of the crash.  Honestly, I don't know why I'm slowing it down, I just like it better that way.  

This was an unnecessary diversion but I'm fairly confident in my ability to perform a buffer overflow -- more so than my ability to write Python so I don't think the deviation was wasted.