题目难度的话,中等偏难一点点?不过听说原题有点多,今天三节课,只剩一节课的时间打比赛,摸了几道简单的就溜了。
队伍成绩:5422pt/22kill/15
个人成绩:3kill

Misc

a_misc

拿到题目,是个压缩包,带密码,先试了下伪密码,不行,于是直接爆破,得到密码qwer

拿到1.png,但是图里只有百度网盘的链接,没有提取码。

file

XnView MP打开报错,多半是图片有改过,尝试改个大高度,出现了提取码。

file

下载得到file.pcap,打开看了下,http流量还挺多,应该是分析http的,所以还是用fiddler导入一下看看。

file

就是个sql注入的爆破,于是用tshark导出一下payload然后python跑一下,应该就能出flag。

tshark -r file.pcap -T fields -e urlencoded-form.value | findstr flag > data.txt

file

with open('data.txt', 'r', encoding='UTF-8') as f:
    data = f.read().strip().split('\n')
flag = [0 for i in range(50)]
for i in data:
    flag[int(i[73:i.find(',', 73)])] = int(i[i.find('=') + 1:i.find(',sleep')])
print(bytes(flag).decode())

file

得到flag。

flag{cd2c3e2fea463ded9af800d7155be7aq}

Reverse

petition

拖进ida看一下,顺带修一下数据的显示格式。

image.png

image.png

image.png

应该就是套娃调用然后每层都有一点点的数据生成。

比如说第一次的30^120=102=f,第二次的0x6c=l,第三次的7^0x66=97=a,那么直接手工把数据全拿出来呗。

30^120
0x6c
7^0x66
0xce^0xa9
0xf9^0x82
0x8c^0xb5
0x88^0xbe
0xa8^0xcb
0x52^0x64
0x99^0xa0
0x19^0x2f
0x15^0x21
0x66^0x50
0x2e^3
0xaf^0x97
0xf6^0xc7
0x43^0x7b
0x2c^0x18
0xc9^0xe4
0xca^0xfe
0x66^0x55
0xaa^0x9c
0x4c^0x7f
0x2d
0x25^0x1d
0xd6^0xb2
0x9a
0x44^0x7d
0xbd^0x90
0x72^0x45
0x65^0x56
8^0x6e
0x85^0xb2
0x12^0x21
0x7f^0x46
0x13^0x2b
0x24^0x14
0xfc^0xca
0x24^0x12
0x33^0x50
0x23^0x12
0x97^0xea
0xb2^0xb2

image.png

发现在0x9a那个地方有点问题,回ida去看看是不是打错了。

image.png

对比了一下发现是有一个取反的操作。

image.png

所以尝试算一下0x9a取反看看能不能得到一个0~9a~f的字符,试了一下确实可以。

image.png

所以最终flag就是flag{96c69646-8184-4363-8de9-73f7398066c1}

flag{96c69646-8184-4363-8de9-73f7398066c1}

Crypto

babyrsa

这题是网上的原题,暑假刷题记录 三 - Hello World - Just So So ...,里面的第二个就是。

flag{ef5e1582-8116-4f61-b458-f793dc03f2ff}

Crazy_Rsa_Tech

这题的话给出了多组n/c,而且组数和e相等,那就是经典的低加密指数广播攻击特征,感觉套个通用的脚本就能出来。

from gmpy2 import *
from Crypto.Util.number import long_to_bytes as l2b

ns = [71189786319102608575263218254922479901008514616376166401353025325668690465852130559783959409002115897148828732231478529655075366072137059589917001875303598680931962384468363842379833044123189276199264340224973914079447846845897807085694711541719515881377391200011269924562049643835131619086349617062034608799, 92503831027754984321994282254005318198418454777812045042619263533423066848097985191386666241913483806726751133691867010696758828674382946375162423033994046273252417389169779506788545647848951018539441971140081528915876529645525880324658212147388232683347292192795975558548712504744297104487514691170935149949, 100993952830138414466948640139083231443558390127247779484027818354177479632421980458019929149817002579508423291678953554090956334137167905685261724759487245658147039684536216616744746196651390112540237050493468689520465897258378216693418610879245129435268327315158194612110422630337395790254881602124839071919, 59138293747457431012165762343997972673625934330232909935732464725128776212729547237438509546925172847581735769773563840639187946741161318153031173864953372796950422229629824699580131369991913883136821374596762214064774480548532035315344368010507644630655604478651898097886873485265848973185431559958627423847, 66827868958054485359731420968595906328820823695638132426084478524423658597714990545142120448668257273436546456116147999073797943388584861050133103137697812149742551913704341990467090049650721713913812069904136198912314243175309387952328961054617877059134151915723594900209641163321839502908705301293546584147, 120940513339890268554625391482989102665030083707530690312336379356969219966820079510946652021721814016286307318930536030308296265425674637215009052078834615196224917417698019787514831973471113022781129000531459800329018133248426080717653298100515701379374786486337920294380753805825328119757649844054966712377, 72186594495190221129349814154999705524005203343018940547856004977368023856950836974465616291478257156860734574686154136925776069045232149725101769594505766718123155028300703627531567850035682448632166309129911061492630709698934310123778699316856399909549674138453085885820110724923723830686564968967391721281, 69105037583161467265649176715175579387938714721653281201847973223975467813529036844308693237404592381480367515044829190066606146105800243199497182114398931410844901178842049915914390117503986044951461783780327749665912369177733246873697481544777183820939967036346862056795919812693669387731294595126647751951, 76194219445824867986050004226602973283400885106636660263597964027139613163638212828932901192009131346530898961165310615466747046710743013409318156266326090650584190382130795884514074647833949281109675170830565650006906028402714868781834693473191228256626654011772428115359653448111208831188721505467497494581]
cs = [62580922178008480377006528793506649089253164524883696044759651305970802215270721223149734532870729533611357047595181907404222690394917605617029675103788705320032707977225447998111744887898039756375876685711148857676502670812333076878964148863713993853526715855758799502735753454247721711366497722251078739585, 46186240819076690248235492196228128599822002268014359444368898414937734806009161030424589993541799877081745454934484263188270879142125136786221625234555265815513136730416539407710862948861531339065039071959576035606192732936477944770308784472646015244527805057990939765708793705044236665364664490419874206900, 85756449024868529058704599481168414715291172247059370174556127800630896693021701121075838517372920466708826412897794900729896389468152213884232173410022054605870785910461728567377769960823103334874807744107855490558726013068890632637193410610478514663078901021307258078678427928255699031215654693270240640198, 14388767329946097216670270960679686032536707277732968784379505904021622612991917314721678940833050736745004078559116326396233622519356703639737886289595860359630019239654690312132039876082685046329079266785042428947147658321799501605837784127004536996628492065409017175037161261039765340032473048737319069656, 1143736792108232890306863524988028098730927600066491485326214420279375304665896453544100447027809433141790331191324806205845009336228331138326163746853197990596700523328423791764843694671580875538251166864957646807184041817863314204516355683663859246677105132100377322669627893863885482167305919925159944839, 2978800921927631161807562509445310353414810029862911925227583943849942080514132963605492727604495513988707849133045851539412276254555228149742924149242124724864770049898278052042163392380895275970574317984638058768854065506927848951716677514095183559625442889028813635385408810698294574175092159389388091981, 16200944263352278316040095503540249310705602580329203494665614035841657418101517016718103326928336623132935178377208651067093136976383774189554806135146237406248538919915426183225265103769259990252162411307338473817114996409705345401251435268136647166395894099897737607312110866874944619080871831772376466376, 31551601425575677138046998360378916515711528548963089502535903329268089950335615563205720969393649713416910860593823506545030969355111753902391336139384464585775439245735448030993755229554555004154084649002801255396359097917380427525820249562148313977941413268787799534165652742114031759562268691233834820996, 25288164985739570635307839193110091356864302148147148153228604718807817833935053919412276187989509493755136905193728864674684139319708358686431424793278248263545370628718355096523088238513079652226028236137381367215156975121794485995030822902933639803569133458328681148758392333073624280222354763268512333515]
e = 9
assert len(ns) == len(cs) == e

def CRT(N, C):
    nmul = 1
    for i in N:
        nmul *= i
    sum = 0
    for n, c in zip(N, C):
        nresidue = nmul // n
        sum += c * nresidue * invert(nresidue, n)
    x = sum % nmul
    return x

x = CRT(ns, cs)
m = int(iroot(x, e)[0])
print l2b(m)

image.png

flag{H0w_Fun_13_HAstads_broadca5t_AtTack!}

Android

AreYouRich

打开apk看了下,主activity就三段代码看起来比较重要。

file

大概意思就是有个f896a后面应该有用,然后o/p分别对应账号密码,账号每位异或个34再拼接个@001就是密码。

然后一个看起来能当全局变量用的token规则就是账号+密码+时间戳,中间用下划线隔一下。

接着去看user的activity。

file

其中获取flag的条件就是余额大于那个499999999,然后输出flag的话是个用初始化对象的时候的str变量参与另一个内置数组的异或拿到的,大致逻辑可见上图。

然后看下面初始化时的余额生成算法。

file

刚才那个a对象初始化时候的str变量跟了下是之前的token,所以flag其实是token相关且唯一相关的,那么就看token的合法逻辑是个啥了,而这里正好i5就是余额累加器,其中的条件成立则翻倍,不成立就加个随机数,所以既然要在有限次里得到499999999,那就让条件一直成立呗。而这里看了下,条件实际上的可控变量只有bytes,跟上去发现就是token,所以这里的成立逻辑正好可以用来生成token

理一下思路,就是构造token,使得余额生成时一直翻倍,达到499999999以上,然后去拿flag,或者用token直接构造flag。

token实际上只用到了前25位,因为循环变量int min = Math.min(bytes.length, bArr.length);跟一下变量来源就会发现实际上就是比较tokenf897b度谁更小,那自然是f897b小,所以正好与最后的时间戳无关,只与前面的账号10+下划线1+密码14有关。

那就可以写脚本了,主要就是把各种不可控的所需数据咋生成的给复制过来,然后爆破一下token每位的情况。

bytes2 = "5FQ5AaBGbqLGfYwjaRAuWGdDvyjbX5nH".encode()

bArr2 = [i for i in range(256)]
i2 = 0
i3 = 0
for i in range(256):
    i3 = ((bytes2[i2] & 255) + (bArr2[i] & 255) + i3) & 255
    b2 = bArr2[i]
    bArr2[i] = bArr2[i3]
    bArr2[i3] = b2
    i2 = (i2 + 1) % len(bytes2)

bArr = [81, 256-13, 84, 256-110, 72, 77, 256-96, 77, 32, 256-115, 256-75, 256-38, 256-97, 69, 256-64, 49, 8, 256-27, 56, 114, 256-68, 256-82, 76, 256-106, 256-34]
i5=16
i6=0
i7=0
token = []
for i in range(25):
    i6 = (i6 + 1) & 255
    i7 = ((bArr2[i6] & 255) + i7) & 255
    b3 = bArr2[i6]
    bArr2[i6] = bArr2[i7]
    bArr2[i7] = b3
    for j in range(256):
        if (bArr2[((bArr2[i6] & 255) + (bArr2[i7] & 255)) & 255] ^ j) == bArr[i]:
            token.append(j)
print(bytes(token).decode())

file

得到账号密码,然后flag生成懒得再继续写脚本了,所以就去app里拿吧。

Screenshot_2021-10-08-22-42-44-653_com.test.areyo.jpg

flag{y0u_h@V3_@_107_0f_m0n3y!!}

designEachStep

这题jadx不认代码,当时懵逼了一下。

file

然后想起来有个叫gda的工具吹得挺牛逼的,就去试了下,没想到真的可以用,不过代码依旧有点问题,有时候代码前后逻辑矛盾的,所以还得靠像用ida那样猜。

file

file

主要的逻辑都在第二张图那个类里(因为图一确实没啥东西)。

大概看了一下,没咋看懂(java的流式读写的代码太狗屎了),不过刚开始应该是读取data.bin然后解一下gzip压缩。

file

所以就写脚本解个gzip试试。

import gzip

with open('data.bin', 'rb') as f:
    data = gzip.decompress(f.read())
print(data)

file

似乎前面几位有成为flag的趋势。

然后回去看代码,应该是解压后的前八位单独取出来,后面剩下的用前八位解一次DES/ECB/PKCS5Padding,至于为什么是用这个模式,因为DES的话是上面String str = "DES";定义的,拼在加密工具类初始化里了cInstance1 = Cipher.getInstance(str);,然后ECB/PKCS5Paddingjavax.crypto.Cipher在解DES的默认模式(不指定的话)。

file

所以改进一下脚本看看能不能成功解码。

import gzip
from Crypto.Cipher import DES

with open('data.bin', 'rb') as f:
    data = gzip.decompress(f.read())
part1 = data[:8]
print(part1)  # DE5_c0mp
data = data[8:]

des = DES.new(part1, DES.MODE_ECB)
data = des.decrypt(data)
print(data)

file

不过看不出啥东西,至少没报错就是好事,接着去看代码。

file

似乎又是解了个类似于压缩一样的东西,查了下inflater.inflate就是python里的zlib.decompress,所以那就去解一下看看呗。

file

又是一个看起来能成为flag的开头。

然后下面接着看代码,又是解一次des,用的密钥就是刚出来的那个前八位。

file

所以再改改脚本看看。

import gzip
from Crypto.Cipher import DES
import zlib

with open('data.bin', 'rb') as f:
    data = gzip.decompress(f.read())
part1 = data[:8]
print(part1)  # DE5_c0mp
data = data[8:]

des = DES.new(part1, DES.MODE_ECB)
data = des.decrypt(data)
data = zlib.decompress(data)
part2 = data[:8]
print(part2)  # r355_m@y
data = data[8:]
des = DES.new(part2, DES.MODE_ECB)
data = des.decrypt(data)
print(data)

file

然后看网上有些文章说python解des出来可能会有奇奇怪怪的填充头尾,所以图上的0xff都是没必要的,去真正的开头看看有啥。

file

好家伙我感觉flag都要出来了,因为刚开始要求输入的就是24位,之前两次8位已经出来了,这次能当明文的有9位,那就都拿去app里试试。

于是在输入DE5_c0mpr355_m@y_c0nfu53的时候成功拿到flag。

image.png

'flag{DE5_c0mpr355_m@y_c0nfu53}'


The End