Loading... > UCAS-IIE-2019-4-BlueBCTF writeup --- # babybaseX > 考点 > > - C++ > - STL:vector > - 编码转换 ## main 先来看一下主函数的逻辑。 ![Snipaste_2019-04-09_16-06-34](./assets/Snipaste_2019-04-09_16-06-34.png) ![Snipaste_2019-04-09_16-10-35](./assets/Snipaste_2019-04-09_16-10-35.png) 发现主要是encode进行了操作,跟进去。 ## encode 主要逻辑是一个双层大循环,对输入进行编码然后输出。 关于最开始一段代码,是用来分配空间的。 ```c len = ((((0xA3D70A3D70A3D70BLL * (138 * (end - p))) >> 64) + 138 * (end - p)) >> 6) - (138 * (end - p) >> 63) + 1; ``` 参考链接[Hacker's-Delight](http://www.icodeguru.com/Embedded/Hacker's-Delight/076.htm) $$ 10^{-2}= 0xa3d70a3d70a3d70b * 2^{-70} $$ 得到前面一部分是0.01,乘以138,等于1.38。考虑到没计算后面2部分,这里可以近似等于1.333循环,所以我猜测该段代码实际作用如下。 $$ \frac{4}{3}x+1 $$ 所以根据最后cipher的长度是22,可以得到给plain分配的空间是15左右。 ### 核心编码过程 ![Snipaste_2019-04-09_16-17-01](./assets/Snipaste_2019-04-09_16-17-01.png) ![Snipaste_2019-04-09_16-19-21](./assets/Snipaste_2019-04-09_16-19-21.png) ```c d<<8|n d r 0031 01 17 0001 00 01 1732 e4 0a 01e4 12 10 0012 00 12 0a33 64 0b 1064 a1 0a 12a1 b7 0b 00b7 07 01 0007 00 07 ``` ## 编写脚本 编码脚本: ```python #coding:utf-8 __author__ = 'zjgcjy' import math table = 'vrYenHCzNgu7FRTDbLiqtBpQZoUS3f5dKWsaM8Gm1EyVJkjw4cA6X92Pxh0OLl+/' plain = 'NowYouKnowBa5358' length = int(math.floor(len(plain) * 4.0/3 + 1 )) mod = ord(plain[1]) - ord(plain[0]) + 25 r0 = r_next = [0] for i in xrange(len(plain)): d = ord(plain[i]) j = 0 r_next = [] while d or j < len(r0): if j >= len(r0): r0.append(0) d = r0[j] << 8 | d rr = d % mod r_next.append(rr) d = d / mod j += 1 #print r_next r0 = r_next if not len(r0) > length: print r0 else: print 'error' cipher = ''.join([table[i] for i in r0]) print cipher[::-1] ``` 解码脚本: ```python #coding:utf-8 __author__ = 'zjgcjy' table = 'vrYenHCzNgu7FRTDbLiqtBpQZoUS3f5dKWsaM8Gm1EyVJkjw4cA6X92Pxh0OLl+/' cipher = 'gmJNxnNCPChRefqDYSU1KZ' r0 = r = [table.index(i) for i in cipher] filterF = lambda x: filter(lambda y: y > 128, x) for mod in xrange(256): r = r0 flag = '' for _ in xrange(len(r)): d = [0] r_prev = [] for i in xrange(len(r)): n = d[i] * mod + r[i] d.append(n & 0xff) r_prev.append(n >> 8) flag += chr(d[-1]) r = r_prev[1:] if filterF(map(ord, flag)) != []: continue print hex(mod), flag if __name__ == '__main__': print '8535aBwonKuoYwoN'[::-1] ``` # babyre > 考点 > > - SEH > - MISC > - 一元一次方程求解 ## main ![Snipaste_2019-04-09_16-58-42](./assets/Snipaste_2019-04-09_16-58-42.png) 一个伪造的fake flag。 ![Snipaste_2019-04-09_17-04-12](./assets/Snipaste_2019-04-09_17-04-12.png) 产生除0异常。 ![Snipaste_2019-04-09_17-11-15](./assets/Snipaste_2019-04-09_17-11-15.png) ## SEH处理 [编译器对系统SEH机制的封装](https://www.cnblogs.com/5iedu/p/5223846.html) ![Snipaste_2019-04-10_10-07-03](./assets/Snipaste_2019-04-10_10-07-03.png) 对于VC的SEH,其每个异常帧的CALL_BACK都统一设为_except_handler4。每进入一个try块里,编译器会将VC_EXCEPTION_REGISTRATION中tryLevel赋值为相应的值。 一旦该try块异常发生,系统会先从VC_EXCEPTION_REGISTRATION的handler域中找到_exception_handler4函数(C运行时库函数),然后根据当前tryLevel的值找到scopetable表中这个__try块相应的过滤函数和处理函数对异常进行相应的处理。 | Enum| value| explanation| |:---------:| :--------: | :-----: | |`EXCEPTION_EXECUTE_HANDLER`|1|处理异常,从异常处下一条指令继续执行 | |`EXCEPTION_CONTINUE_SERCH`|0|不处理异常,继续搜索执行下一个EH| |`EXCEPTION_CONTINUE_EXECUTION`|-1|忽略异常,从异常处继续执行| ![Snipaste_2019-04-10_10-47-38](./assets/Snipaste_2019-04-10_10-47-38.png) ```c BOOL __cdecl check11(char *a1) { return (a1[4] + a1[2] + *a1) == 253 && (a1[7] + a1[5] + a1[3] + a1[1]) == 140 && *a1 == (a1[1] + 1) && a1[1] == (a1[2] + 50) && a1[2] == (a1[3] - 47) && a1[6] == (a1[4] - 49) && a1[6] == (a1[7] - 49) && a1[5] == (a1[3] - 1); } ``` 使用z3进行约束求解。 ```python #coding:utf-8 __author__ = 'zjgcjy' from z3 import * a1 = [BitVec('a1[%d]'%i, 8) for i in xrange(8)] s = Solver() s.add(And( ((a1[4] + a1[2] + a1[0]) & 0xff == 253), ((a1[7] + a1[5] + a1[3] + a1[1]) & 0xff == 140), (a1[0] == a1[1] + 1), (a1[1] == a1[2] + 50), (a1[2] == a1[3] - 47), (a1[6] == a1[4] - 49), (a1[6] == a1[7] - 49), (a1[5] == a1[3] - 1), )) for i in xrange(len(a1)): s.add(ULE(a1[i], 0x7f)) s.add(UGE(a1[i], 0x20)) if s.check() == sat: m = s.model() flag = '' for i in xrange(8): flag += chr(m[a1[i]].as_long().real) print flag else: print 'no' ``` 得到结果是`fe3bda3d`。 进行第二部分的检查。 ![Snipaste_2019-04-09_17-14-48](./assets/Snipaste_2019-04-09_17-14-48.png) ## 解决 最后的脚本如下。 ```python #coding:utf-8 __author__ = 'zjgcjy' plain = 'fe3bda3d' * 3 cipher = '04 09 46 07 1F 03 52 06 1F 3A 41 51 3B 50 40 3B 55 04 40 1B 3B 09 5B 19'.replace(' ', '').decode('hex') xorF = lambda a, b: map(lambda x, y: x ^ y, a, b) flag = xorF(map(ord, plain), map(ord, cipher)) print ''.join(map(chr, flag)) ``` # Thanks ``` ``` Last modification:January 16th, 2021 at 12:38 pm © 允许规范转载 Support 确定不打赏一下支持博主吗 ×Close Appreciate the author Sweeping payments Pay by AliPay