The past few weeks, I’ve been spending a lot of my free time preparing for the OSCP exam, which means refreshing a lot of skills that I haven’t used in years. A large part of that is rebuilding muscle memory around buffer overflows, so that’s how I spent my four-day weekend. I logged about 70 hours compiling small programs, writing buffer overflows, building simple ROP chains, and honestly having a lot of fun.

When I started doing this stuff, Python 2 reigned supreme. These days, Python 3 is more common on systems, but a lot of the materials out there still reference Python 2. One of the things I noticed as I hit a wall myself early in the weekend was that there’s a bit of trickiness involved in ensuring you get the data you want out of Python 3. It was something I came across naturally due to the way I ran my code and when I started Googling, I realized that there were a lot of questions and a few stack overflow responses, but that nobody really laid it out with a detailed explanation of what was going on. So, that’s what I’m going to do … walk you through a peculiarity of Python 2 vs. Python 3 code that may have you banging your head against the wall.

To start, we’ll use msfvenom to generate shellcode and look at the differences in interacting with it:

This code is then placed into a simple Python script, which we run with both Python 2 and Python 3:

Notice the difference between the hex output on our print statement. We have that familiar b’ at the start of our sequence and the ‘ at the end before the 0x0a. Our sequence has been printed out as literal characters. Instead (Read more...)