我正在尝试使用 ruby Fiddle 标准库到 Windows API 来运行 shellcode
代码的想法是
- 具有可执行任何内容的十六进制 shellcode 原始代码(例如 MessageBoxA)
- 称呼
kernel32.dll
- 为这个 shellcode 分配内存。
VirtualAlloc
- 为这个 shellcode 创建一个缓冲区
- 将 shellcode 移至该分配。
RtlMoveMemory
- 创建一个新线程来执行该 shellcode。
CreateThread
- 等待执行/线程结束。
WaitForSingleObject
这是代码:
require 'fiddle'
require 'fiddle/import'
require 'fiddle/types'
shellcode = # MessageBoxA
"\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42" +
"\x08\x8b\x72\x20\x8b\x12\x80\x7e\x0c\x33\x75\xf2\x89\xc7\x03" +
"\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x31\xed\x8b" +
"\x34\xaf\x01\xc6\x45\x81\x3e\x46\x61\x74\x61\x75\xf2\x81\x7e" +
"\x08\x45\x78\x69\x74\x75\xe9\x8b\x7a\x24\x01\xc7\x66\x8b\x2c" +
"\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf\xfc\x01\xc7\x68\x79\x74" +
"\x65\x01\x68\x6b\x65\x6e\x42\x68\x20\x42\x72\x6f\x89\xe1\xfe" +
"\x49\x0b\x31\xc0\x51\x50\xff\xd7"
include Fiddle
kernel32 = Fiddle.dlopen('kernel32')
puts "[-] VirtualAlloc"
ptr = Function.new(kernel32['VirtualAlloc'], [4,4,4,4], 4).call(0, (shellcode.size), 0x3000, 0x40)
Function.new(kernel32['VirtualProtect'], [4,4,4,4], 4).call(ptr, shellcode.size, 0, 0)
puts "[-] Create buffer"
buf = Fiddle::Pointer[shellcode]
puts "[-] RtlMoveMemory"
Function.new(kernel32['RtlMoveMemory'], [4, 4, 4], 4).call(ptr, buf, shellcode.size)
puts "[-] CreateThread"
# thread = Function.new(kernel32['CreateThread'], [4, 4, 4, 4, 4, -4], 4).call(0, 0, ptr, 0, 0, 0)
thread = Function.new(kernel32['CreateThread'], [4,4,4,4,4,4], 4).call(Fiddle::NULL, 0, ptr, 0, 0, 0)
pp Function.new(kernel32['WaitForSingleObject'], [4,4], 4).call(thread, -1)
问题是 MessageBoxA 永远不会被执行,当我尝试绑定 shell 时,TCP 连接在我连接时成功启动,但我无法执行命令,并且一旦我发送任何东西(如按两次回车)它就会结束。
我检查了缓冲区buf
大小和内容buf.size
,buf.to_str
它是准确的。
我在这里错过了什么吗?
谢谢!
注意:我不想直接调用 MessageBoxA API,我需要从 shellcode 中执行它。