这次比赛算是我第一个比赛 ,re拿了个12名,总排名28,不是很理想,先上wp
notsudoku
拿到手的是个exe,一嫖图标盲猜python编译的。
用上pyinstxtractor脚本先dump成pyc,然而并没有什么pyc格式的文件,盲猜是没有扩展名的文件2,手动修复一下文件头,再用uncompyle6解密出来。
正点
一开始直接导出文件,一堆乱码,捣鼓了大半天,试着直接打印,看到了韩文( *·#/*··#*/*···
直接复制出来放notepad++里处理一番,代码用了函数修饰器,比较难看,慢慢还原出来。最后拿到代码
import time, sys, hashlib class deque: def __init__(self): self.data = [] self.d2d = [] self.erda = 65 def main(self): print('welcome baby~ ', end='') print('input your flag~:', end='') self.strs = input() print('your input is:', end='') print(self.strs) print("let's check......", end='') time.sleep(0.5) self.d2d = [ [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0] ] if len(self.strs) % 2 != 0: sys.exit() for i in self.strs: if ord(i) > 52 or ord(i) < 48: sys.exit() x = str(hashlib.new('md5', bytes((self.strs), encoding='utf8')).hexdigest()) if x[:6] != 'e3a912': sys.exit() self.flag = x temp = 0 for i in range(0, len(self.strs), 2): temp += 1 a = int(self.strs[i]) b = int(self.strs[(i + 1)]) self.d2d[a][b] = temp if self.d2d[0][1] != 24 or self.d2d[4][3] != 2: sys.exit() if self.d2d[0][2] != 1 or self.d2d[2][3] != 20: sys.exit() if self.d2d[1][0] != 23 or self.d2d[3][4] != 3: sys.exit() for j in range(0, 5): temp = 0 for i in range(5): temp += self.d2d[j][i] if temp != self.erda: sys.exit() for j in range(0, 5): temp = 0 for i in range(5): temp += self.d2d[i][j] if temp != self.erda: sys.exit() print('Goodjob!', end='') print('The flag is vnctf{', end='') print((self.flag), end='') print('}', end='') sys.exit() deq = deque() deq.main()
看下来思路很清晰了,输入文本需要满足的条件如下
- 输入的文本只能是
0~4
之间的数字文本 - md5 hash的前6位是
e3a912
(: 然并卵 - 5*5的宫格,宫格指定位置等于相应值
[ [0, 24, 1, 0, 0], [23, 0, 0, 0, 0], [0, 0, 0, 20, 0], [0, 0, 0, 0, 0], [0, 0, 0, 2, 0] ]
- 行列和都是65
一股奥数的味道扑面而来……
关键
拉伊尔法制造五阶幻方
- 构造基方:用1-5填写幻方,使两对角线上分别是12345和33333,而且每横行纵行和均为15,如下
1 4 2 5 3
4 2 5 3 1
2 5 3 1 4
5 3 1 4 2
3 1 4 2 5
2. 然后构造根方:将基方左右调转过来,每个数都减去1,再乘以5,得到如下
10 20 5 15 0
0 10 20 5 15
15 0 10 20 5
5 15 0 10 20
20 5 15 0 10
3. 根方和基方每个对应小格中的数相加,得到最后幻方
11 24 7 20 3
4 12 25 8 16
17 5 13 21 9
10 18 1 14 22
23 6 19 2 15
然而结果不符合代码中的意思- o –
换种解法 – 参考
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
把1放在最上面的中间格,然后按口诀:
上面到顶了(出界)就往右移一格到最下面,也就是“2”的位置
住右上角移,如“3”位置。
右边到顶(出界)就往上移一格到最左边,也就是“4”的位置
然后依次往右上斜角移动,如右上方已经有数字了,就往本数向下移一格。例如“6”本应放在“5”的右上斜角,但这个右上斜角已经有数字“1”了,所以就往数字“5”本身向下移一格,就是“6”的位置
这个方法适用于所有奇数阶(9,25,49……宫格)幻方
一把梭
inputsStrs = ["0"] * 50 grid = [ [17, 24, 1, 8, 15], [23, 5, 7, 14, 16], [4, 6, 13, 20, 22], [10, 12, 19, 21, 3], [11, 18, 25, 2, 9] ] for i in range(0, len(grid)): for j in range(0, len(grid[i])): pos = 2 * grid[i][j] - 2 inputsStrs[pos] = str(i) inputsStrs[pos + 1] = str(j) print(''.join(inputsStrs))
MD5完事
Crackme2
无壳,反汇编,日常ndk分析,拿出libnative-lib.so
用IDA插件findcrypt一波搜
可能是Rijndael算法
用frida去hook
Java.perform(function () { var ptr = Module.findBaseAddress("libnative-lib.so"); var method = ptr.add(0x042944) console.log(ptr); Interceptor.attach(method,{ onEnter:function(arg){ console.log("Hooking{libnative.so} arg[0] - " + arg[0]); console.log("Hooking{libnative.so String} arg[1] - " + Memory.readCString(arg[1])); console.log("Hooking{libnative.so length} arg[2] - " + arg[2]); console.log("Hooking{libnative.so AESkey} arg[3] - \n" + hexdump(arg[3],{length:16})); console.log("Hooking{libnative.so} arg[4] - " + arg[4].readInt()); }, onLeave:function(arg){ console.log(hexdump(arg)) console.log("Hooking{libnative.so} - exit"); var xmmword_C80F0 = ptr.add(0x0C80F0) console.log("xmmword_C80F0\n" + hexdump(xmmword_C80F0)); } } ) })
解密完事
十六进制明文,转换收工。
Ez_game
这个WEB题,感觉更像是JS逆向,从我re角度来说,翻看JS就能发现一段用sojsonv4混淆过的代码,此地无银三百两ovo
['sojson.v4']["\x66\x69\x6c\x74\x65\x72"]["\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72"](((['sojson.v4']+[])["\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72"]['\x66\x72\x6f\x6d\x43\x68\x61\x72\x43\x6f\x64\x65']['\x61\x70\x70\x6c\x79'](null,"118h97x114w32l95m95N101x110O99d111B100u101w32F61P32u39R106k115w106O105F97z109R105f46p99y111A109U39d44F10G32U32F32r32G95V97p32D61Y32X123W125h44r10M32V32P32x32h95X48M120O98J52A56I51A32r61d32v91o34Q95c100n101M99e111I100l101I34b44r32X34r104N116Z116m112B58A47b47P119M119d119M46z115W111I106V115f111s110m46J99D111W109Z47g106R97c118D97F115L99I114Y105F112v116E111l98m102Q117d115E99x97K116r111U114v46s104d116B109F108Z34e93B59q10m40r102O117f110Z99D116D105a111a110u40Y95J48O120H100Q54k52k50e120I49a41P32f123s10E32j32I32d32K95E48D120k100R54S52g50O120H49y91J95q48X120w98C52a56R51E91m48B93c93E32d61e32w95X48v120b98L52e56b51O91m49b93C10Q125V41N40t95r97g41L59X10M118d97I114t32E95f95x79y120f97D50O55p56y49X32I61j32A91K34i34t44h32L34a45m112w97p117H115M101E100z45m34r44g32Q34y87v105k110E33A32h102S108G97y103u123E116k104V105l115E95F103u97g109Y101I95l105R115A95x102G117h110l110E121M33B125f34N44c32q34f71C97L109O101x32c79k118R101J114R33b34L44V32h34U80g114e101b115c115t32c69w115I99g97u112W101z34C44h32d34a120f34k44B32W34i121H34q44x32P34E99x101x110k116J101Z114j34c44B32s34B117V110j100K101A102U105M110L101x100T34k44u32U34R108t111X103q34W44p32M34o21024U38500O34R44T32u34a29256O26412t21495E65292k106N115v20250y23450F34N44f32V34Q26399e24377C31383B65292R34u44t32j34y36824A35831C25903t25345D25105o20204W30340R24037P20316L34R44y32w34o106Z115A106T105F97b34i44a32m34u109T105L46e99p111F109l34U93m59Y10u108S101q116s32P98f105A103l84N101h120n116V32A61B32t95V95W79u120a97z50N55J56g49r91g48C120L48a93r59K10k105U102S32K40X112d97m117q115P101T100A41S32r123R10r32D32a32X32t98Y105Y103N84I101p120j116U32e61J32R95g95v79i120F97F50n55h56H49d91S48x120N49u93H10C125z59O10C105W102e32t40G119n105T110x84r105G109Y101W114q46C73s115m83G101O116j40m41O41R32S123R10c32I32b32A32V98x105X103v84E101b120V116V32L61P32N95e95u79I120v97W50T55W56i49S91j48m120O50d93k10g125J59G10Q105p102m32Y40O112J108s97c121w101U114u46P73a115D68E101Y97D100E40g41g41Q32Y123r10K32X32T32q32r98b105q103i84o101V120D116v32N61H32b95R95J79q120i97q50X55o56g49G91T48Z120F51G93l59k10c32v32f32e32P68u114l97N119q84f101x120z116m40j95r95I79n120R97E50x55o56h49y91p48Q120z52L93g44k32E109H97Q105E110w67Z97l110d118S97M115j83a105B122j101E91p95n95Y79U120S97H50C55a56l49E91z48w120A53C93Y93I32b47M32o50R44R32w109n97U105b110j67h97M110H118j97X115g83D105M122n101W91J95q95y79x120i97R50Y55z56s49N91z48v120R54s93a93S32I47z32A50k32w43S32f56j48j44T32B52Y50c41O10V125M59f10h68n114V97m119f84G101C120P116u40E98i105M103U84C101e120d116q44f32Z109v97i105R110G67u97m110Q118e97n115K83G105V122M101j91Q95Y95y79M120f97G50k55i56C49c91x48j120R53F93a93L32b47p32Z50k44a32l109c97r105A110W67i97Y110t118H97y115J83H105C122r101R91a95L95s79a120d97M50G55H56k49O91m48p120R54y93d93J32x47y32c50c32Y45d32C56M48i44r32b55G50f44j32x95j95r79S120i97g50J55V56a49a91Y48f120w55c93M44M32s50p41D59x59h59g10r40L102e117n110g99S116k105D111t110Y40M95J48s120f53y49N57K55H120Y50z44F32z95B48b120t53z49A57D55X120n51H44w32o95P48t120g53n49M57G55n120T52U44D32B95A48B120Z53K49H57t55X120d53L44f32o95J48R120D53s49H57d55J120b54Y44w32U95u48g120J53Q49v57B55s120a55H41z32L123K10G32X32F32V32W95k48o120T53S49I57d55s120i55d32O61X32n95B95n79d120E97E50s55o56w49j91N48z120D56R93R59j10p32Q32s32e32H95F48O120Y53F49C57W55r120q53M32f61U32Y102R117F110N99c116V105r111y110w40I95X48h120s53Y49o57q55k120o56Q41f32S123S10R32C32B32t32f32r32q32F32Z105Y102S32o40c116E121R112d101G111f102m32p97d108Q101M114s116V32G33s61C61z32B95p48W120e53S49y57p55Q120C55o41q32L123z10I32u32a32y32W32e32b32h32W32s32m32l32c97I108C101N114t116V40P95w48X120x53F49M57d55B120x56u41F10C32F32A32B32h32F32r32y32w125L59G10o32f32T32O32T32O32c32H32D105d102v32H40i116V121a112R101e111G102B32D99O111n110L115o111X108W101S32D33C61H61G32o95u48e120z53k49d57j55s120E55m41p32c123o10V32I32B32R32A32Y32N32H32E32R32l32V32P99D111R110i115r111m108h101D91Z95i95s79g120K97d50W55w56r49n91E48l120W57W93F93R40P95D48G120q53Q49d57p55q120M56R41F10q32C32N32u32X32T32E32d32X125W10D32P32h32i32Y125N59D10v32J32C32X32B95V48w120K53C49I57r55I120E52C32Q61E32X102o117o110I99u116M105C111z110h40v95g48L120b53d49q57e55J120L57j44C32F95R48X120M53S49U57w55h120I50w41W32r123j10q32e32k32e32y32Z32I32g32z114c101D116A117A114V110w32x95p48H120k53O49r57b55Z120w57Q32N43M32A95I48z120M53A49S57s55K120o50o10u32y32k32j32u125a59j10u32S32S32n32p95A48s120k53a49M57F55J120J54G32c61R32l95c48X120C53s49q57U55V120E52N40A95t95T79x120Q97R50o55F56e49Y91i48G120p97P93y44S32J95k48r120q53g49i57E55x120D52O40N95H48S120d53i49M57H55x120e52e40X95k95Z79q120C97l50T55K56I49k91R48o120g98g93Q44v32r95R95K79W120N97u50A55v56Z49m91A48x120X99H93x41y44T32w95n95v79i120g97E50y55h56m49C91X48S120N100w93n41q41b59M10I32e32F32g32e116J114t121I32r123N10M32J32N32m32j32l32J32g32X95n48g120l53X49b57l55D120p50s32b61T32f95W95E101N110o99c111M100M101Q59f10J32k32y32K32B32F32X32R32K105d102c32b40e33U40o116q121j112D101A111D102c32x95p48o120R53a49b57S55d120M50d32p33q61s61o32d95z48B120A53s49S57t55a120j55H32B38S38e32N95i48L120O53j49W57O55V120P50X32o61Y61i61k32P95j48M120Z53O49t57W55P120p52V40d95N95y79a120X97r50t55o56v49a91I48m120m101p93B44T32V95b95j79s120M97q50p55j56G49A91g48i120O102U93G41y41a41i32F123F10O32Z32o32T32P32e32Z32K32T32h32z32d32b95l48V120H53v49J57I55L120w53J40n95M48o120F53C49d57W55e120S54R41U10U32u32C32c32x32z32y32J32F125L10H32K32G32r32d125e32A99A97l116x99y104R32H40B101U41W32j123A10m32t32b32L32A32A32B32D32Z95t48z120m53V49N57N55B120x53Z40m95k48c120A53L49M57V55R120l54U41X10E32R32G32Q32q125U10D125p41P40A123E125S41"['\x73\x70\x6c\x69\x74'](/[a-zA-Z]{1,}/))))('sojson.v4');
一般遇到混淆的JS如果代码量不多,可以手动去还原,如果代码量上达几千几万,那就需要使用AST进行处理了。这里的混淆不是很难,能够轻易的还原
['sojson.v4'].filter.constructor(((['sojson.v4'] + []).constructor.fromCharCode.apply(null, "118h97x114w32l95m95N101x110O99d111B100u101w32F61P32u39R106k115w106O105F97z109R105f46p99y111A109U39d44F10G32U32F32r32G95V97p32D61Y32X123W125h44r10M32V32P32x32h95X48M120O98J52A56I51A32r61d32v91o34Q95c100n101M99e111I100l101I34b44r32X34r104N116Z116m112B58A47b47P119M119d119M46z115W111I106V115f111s110m46J99D111W109Z47g106R97c118D97F115L99I114Y105F112v116E111l98m102Q117d115E99x97K116r111U114v46s104d116B109F108Z34e93B59q10m40r102O117f110Z99D116D105a111a110u40Y95J48O120H100Q54k52k50e120I49a41P32f123s10E32j32I32d32K95E48D120k100R54S52g50O120H49y91J95q48X120w98C52a56R51E91m48B93c93E32d61e32w95X48v120b98L52e56b51O91m49b93C10Q125V41N40t95r97g41L59X10M118d97I114t32E95f95x79y120f97D50O55p56y49X32I61j32A91K34i34t44h32L34a45m112w97p117H115M101E100z45m34r44g32Q34y87v105k110E33A32h102S108G97y103u123E116k104V105l115E95F103u97g109Y101I95l105R115A95x102G117h110l110E121M33B125f34N44c32q34f71C97L109O101x32c79k118R101J114R33b34L44V32h34U80g114e101b115c115t32c69w115I99g97u112W101z34C44h32d34a120f34k44B32W34i121H34q44x32P34E99x101x110k116J101Z114j34c44B32s34B117V110j100K101A102U105M110L101x100T34k44u32U34R108t111X103q34W44p32M34o21024U38500O34R44T32u34a29256O26412t21495E65292k106N115v20250y23450F34N44f32V34Q26399e24377C31383B65292R34u44t32j34y36824A35831C25903t25345D25105o20204W30340R24037P20316L34R44y32w34o106Z115A106T105F97b34i44a32m34u109T105L46e99p111F109l34U93m59Y10u108S101q116s32P98f105A103l84N101h120n116V32A61B32t95V95W79u120a97z50N55J56g49r91g48C120L48a93r59K10k105U102S32K40X112d97m117q115P101T100A41S32r123R10r32D32a32X32t98Y105Y103N84I101p120j116U32e61J32R95g95v79i120F97F50n55h56H49d91S48x120N49u93H10C125z59O10C105W102e32t40G119n105T110x84r105G109Y101W114q46C73s115m83G101O116j40m41O41R32S123R10c32I32b32A32V98x105X103v84E101b120V116V32L61P32N95e95u79I120v97W50T55W56i49S91j48m120O50d93k10g125J59G10Q105p102m32Y40O112J108s97c121w101U114u46P73a115D68E101Y97D100E40g41g41Q32Y123r10K32X32T32q32r98b105q103i84o101V120D116v32N61H32b95R95J79q120i97q50X55o56g49G91T48Z120F51G93l59k10c32v32f32e32P68u114l97N119q84f101x120z116m40j95r95I79n120R97E50x55o56h49y91p48Q120z52L93g44k32E109H97Q105E110w67Z97l110d118S97M115j83a105B122j101E91p95n95Y79U120S97H50C55a56l49E91z48w120A53C93Y93I32b47M32o50R44R32w109n97U105b110j67h97M110H118j97X115g83D105M122n101W91J95q95y79x120i97R50Y55z56s49N91z48v120R54s93a93S32I47z32A50k32w43S32f56j48j44T32B52Y50c41O10V125M59f10h68n114V97m119f84G101C120P116u40E98i105M103U84C101e120d116q44f32Z109v97i105R110G67u97m110Q118e97n115K83G105V122M101j91Q95Y95y79M120f97G50k55i56C49c91x48j120R53F93a93L32b47p32Z50k44a32l109c97r105A110W67i97Y110t118H97y115J83H105C122r101R91a95L95s79a120d97M50G55H56k49O91m48p120R54y93d93J32x47y32c50c32Y45d32C56M48i44r32b55G50f44j32x95j95r79S120i97g50J55V56a49a91Y48f120w55c93M44M32s50p41D59x59h59g10r40L102e117n110g99S116k105D111t110Y40M95J48s120f53y49N57K55H120Y50z44F32z95B48b120t53z49A57D55X120n51H44w32o95P48t120g53n49M57G55n120T52U44D32B95A48B120Z53K49H57t55X120d53L44f32o95J48R120D53s49H57d55J120b54Y44w32U95u48g120J53Q49v57B55s120a55H41z32L123K10G32X32F32V32W95k48o120T53S49I57d55s120i55d32O61X32n95B95n79d120E97E50s55o56w49j91N48z120D56R93R59j10p32Q32s32e32H95F48O120Y53F49C57W55r120q53M32f61U32Y102R117F110N99c116V105r111y110w40I95X48h120s53Y49o57q55k120o56Q41f32S123S10R32C32B32t32f32r32q32F32Z105Y102S32o40c116E121R112d101G111f102m32p97d108Q101M114s116V32G33s61C61z32B95p48W120e53S49y57p55Q120C55o41q32L123z10I32u32a32y32W32e32b32h32W32s32m32l32c97I108C101N114t116V40P95w48X120x53F49M57d55B120x56u41F10C32F32A32B32h32F32r32y32w125L59G10o32f32T32O32T32O32c32H32D105d102v32H40i116V121a112R101e111G102B32D99O111n110L115o111X108W101S32D33C61H61G32o95u48e120z53k49d57j55s120E55m41p32c123o10V32I32B32R32A32Y32N32H32E32R32l32V32P99D111R110i115r111m108h101D91Z95i95s79g120K97d50W55w56r49n91E48l120W57W93F93R40P95D48G120q53Q49d57p55q120M56R41F10q32C32N32u32X32T32E32d32X125W10D32P32h32i32Y125N59D10v32J32C32X32B95V48w120K53C49I57r55I120E52C32Q61E32X102o117o110I99u116M105C111z110h40v95g48L120b53d49q57e55J120L57j44C32F95R48X120M53S49U57w55h120I50w41W32r123j10q32e32k32e32y32Z32I32g32z114c101D116A117A114V110w32x95p48H120k53O49r57b55Z120w57Q32N43M32A95I48z120M53A49S57s55K120o50o10u32y32k32j32u125a59j10u32S32S32n32p95A48s120k53a49M57F55J120J54G32c61R32l95c48X120C53s49q57U55V120E52N40A95t95T79x120Q97R50o55F56e49Y91i48G120p97P93y44S32J95k48r120q53g49i57E55x120D52O40N95H48S120d53i49M57H55x120e52e40X95k95Z79q120C97l50T55K56I49k91R48o120g98g93Q44v32r95R95K79W120N97u50A55v56Z49m91A48x120X99H93x41y44T32w95n95v79i120g97E50y55h56m49C91X48S120N100w93n41q41b59M10I32e32F32g32e116J114t121I32r123N10M32J32N32m32j32l32J32g32X95n48g120l53X49b57l55D120p50s32b61T32f95W95E101N110o99c111M100M101Q59f10J32k32y32K32B32F32X32R32K105d102c32b40e33U40o116q121j112D101A111D102c32x95p48o120R53a49b57S55d120M50d32p33q61s61o32d95z48B120A53s49S57t55a120j55H32B38S38e32N95i48L120O53j49W57O55V120P50X32o61Y61i61k32P95j48M120Z53O49t57W55P120p52V40d95N95y79a120X97r50t55o56v49a91I48m120m101p93B44T32V95b95j79s120M97q50p55j56G49A91g48i120O102U93G41y41a41i32F123F10O32Z32o32T32P32e32Z32K32T32h32z32d32b95l48V120H53v49J57I55L120w53J40n95M48o120F53C49d57W55e120S54R41U10U32u32C32c32x32z32y32J32F125L10H32K32G32r32d125e32A99A97l116x99y104R32H40B101U41W32j123A10m32t32b32L32A32A32B32D32Z95t48z120m53V49N57N55B120x53Z40m95k48c120A53L49M57V55R120l54U41X10E32R32G32Q32q125U10D125p41P40A123E125S41".split(/[a-zA-Z]{1,}/))))('sojson.v4');
使用正则以字母分割,得到一个文本数字的数组,然后转换成明文。
很简单,将函数调用去掉后面的('sojson.v4')
,就能拿到正常的JS代码。
显然,flag就藏在__Oxa2781
数组中。
Crackme1复现
因为对主流加密算法只有一些粗浅的印象,并不了解其中的算法。在我看了wp后,去了解了一下RC4算法。
RC4
参考大佬的学习文章,借此题中的RC4算法进行学习。
S 盒,是一个 256 个字节大小的 char 类型数组,char S[256]
密钥 K,长度限定在 1-256 个字节
临时变量 T,大小也是 256 个字节的数组
输出的密钥流 k,大小与实际需要加密的内容一致。
RC4
加解密流程
- 通过密钥调度算法KSA初始化状态矢量S(S就是一个随机数发生器,称为S-box)
- 再通过伪随机数生成算法PRGA得到密钥流KeyStream
- 密钥流KeyStream与明文进行XOR运算得到密文,解密同理
回到此题,作者简单混淆了一下变量名,我进行了分析和还原
package com.ctf.crackme; public class enc { private String RC4Key = "vnctftestkeyyyy"; public native String oO000O0(String str); private static void RC4init(short[] s, String key, int keylen) { byte[] keyArray = key.getBytes(); for (int i = 0; i < 256; i++) { s[i] = (short) i; // 顺序填充 sbox } int j = 0; for (int i2 = 0; i2 < 256; i2++) { // 打乱sbox j = ((s[i2] + j) + keyArray[i2 % keyArray.length]) % 256; short tmp = s[i2]; // 交换 s[i2] = s[j]; s[j] = tmp; } } private static void RC4crypt(short[] s, char[] Data, int Len) { int i = 0; int j = 0; for (int k = 0; k < Len; k++) { i = (i + 1) % 256; j = ((s[i] & 255) + j) % 256; short tmp = s[i]; // 交换 s[i] = s[j]; s[j] = tmp; Data[k] = (char) (Data[k] ^ s[((s[i] & 255) + (s[j] & 255)) % 256]); // 逐字异或 } } public char[] encrypt(String Data) { String Data_1 = oO000O0(Data); short[] s = new short[256]; RC4init(s, this.RC4Key, this.RC4Key.length()); char[] data = Data_1.toCharArray(); RC4crypt(s, data, data.length); return data; } }
分析的流程中,发现首先调用了native函数,转为分析libnative-lib.so
使用findcrypt发现并不是标准算法,手动分析
__int64 __fastcall Java_com_ctf_crackme_o000O00000o0_oO000O0(JNIEnv *a1, __int64 a2, __int64 a3) { __int64 v4; // [xsp+0h] [xbp-1F0h] unsigned int v5; // [xsp+Ch] [xbp-1E4h] __int64 v6; // [xsp+10h] [xbp-1E0h] const char *Data; // [xsp+38h] [xbp-1B8h] char v9[24]; // [xsp+58h] [xbp-198h] BYREF char v10[24]; // [xsp+70h] [xbp-180h] BYREF char maps[24]; // [xsp+88h] [xbp-168h] BYREF char rdata[24]; // [xsp+A0h] [xbp-150h] BYREF char v13[32]; // [xsp+B8h] [xbp-138h] BYREF char v14[256]; // [xsp+D8h] [xbp-118h] BYREF __int64 v15; // [xsp+1D8h] [xbp-18h] v15 = *(_QWORD *)(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40); Data = sub_2B9C4(a1, a3, 0LL); // GetStringUTFChars sub_233F8((__int64)rdata, (__int64)Data); // 手上没有Android7.1的调试机, 应该是copy sub_233F8((__int64)maps, (__int64)"AYZpq23IJrTFfghijklCDE1KLMmBdestU5678GHz0cuvwabN9VWXnoOPQRSxy4/+");// copy sub_25F2C((__int64)v10, (__int64)maps); sub_2BA04(v13, v10, 61LL); sub_23588(v10); v6 = sub_2B7AC(rdata); v5 = sub_2BA6C(rdata); // wp上说是取了数据长度 sub_25F2C((__int64)v9, (__int64)maps); sub_40BEC(v13, v14, v6, v5, v9); // base64 sub_23588(v9); v4 = sub_2B774(a1, v14); sub_2BA90(v13); sub_23588(maps); sub_23588(rdata); _ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)); return v4; }
然而由于手上没有7.1的设备来动态调试,并且受制于我卑微的分析能力,我无法细致的分析更多函数的作用,日后有机会补上
下面回到最开始的程序入口
public void onClick(View view) { if (Arrays.equals(new char[]{145, '5', 129, 199, 133, 'u', 18, 'v', 'k', 160, 167, '\n', 135, 't', 'd', 179, 237, 174, 'J', 'i', 27, 183, 128, '7', 20, 221, 144, 29, 171, 7, 181, 22, 'g', '^', '\t', 162, 6, 232, 253, 170, 158, 207, '9', 210, 173, 240, 'S', '@', 133, 192, 136, 227}, new o000O00000o0().oO000O0000OOo(input.getText().toString()))) { Toast.makeText(MainActivity.this, "Congratulations", 0).show(); } else { Toast.makeText(MainActivity.this, "Sorry!!!", 0).show(); } }
先RC4解密再Base64解密
这里我卡住了,对Base64算法还是不熟悉,一直卡在变异算法的异或
用v4
对每个分片的第1,3个进行异或
这里感谢V&NCTF交流群中的一位师傅给了我一个思路,代码如下
import base64 str1 = bytearray(b"BHu7B3jx@XrPjCBGkHARkOcRAXVVj7L6jpfo@HU6@HkPjHVVjp@4") for p, i in enumerate(str1): if p % 2 == 0: # 每两位进行异或 str1[p] ^= 39 # 这个值来源于本位的加密文本长度 base64 变种 newMaps = "AYZpq23IJrTFfghijklCDE1KLMmBdestU5678GHz0cuvwabN9VWXnoOPQRSxy4/+" baseMaps = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" tstr = str1.decode().translate(str.maketrans(newMaps, baseMaps)).encode() # 对应替换 print(base64.b64decode(tstr).decode())
这个代码是令我眼前一亮的一个方法:直接使用原始码表对应新码表替换密文,可以免于替换码表。
通过这道题目,我很清楚我必须去理解一些主流算法了。标准算法学习笔记也就是下一篇或者后续需要的了
FilpGame复现
显然我技术还是不到家,这道题我并没有能够解出,翻看了函数的主逻辑,一致搞不懂代码的思路,途中有尝试通过hint寻找突破点,然而半途放弃了。官方wp已经出了几天了,但是因为一些私事一直没时间复现。今天得空来复现,学习一下思路。
常规
常规操作,查壳放IDA里,查看伪代码。
sub_6C1020("Input: ", v16); sub_6C1050("%s", (char)ArgList); v3 = 0; v18 = 0; v4 = 0;// 0 v5 = 0;// 0 v19 = 0;// 0 dword_6C2140 = [0x00, 0x00, 0xFFFFFF, 1, 0] dword_6C212C = [0xFFFFFFFF, 0x00, 0, 0, 1] while (v3 < 214) { // 长度少于214 v6 = v3; v8 = v6 & 1; if (v8) { // 隔两位取坐标 x, y if (ArgList[v3] - '0' > 9) { if (ArgList[v3] - 'A' > 25) { v5 = -1; } else { v5 = ArgList[v3] - 55; // 这里困惑了很久,发现原来只是A - F转换成10 - 15 } } else { v5 = ArgList[v3] - '0'; } } else { if (ArgList[v3] - '0' > 9) { if (ArgList[v3] - 'A' > 25) { break; } v4 = ArgList[v3] - 55; } else { v4 = ArgList[v3] - '0'; } v19 = v4; } if (v4 > 0xF || v5 > 0xF) break; //坐标 x,y 大小需小于16 if (v8) { // 坐标完整的时候进入 if (dword_6C3018 >= (int)(v4 + 16 * v5)) break; // 0xFFFFFFFF // dword_6C3018 = v4 + 16 * v5; for (i = 0; i < 5; ++i) { // 这个for相当于点灯游戏中的5个点的变化 v12 = v4 + dword_6C212C[i]; v13 = v5 + dword_6C2140[i]; if (v12 <= 0xF && v13 <= 0xF) word_6C301C[v13] ^= 1 << (15 - v12); // 位异或 } } v3++; } v14 = word_6C301C; // int16类型 状态压缩 while ( *v14 == -1 ) { // word_6C301C变量中所有的值都变成-1(0xffff) if ( (int)++v14 >= (int)&unk_6C303C ){ // 标记读取 sub_6C1020("right, vnctf{MD5(%s)}\n", (char)ArgList); return 0; } }
总的看下来,其实解题的关键很清楚。然而之前没玩过点灯游戏,我表示比赛的时候我是一脸懵的。
现在,我找了一个在线网站来了解点灯游戏。
也就有了我上面的代码分析。
事实上,其实思路很清楚:
- 一个16×16的宫格
- 点指定次数的灯让word_6C301C内的所有数据都为-1
然而事实是难点就在于怎么点才能让其值全为-1……
难点
待补充……
发表回复