Category - Codegate2020

用python的llvmlite库实现了一个brainfuck的解释器。通过runtime.so的动态库中的ptrBoundChk做了内存边界检查,可读写的范围被限定在了[DATA+0x10, DATA+0X3010]的范围。所以解题的关键在于如何绕过边界检查。

先来看一下程序的几个关键函数:bfProgram用于将brainfuck语言转换成shortended_code的形式,就是一系列(state, imm)的二元组。codegen函数用于将上述的二元组转换成为llvm的IR,compile将IR转换成为x86的机器码。execute自然就是用于执行机器码。

这里的重点是在生成IR的过程中为了提高代码的执行效率引入了白名单机制,比赛过程中意识到了这里应该就是问题点,但是没有想到如何绕过边界检查,赛后看到别人的脚本才明白。在codegen函数里面有个递归处理的机制,如果处理的是单个代码块就直接根据二元组生成IR,如果涉及多个代码块就递归处理,这里把[]包裹的语句视作一个代码块。

在处理子代码块的递归调用时候是这样的:

  1. headb = self.head.codegen(module)
  2. br1b = self.br1.codegen(module, (0, 0))
  3. br2b = self.br2.codegen(module, (0, 0))

生成移位操作和增减值操作的IR代码:

  1. for op, imm in self.shortened_code:
  2. if op == 0:
  3. continue
  4. elif op == 1: # inc/dec ptr
  5. if imm != 0:
  6. ori = builder.ptrtoint(builder.load(dptr_ptr), i64)
  7. incr = llvmIR.Const
  1. Codegate CTF 2020 Preliminary
  2. Challenge : SimpleMachine
  3. Description :
  4. (fixed-point challenge)
  5. Classic Check Flag Challenge Machine
  6. DOWNLOAD :
  7. http://ctf.codegate.org/099ef54feeff0c4e7c2e4c7dfd7deb6e/116ea16dbeabe08d1fe8891a27d0f16b
  8. point : 333 (80 team solved)

说明

脚本

  1. from pwn import *
  2. stage1 = [0xb0bd, 0xbabc, 0xbeb9, 0xbaac, 0xcfce, 0xcfce]
  3. stage2 = [0xf974, 0x2b9d, 0x4caf, 0xbee1, 0xfc0d, 0x6e48, 0xe03c, 0xd322, 0x1979, 0x36d6, 0x40e8, 0xcbf7]
  4. val = 0xdead
  5. flag = ''
  6. for i in stage1:
  7. flag += p16((0x10000 - i))
  8. next = lambda x:x ^ ((x << 1) & 0xffff)
  9. for i in stage2:
  10. val = next(val)
  11. flag += p16((0x10000 - i) ^ val)
  12. # CODEGATE2020{ezpz_but_1t_1s_pr3t3xt}
  13. print flag
  1. Codegate CTF 2020 Preliminary
  2. Challenge : Halffeed
  3. Description :
  4. nc 110.10.147.44 7777
  5. DOWNLOAD :
  6. http://ctf.codegate.org/099ef54feeff0c4e7c2e4c7dfd7deb6e/9a7f846af14e09f6b32cff3a648b80f5
  7. point : 670 (43 team solved)

mixFeed 算法 Nonce 误用攻击

流程

伪造AAAAAAAAAAAAAAAA;cat flag;AAAAAA的密文和认证码:

  1. 泄漏 T0T1T1:依次加密'\x00' * 16'A' * 16 + '\x00' * 16'B' * 16 + '\x00' * 16,取密文最后16字节。
  2. 计算中间 Tag t2t2 , _ = feed_plus(T1, ';cat flag;AAAAAA')
  3. 构造forge_tag: 加密"B" * 16 + xor(T1_[:8], t2[:8]) + t2[8:],取认证码。
  4. 构造forge_ciphertextforge_ciphertext = xor('AAAAAAAAAAAAAAAA;cat flag;AAAAAA', T0 + T1)
  5. 提交nonceforge_ciphertextforge_tag,get fla

ENIGMA

找规律,一个字符对应一个字母,最后flag是

CODEGATE2020{HACKERS ARE NOT BORN ONLY IT IS MADE}