3

This is the code to run shellcode using ctype. The shellcode runs "whoami" on a 64 bit linux. But this program gives me a "segmentation fault". But I m unable to figure out the error in it. The structure of the code is from: ctypes: Cast string to function?

#!/usr/bin/python

from ctypes import *

# /usr/bin/whoami
shellcode_data = ("\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68\x00\x53"
"\x48\x89\xe7\x68\x2d\x63\x00\x00\x48\x89\xe6\x52\xe8\x10\x00"
"\x00\x00\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x77\x68\x6f\x61"
"\x6d\x69\x00\x56\x57\x48\x89\xe6\x0f\x05");

shellcode = c_char_p(shellcode_data)
function = cast(shellcode, CFUNCTYPE(None))
function()

For 32bits architectures this will be the shell code:

shellcode_data = ("\x6a\x0b\x58\x99\x52\x66\x68\x2d\x63\x89\xe7\x68\x2f\x73\x68"
"\x00\x68\x2f\x62\x69\x6e\x89\xe3\x52\xe8\x10\x00\x00\x00\x2f"
"\x75\x73\x72\x2f\x62\x69\x6e\x2f\x77\x68\x6f\x61\x6d\x69\x00"
"\x57\x53\x89\xe1\xcd\x80");

1 Answer 1

5

The NX Bit prevents random data being executed on modern processors and OSs. To get around it, call mprotect. You should also define your shellcode as a binary instead of a character string, like this:

#!/usr/bin/python
import ctypes
shellcode_data = (b"\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68\x00\x53"
    b"\x48\x89\xe7\x68\x2d\x63\x00\x00\x48\x89\xe6\x52\xe8\x10\x00"
    b"\x00\x00\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x77\x68\x6f\x61"
    b"\x6d\x69\x00\x56\x57\x48\x89\xe6\x0f\x05")

shellcode = ctypes.create_string_buffer(shellcode_data)
function = ctypes.cast(shellcode, ctypes.CFUNCTYPE(None))

addr = ctypes.cast(function, ctypes.c_void_p).value
libc = ctypes.CDLL('libc.so.6')
pagesize = libc.getpagesize()
addr_page = (addr // pagesize) * pagesize
for page_start in range(addr_page, addr + len(shellcode_data), pagesize):
    assert libc.mprotect(page_start, pagesize, 0x7) == 0

function()
Sign up to request clarification or add additional context in comments.

1 Comment

@J.F.Sebastian Indeed, modern Python versions put the value of shellcode_data into a page that can't be munprotected. However, I believe in these cases the assertion should fail. create_string_buffer seems to work on cpython at the moment.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.