Openctf 2016-tyro_shellcode1

1.常规checksec,开了Canary和NX,IDA查找漏洞,找到下列奇怪代码:

1
2
3
4
5
6
#注释头

v4 = mmap(0, 0x80u, 7, 34, -1, 0);
-----------------------------------------------------------------------------
read(0, v4, 0x20u);
v5 = ((int (*)(void))v4)();

可以猜出来是输入到v4中,然后v4被强制转换成函数指针被调用。查看汇编代码也可以看到:

img

这里就没办法判断到底[esp+34h]是不是v4了,因为v4是通过mmap申请的一块内存,虽然在栈上,但是并不知道在哪,需要通过调试才能知道,调试之后发现确实是这样。

2.虽然最开始checksec程序,发现开了NX,那么这不就代表没办法shellcode了吗。调试也发现,除了代码段,其它段都没有X属性,都不可执行。但是我们看汇编代码,是call eax,调用的是寄存器,不是程序段,一定可以被调用的,然后eax中保存的内容就是我们输入的内容啊,所以直接输入shellcode就完事,连栈溢出什么的都不用考虑。

3.那么直接从http://shell-storm.org/shellcode/

查找获取就可以。给出一段可用shellcode:

\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80

由于这段shellcode调用的是int80来获取shell的,所以给出下列介绍

▲int 80h:128号中断

1.在32位Linux中该中断被用于呼叫系统调用程序system_call()。

2.read(), write(), system()之类的需要内核“帮忙”的函数,就是围绕这条指令加上一些额外参数处理,异常处理等代码封装而成的。32位linux系统的内核一共提供了0~337号共计338种系统调用用以实现不同的功能。

3.输入的shellcode也就汇编成了EAX = 0Xb = 11,EBX = &(“/bin//sh”), ECX = EDX = 0,等同于执行代码sys_execve(“/bin//sh”, 0, 0, 0),通过/bin/sh软链接打开一个shell。这里sys_execve调用的参数就是ebx的对应的地址。所以我们可以在没有system函数的情况下打开shell。64位linux系统的汇编指令就是syscall,调用sys_execve需要将EAX设置为0x3B,放置参数的寄存器也和32位不同

参考资料:

https://bbs.ichunqiu.com/forum.php?mod=collection&action=view&ctid=157