我在 64 位 Linux 上使用 Python 2.7。我有以下 Python 脚本女巫应该执行一个简单的 Hello World shellcode。
import urllib2
import ctypes
shellcode = "\xb8\x01\x00\x00\x00\xbf\x01\x00\x00\x00\x48\xbe\xd8\x00\x60\x00\x00\x00\x00\xba\x0e\x00\x00\x00\x0f\x05\xb8\x3c\x00\x00\x00\xbf\x00\x00\x00\x00\x0f\x05"
#Create buffer in memory
shellcode_buffer = ctypes.create_string_buffer(shellcode, len(shellcode))
#Funktionszeiger
shellcode_func = ctypes.cast(shellcode_buffer, ctypes.CFUNCTYPE(ctypes.c_void_p))
#Shellcode execute
shellcode_func()
如果我运行 python Scriptname.py
,我会遇到内存访问错误。这里有人知道为什么我的脚本不起作用吗?
编辑: 原始 ASM 代码:
section .data
text db "Hello",10
section .text
global _start
_start:
;syscall sys_write(1, text, 14)
mov rax, 1
mov rdi, 1
mov rsi, text
mov rdx, 14
syscall
;syscall sys_exit(0)
mov rax, 60
mov rdi, 0
syscall
最佳答案
您将需要使您的 shellcode 在具有读/写/执行权限的内存位置运行的 python 代码。因为它是您运行 shell 代码的内存,所以不在可执行内存中。您可以创建一个函数来为您执行此操作 (testshellcode.py
):
import ctypes, mmap, sys
# Convert string to bytes object. Differs between Python2 and Python3
if sys.version_info >= (3, 0):
def b(string, charset='latin-1'):
if isinstance(string, bytes) and not isinstance(string, str):
return (string)
else:
return bytes(string, charset)
else:
def b(string):
return bytes(string)
def create_shellcode_function (shellcode_str):
shellcode_bytes = b(shellcode_str)
# Allocate memory with a RWX private anonymous mmap
exec_mem = mmap.mmap(-1, len(shellcode_bytes),
prot = mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC,
flags = mmap.MAP_ANONYMOUS | mmap.MAP_PRIVATE)
# Copy shellcode from bytes object to executable memory
exec_mem.write(shellcode_bytes)
# Cast the memory to a C function object
ctypes_buffer = ctypes.c_int.from_buffer(exec_mem)
function = ctypes.CFUNCTYPE( ctypes.c_int64 )(ctypes.addressof(ctypes_buffer))
function._avoid_gc_for_mmap = exec_mem
# Return pointer to shell code function in executable memory
return function
# linux machine code
shellcode = "shell code string here"
# Create a pointer to our shell code and execute it with no parameters
create_shellcode_function(shellcode)()
代码应该适用于 Python2.7+ 和 Python3
即使您将 shell 代码字符串插入到上面测试程序中的字节对象中,它也会失败。您的 shell 代码字符串似乎缺少字符串本身 (hello
);似乎没有正确编码,您依赖于 text
标签的静态内存位置。您将需要一个与位置无关的地址。
要修复代码使其与位置无关,您可以使用 RIP 相对寻址。将字符串放在代码部分之后的 .text
中,而完全忘记 .data
。这个版本应该足够了(shellcode.asm
):
section .text
global _start
_start:
;syscall sys_write(1, text, text_len)
mov rax, 1
mov rdi, 1
lea rsi, [rel text] ; RIP Relative addressing for Position independent code
mov rdx, text_len ; text length computed by assembler
syscall
;syscall sys_exit(0)
mov rax, 60
mov rdi, 0
syscall
text db "Hello",10
text_len EQU $-text ; Rather than hard coding length compute text length
使用 OBJDUMP 将 shell 代码程序转换为 shell 代码字符串可能会出现问题。我写了一个Stackoverflow Answer讨论 OBJDUMP 方法的一些缺陷。如果您正在创建一个可执行文件来独立测试您的 shell 代码,那么最好将其汇编并链接到一个可执行文件;使用 OBJCOPY 将可执行文件转换为二进制文件,然后使用某些东西(如 HEXDUMP)将二进制文件转换为 shell 代码字符串。以下命令应该有效:
nasm -f elf64 shellcode.asm -o shellcode.o
ld shellcode.o -o shellcode
objcopy -O binary shellcode shellcode.bin
如果你运行独立的二进制shellcode
,它应该输出:
Hello
然后您可以将 shellcode.bin
转换为 shell 代码字符串:
hexdump -v -e '"\\""x" 1/1 "%02x" ""' shellcode.bin
输出看起来像这样:
\xb8\x01\x00\x00\x00\xbf\x01\x00\x00\x00\x48\x8d\x35\x13\x00\x00\x00\xba\x06\x00\x00\x00\x0f\x05\xb8\x3c\x00\x00\x00\xbf\x00\x00\x00\x00\x0f\x05\x48\x65\x6c\x6c\x6f\x0a
然后您可以将此 shell 代码字符串插入上面的 python 程序 (testshellcode.py
),用上面的字符串替换 此处的 shell 代码字符串。您可以运行上面的脚本:
python testshellcode.py
输出应该是:
Hello
这是更高级的,并且有 shell 代码教程解释了许多避免字符串中出现 \x00
字节的技巧。
通常,对于 shell 代码,您希望消除 NUL (\x00
) 字节以进行真正的字符串攻击。执行此操作的 shellcode.asm
版本可能类似于:
section .text
global _start
_start:
jmp afterdata
text db "Hello",10
text_len EQU $-text
afterdata:
;syscall sys_write(1, text, text_len)
xor eax, eax
inc eax
mov edi, eax
lea rsi, [rel text]
xor edx, edx
mov dl, text_len
syscall
;syscall sys_exit(0)
xor eax, eax
mov al, 60
xor edi, edi
syscall
如果您使用前面提到的命令创建 shell 代码字符串,HEXDUMP 应该生成如下内容:
\xeb\x06\x48\x65\x6c\x6c\x6f\x0a\x31\xc0\xff\xc0\x89\xc7\x48\x8d\x35\xed\xff\xff\xff\x31\xd2\xb2\x06\x0f\x05\x31\xc0\xb0\x3c\x31\xff\x0f\x05
此版本与您的代码执行相同的操作,但请注意字符串中没有 \x00
字节。运行时,它也应该打印:
Hello
关于python - x86_64 执行 Shellcode 失败 :,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50686320/