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()