感觉hackme的逆向偏算法,加壳混淆的题目不多。

041 helloworld

要求输入一个数。

img

ida打开后很容易知道。

img

img

最简单的签到题

042 simple

img

"UIJT.JT.ZPVS.GMBH"字符分别减一即可

s = 'UIJT.JT.ZPVS.GMBH'
for i in s:
    print(chr(ord(i)-1),end='')

043passthis

不要直接运行,火绒会报毒,关闭火绒后再运行,电脑直接黑屏。

img

主逻辑就是判断数据库字符串与输入字符串异或值是否为135。(46行)

将byte_404040处的数据复制,通过winhex生成文件。

with open('11.txt','rb')as f:    #二进制读入
    s = f.read()
print(s)
for i in s:
    print(chr(i^135),end='')

顺便说一下_bittest(*a, b),检查地址a中,第b位的值是0还是1。注意到b的值从0开始取。

https://docs.microsoft.com/en-us/cpp/intrinsics/bittest-bittest64?view=vs-2019

https://www.cnblogs.com/aquar/archive/2009/11/08/3451517.html

044 pyyy

直接运行pyc,没运行成功

img

然后在线反编译,但是拿到的py代码不是很理想。然后使用uncompyle6反编译的。

pip install uncompyle6
uncompyle6 D:\桌面\pyyy.pyc > D:\桌面\123123.py

拿到代码

__import__('sys').setrecursionlimit(1048576)
data = 'Tt1PJbKTTP+nCqHvVwojv9K8AmPWx1q1UCC7yAxMRIpddAlH+oIHgTET7KHS1SIZshfo2DOu8dUt6wORBvNVBpUSsuHa0S78KG+SCQtB2lr4c1RPbMf0nR9SeSm1ptEY37y310SJMY28u6m4Y44qniGTi39ToHRTyxwsbHVuEjf480eeYAfSVvpWvS8Oy2bjvy0QMVEMSkyJ9p1QlGgyg3mUnNCpSb96VgCaUe4aFu4YbOnOV3HUgYcgXs7IcCELyUeUci7mN8HSvNc93sST6mKl5SDryngxuURkmqLB3azioL6MLWZTg69j6dflQIhr8RvOLNwRURYRKa1g7CKkmhN4RytXn4nyK2UM/SoR+ntja1scBJTUo0I31x1wBJpT4HjDN47FLQWIkRW+2wnB3eEwO5+uSiQpzA8VaH7VGRrlU/BFW4GqbaepzKPLdXQFBkNyBKzqzR/zA2GIrYbLIVScWJ19DqJCOyVLGeVIVXyzN1y327orYL2Ee3lRITnE3FouicRStaznIcw8xmxvukwVMRZIJ/vTu8Zc1WQIYEIFXMHozGuvzZgROZTyFihWNRCBBtoP9DJJALJb0pA1IKIb2zLh+pwGF40Y6y93D6weKejGPO+A0DBXH9vuLcCcCIvr/XPQhO3jLKCBN+h9unuJKW3dyWxyaVPdR2V+BTw10VXolo7yaTH1GbR4TiVSB308mBOMwfchwihEe7RdMXvmXgaGarKkJe0NLUCd8jwhYII+WymjxO/xOz/ppOvNfAyIQksW0sggRPQTlgXSZ7MIVA1h66sGNljJ833MoFzWof3azLabaz1OrAJFqYXBg/myDsy1tV6rULSQ82hVR/TNnSmBGvyEDJTrLSwHyj78NOrW4mUnlLGBnAgWfw6pW2lRK2jkNX9NM6DfLsRK8lwl85UP8CZSuNdcLmLwHTVMZGm/cNkZCtWRBlZqEggxGdIO44D+f4y6ysnAk5/QzEwjIuecxEOb0jyV6dFui8g0c3Oxlhzcli0X8ToJFyeQRv1N9nokYZ07tFlG6m18kCToKz1qiH1U7kljXa6SvdORur5dWYLQ//gwhwppe7JlNda/cEoh92h96wRZDv1dSK/f1vz+mUeUyUlFY0iMjfw5eBXWZppNZi3ZtJcq5kllM2ACVFcxQWI3azM3ArOcqjosoiPjNoDYgKh7w4k2Cd0kLYEHscz/njtJ1KEcwLtqs4nJ+gB2r4V9g03YgvY5E8JJtfJMKdaTedjtvEuif8FNlCK9DMnL1iLpWptJbdfO83Y7Y46XCqjZFBI5o9Qtb78nLhMEM5/YTaNOM/wE/oJl5HI/i1X6kW3PKCsVubRkOkc2xawl6NYdLETjLvmrGhhI'
a = 138429774382724799266162638867586769792748493609302140496533867008095173455879947894779596310639574974753192434052788523153034589364467968354251594963074151184337695885797721664543377136576728391441971163150867881230659356864392306243566560400813331657921013491282868612767612765572674016169587707802180184907L
b = 166973306488837616386657525560867472072892600582336170876582087259745204609621953127155704341986656998388476384268944991674622137321564169015892277394676111821625785660520124854949115848029992901570017003426516060587542151508457828993393269285811192061921777841414081024007246548176106270807755753959299347499L
c = 139406975904616010993781070968929386959137770161716276206009304788138064464003872600873092175794194742278065731836036319691820923110824297438873852431436552084682500678960815829913952504299121961851611486307770895268480972697776808108762998982519628673363727353417882436601914441385329576073198101416778820619L
d = 120247815040203971878156401336064195859617475109255488973983177090503841094270099798091750950310387020985631462241773194856928204176366565203099326711551950860726971729471331094591029476222036323301387584932169743858328653144427714133805588252752063520123349229781762269259290641902996030408389845608487018053L
e = 104267926052681232399022097693567945566792104266393042997592419084595590842792587289837162127972340402399483206179123720857893336658554734721858861632513815134558092263747423069663471743032485002524258053046479965386191422139115548526476836214275044776929064607168983831792995196973781849976905066967868513707L
F = (a, b, c, d, e)
m = 8804961678093749244362737710317041066205860704668932527558424153061050650933657852195829452594083176433024286784373401822915616916582813941258471733233011L
g = 67051725181167609293818569777421162357707866659797065037224862389521658445401L
z = []
for i, f in enumerate(F):
    n = pow(f, m, g)
    this_is = 'Y-Combinator'
    l = (lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args))))(lambda f: lambda x: 1 if x < 2 else f(x - 1) * x % n)(g % 27777)
    c = raw_input('Channenge #%d:' % i)
    if int(c) != l:
        print 'Wrong~'
        exit()
    z.append(l)

z.sort()
gg = '(flaSg\'7 \\h#GiQwt~66\x0csxCN]4sT{? Zx YCf6S>|~`\x0c$/}\'\r:4DjJFvm]([sP%FMY"@=YS;CQ7T#zx42#$S_j0\\Lu^N31=r\x0b\t\tjVhhb_KM$|6]\nl!:V\rx8P[0m ;ho_\rR(0/~9HgE8!ec*AsGd[e|2&h!}GLGt\'=$\x0cbKFMnbez-q\\`I~];@$y#bj9K0xmI2#8 sl^gBNL@fUL\x0b\\9Ohf]c>Vj/>rnWXgLP#<+4$BG@,\'n a_7C:-}f(WO8Y\x0c2|(nTP!\'\\>^\'}-7+AwBV!w7KUq4Qpg\tf.}Z7_!m+ypy=`3#\\=?9B4=?^}&\'~ Z@OH8\n0=6\x0b\tv\nl!G\'y4dQW5!~g~I*f"rz1{qQH{G9\x0c\'b\x0cp\x0bdu!2/\\@i4eG"If0A{-)N=6GMC<U5/ds\rG&z>P1\nsq=5>dFZUWtjv\tX~^?9?Irwx\\5A!32N\x0bcVkx!f)sVY Men\x0c\'ujN<"LJ\x0c5R4"\\\\XPVA\'m$~tj)Br}C}&kX2<|\np3XtaHB.P\'(E 4$dm!uDyC%u ["x[VYw=1aDJ (8V/a!J?`_r:n7J88!a25AZ]#,ab?{%e\x0b]wN_}*Q:mh>@]u\t&6:Z*Fmr?U`cOHbAf7s@&5~L ,\tQ18 -Hg q2nz%\x0ccUm=dz&h1(ozoZ)mrA=`HKo\n\'rXm}Z-l3]WgN\\NW<{o=)[V({7<N1.-A8S"=;3sderb\tOZ$K\r0o/5\x0bMc76EGCWJ3IQpr7!QhbgzX8uGe3<w-g\'/j\'\tM4|9l?i&tm_\n57X0B2rOpuB@H@%L_\r)&/q=LZa(%}""#if#Kq74xK?`jGFOn"8&^3Q-\r#]E$=!b^In0:$4VKPXP0UK=IK)Y\rstOT40=?DyHor8j7O\\r/~ncJ5];cCT)c?OS0EM5m#V(-%"Tu:!UsE],0Dp  s@HErS]J{%oH54B&(zE.(@5#2k\tJnNlnUEij\\.q/3HBpJNk*X(k5;DlqK\'\'fX\r}EBk_7\x0b:>8~\t+M@WJx.PO({/U}1}#TqjreG\nN{\rX>4EsJr0Pn\\Z\\aL/-U<<{,Q;j\tF=7f\')+wH:p{G=_.s\\t-\x0bI\x0c*y\t1P:Y|/2xE<uo]~$>5k]FW+>fR<QA"(Fj[LL(hzfQo#PJ;:*0kB~3]9uL[o.xue:VQ\t;9-Tu\tq|mzzhV_okP\t,d\rQ`]5Gf\x0c#gXB\x0cAH|)NI|K=KW-&p-<b"3e.rO\x0cuK=\x0c^\r+MuLxCJ`UKaD\x0bBH&n+YVajZ(U7pwWtto3T10VLHwSJ\rK\t}\'F$l1:b2Bd\na=#t0iq}#!{1_)w$}<Dp(borC\'\t?r6;,+k;a(Q3@B?RCWYEDrjZe![x=n_%S]rl{&fLr*mgCD;92/nNsaxKy/;\nr]sPK=`+YP>MmfB\n8O4/"}nE7r*=41f2\t37>K\'s$wpl;qS[`qzu\x0b\t\nuaU|b,C`4& dRN~]7DnuTb2FhNHV!#Z2Hho\x0b[%.{O\t$q0\x0ch_@?w@b8[I^{JL|O8]i8{p)A.w)14qK3JoyF%licZ~ga\rW[L:W\rtIvfWJjZUOvB\rS.Beav3!-@bw|PexJ Pcw1\ry6!63B}]J])6fak/3r]W\tMeXt[uc(1_U lys{a1X\r%)[wwP3rhgNW{*d~_E%Q2htCt5ha@l0^0=\x0bwT\ni4/V;_\nM1rb?w~Q)Dli4u\n`}1+D8"\t`@V~$9l$Uy**VnI (@Ga0<RxfmoNgJTtE-aLH\rE5fMy7rk$)V\rL2Fv/AivOa"\nuX|70Xrw^D]%i%JyT\x0cc%cwZ/Wbp=IiY;/@nFEe>3=tM;K*`fReGoc5V/Ri?nXZ-RW)\'\t<\x0cV>@X@-Ei4%sO%},B_pjc`s"@oKCmdgDhjUZT@?mb\'?Q:F\x0bLJkPgjaFAc=rbrjAz$Zz\x0cq0GU!")xFOEF(x!3M\t:l83|}}HgGJJ#eT/I\x0b[|lK_n+;Wi/N^B4LzL.a(gVWq,zO6\'S|tb>RX` ca*CO<w\x0ci =wc1,M~\x0bc`FYEs\r){+Ll8[I9-88m\t\\iK/\\hno-C[vX*3Hx:%:K\rt\x0cW!tj\'SOhqxP|k7cw Hm?I@?P\'HmapG7$0#T(Auz]sjmd#\rFP/}53@-Kvmi(d%dZKLZ2LK\'e_E\x0bQmR 5/(irq4-EUyp<hB?[\tnU:p*xuzASM'
print ('').join(gg[(lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args))))(lambda f: lambda n: 1 if n < 3 else f(n - 1) + f(n - 2))(i + 2)] for i in range(16)) % ('').join(data[pow((__import__('fractions').gcd(z[(i % 5)], z[((i + 1) % 5)]) * 2 + 1) * g, F[(i % 5)] * (i * 2 + 1), len(data))] for i in range(32))

__import__('sys').setrecursionlimit(1048576)设置最大递归次数

lambda起到匿名函数的功能。可参考:

https://rosettacode.org/wiki/Y_combinator#Python

https://www.cnblogs.com/evening/archive/2012/03/29/2423554.html

我开始想读懂算法,但是这个lambda太难读了,毫无游戏体验感。

最后看了大佬的题解,才醒悟原来可以直接修改相关判断条件,不需要读懂算法。

将代码的第16行修改为c = l,则可以直接满足17行的c==l的判断条件。

修改后的代码为

__import__('sys').setrecursionlimit(1048576)
data = 'Tt1PJbKTTP+nCqHvVwojv9K8AmPWx1q1UCC7yAxMRIpddAlH+oIHgTET7KHS1SIZshfo2DOu8dUt6wORBvNVBpUSsuHa0S78KG+SCQtB2lr4c1RPbMf0nR9SeSm1ptEY37y310SJMY28u6m4Y44qniGTi39ToHRTyxwsbHVuEjf480eeYAfSVvpWvS8Oy2bjvy0QMVEMSkyJ9p1QlGgyg3mUnNCpSb96VgCaUe4aFu4YbOnOV3HUgYcgXs7IcCELyUeUci7mN8HSvNc93sST6mKl5SDryngxuURkmqLB3azioL6MLWZTg69j6dflQIhr8RvOLNwRURYRKa1g7CKkmhN4RytXn4nyK2UM/SoR+ntja1scBJTUo0I31x1wBJpT4HjDN47FLQWIkRW+2wnB3eEwO5+uSiQpzA8VaH7VGRrlU/BFW4GqbaepzKPLdXQFBkNyBKzqzR/zA2GIrYbLIVScWJ19DqJCOyVLGeVIVXyzN1y327orYL2Ee3lRITnE3FouicRStaznIcw8xmxvukwVMRZIJ/vTu8Zc1WQIYEIFXMHozGuvzZgROZTyFihWNRCBBtoP9DJJALJb0pA1IKIb2zLh+pwGF40Y6y93D6weKejGPO+A0DBXH9vuLcCcCIvr/XPQhO3jLKCBN+h9unuJKW3dyWxyaVPdR2V+BTw10VXolo7yaTH1GbR4TiVSB308mBOMwfchwihEe7RdMXvmXgaGarKkJe0NLUCd8jwhYII+WymjxO/xOz/ppOvNfAyIQksW0sggRPQTlgXSZ7MIVA1h66sGNljJ833MoFzWof3azLabaz1OrAJFqYXBg/myDsy1tV6rULSQ82hVR/TNnSmBGvyEDJTrLSwHyj78NOrW4mUnlLGBnAgWfw6pW2lRK2jkNX9NM6DfLsRK8lwl85UP8CZSuNdcLmLwHTVMZGm/cNkZCtWRBlZqEggxGdIO44D+f4y6ysnAk5/QzEwjIuecxEOb0jyV6dFui8g0c3Oxlhzcli0X8ToJFyeQRv1N9nokYZ07tFlG6m18kCToKz1qiH1U7kljXa6SvdORur5dWYLQ//gwhwppe7JlNda/cEoh92h96wRZDv1dSK/f1vz+mUeUyUlFY0iMjfw5eBXWZppNZi3ZtJcq5kllM2ACVFcxQWI3azM3ArOcqjosoiPjNoDYgKh7w4k2Cd0kLYEHscz/njtJ1KEcwLtqs4nJ+gB2r4V9g03YgvY5E8JJtfJMKdaTedjtvEuif8FNlCK9DMnL1iLpWptJbdfO83Y7Y46XCqjZFBI5o9Qtb78nLhMEM5/YTaNOM/wE/oJl5HI/i1X6kW3PKCsVubRkOkc2xawl6NYdLETjLvmrGhhI'
a = 138429774382724799266162638867586769792748493609302140496533867008095173455879947894779596310639574974753192434052788523153034589364467968354251594963074151184337695885797721664543377136576728391441971163150867881230659356864392306243566560400813331657921013491282868612767612765572674016169587707802180184907
b = 166973306488837616386657525560867472072892600582336170876582087259745204609621953127155704341986656998388476384268944991674622137321564169015892277394676111821625785660520124854949115848029992901570017003426516060587542151508457828993393269285811192061921777841414081024007246548176106270807755753959299347499
c = 139406975904616010993781070968929386959137770161716276206009304788138064464003872600873092175794194742278065731836036319691820923110824297438873852431436552084682500678960815829913952504299121961851611486307770895268480972697776808108762998982519628673363727353417882436601914441385329576073198101416778820619
d = 120247815040203971878156401336064195859617475109255488973983177090503841094270099798091750950310387020985631462241773194856928204176366565203099326711551950860726971729471331094591029476222036323301387584932169743858328653144427714133805588252752063520123349229781762269259290641902996030408389845608487018053
e = 104267926052681232399022097693567945566792104266393042997592419084595590842792587289837162127972340402399483206179123720857893336658554734721858861632513815134558092263747423069663471743032485002524258053046479965386191422139115548526476836214275044776929064607168983831792995196973781849976905066967868513707
F = (a, b, c, d, e)
m = 8804961678093749244362737710317041066205860704668932527558424153061050650933657852195829452594083176433024286784373401822915616916582813941258471733233011
g = 67051725181167609293818569777421162357707866659797065037224862389521658445401
z = []
for i, f in enumerate(F):
    n = pow(f, m, g)
    this_is = 'Y-Combinator'
    l = (lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args))))(lambda f: lambda x: 1 if x < 2 else f(x - 1) * x % n)(g % 27777)
    c = l 
    if int(c) != l:
        print 'Wrong~'
        exit()
    z.append(l)

z.sort()
gg = '(flaSg\'7 \\h#GiQwt~66\x0csxCN]4sT{? Zx YCf6S>|~`\x0c$/}\'\r:4DjJFvm]([sP%FMY"@=YS;CQ7T#zx42#$S_j0\\Lu^N31=r\x0b\t\tjVhhb_KM$|6]\nl!:V\rx8P[0m ;ho_\rR(0/~9HgE8!ec*AsGd[e|2&h!}GLGt\'=$\x0cbKFMnbez-q\\`I~];@$y#bj9K0xmI2#8 sl^gBNL@fUL\x0b\\9Ohf]c>Vj/>rnWXgLP#<+4$BG@,\'n a_7C:-}f(WO8Y\x0c2|(nTP!\'\\>^\'}-7+AwBV!w7KUq4Qpg\tf.}Z7_!m+ypy=`3#\\=?9B4=?^}&\'~ Z@OH8\n0=6\x0b\tv\nl!G\'y4dQW5!~g~I*f"rz1{qQH{G9\x0c\'b\x0cp\x0bdu!2/\\@i4eG"If0A{-)N=6GMC<U5/ds\rG&z>P1\nsq=5>dFZUWtjv\tX~^?9?Irwx\\5A!32N\x0bcVkx!f)sVY Men\x0c\'ujN<"LJ\x0c5R4"\\\\XPVA\'m$~tj)Br}C}&kX2<|\np3XtaHB.P\'(E 4$dm!uDyC%u ["x[VYw=1aDJ (8V/a!J?`_r:n7J88!a25AZ]#,ab?{%e\x0b]wN_}*Q:mh>@]u\t&6:Z*Fmr?U`cOHbAf7s@&5~L ,\tQ18 -Hg q2nz%\x0ccUm=dz&h1(ozoZ)mrA=`HKo\n\'rXm}Z-l3]WgN\\NW<{o=)[V({7<N1.-A8S"=;3sderb\tOZ$K\r0o/5\x0bMc76EGCWJ3IQpr7!QhbgzX8uGe3<w-g\'/j\'\tM4|9l?i&tm_\n57X0B2rOpuB@H@%L_\r)&/q=LZa(%}""#if#Kq74xK?`jGFOn"8&^3Q-\r#]E$=!b^In0:$4VKPXP0UK=IK)Y\rstOT40=?DyHor8j7O\\r/~ncJ5];cCT)c?OS0EM5m#V(-%"Tu:!UsE],0Dp  s@HErS]J{%oH54B&(zE.(@5#2k\tJnNlnUEij\\.q/3HBpJNk*X(k5;DlqK\'\'fX\r}EBk_7\x0b:>8~\t+M@WJx.PO({/U}1}#TqjreG\nN{\rX>4EsJr0Pn\\Z\\aL/-U<<{,Q;j\tF=7f\')+wH:p{G=_.s\\t-\x0bI\x0c*y\t1P:Y|/2xE<uo]~$>5k]FW+>fR<QA"(Fj[LL(hzfQo#PJ;:*0kB~3]9uL[o.xue:VQ\t;9-Tu\tq|mzzhV_okP\t,d\rQ`]5Gf\x0c#gXB\x0cAH|)NI|K=KW-&p-<b"3e.rO\x0cuK=\x0c^\r+MuLxCJ`UKaD\x0bBH&n+YVajZ(U7pwWtto3T10VLHwSJ\rK\t}\'F$l1:b2Bd\na=#t0iq}#!{1_)w$}<Dp(borC\'\t?r6;,+k;a(Q3@B?RCWYEDrjZe![x=n_%S]rl{&fLr*mgCD;92/nNsaxKy/;\nr]sPK=`+YP>MmfB\n8O4/"}nE7r*=41f2\t37>K\'s$wpl;qS[`qzu\x0b\t\nuaU|b,C`4& dRN~]7DnuTb2FhNHV!#Z2Hho\x0b[%.{O\t$q0\x0ch_@?w@b8[I^{JL|O8]i8{p)A.w)14qK3JoyF%licZ~ga\rW[L:W\rtIvfWJjZUOvB\rS.Beav3!-@bw|PexJ Pcw1\ry6!63B}]J])6fak/3r]W\tMeXt[uc(1_U lys{a1X\r%)[wwP3rhgNW{*d~_E%Q2htCt5ha@l0^0=\x0bwT\ni4/V;_\nM1rb?w~Q)Dli4u\n`}1+D8"\t`@V~$9l$Uy**VnI (@Ga0<RxfmoNgJTtE-aLH\rE5fMy7rk$)V\rL2Fv/AivOa"\nuX|70Xrw^D]%i%JyT\x0cc%cwZ/Wbp=IiY;/@nFEe>3=tM;K*`fReGoc5V/Ri?nXZ-RW)\'\t<\x0cV>@X@-Ei4%sO%},B_pjc`s"@oKCmdgDhjUZT@?mb\'?Q:F\x0bLJkPgjaFAc=rbrjAz$Zz\x0cq0GU!")xFOEF(x!3M\t:l83|}}HgGJJ#eT/I\x0b[|lK_n+;Wi/N^B4LzL.a(gVWq,zO6\'S|tb>RX` ca*CO<w\x0ci =wc1,M~\x0bc`FYEs\r){+Ll8[I9-88m\t\\iK/\\hno-C[vX*3Hx:%:K\rt\x0cW!tj\'SOhqxP|k7cw Hm?I@?P\'HmapG7$0#T(Auz]sjmd#\rFP/}53@-Kvmi(d%dZKLZ2LK\'e_E\x0bQmR 5/(irq4-EUyp<hB?[\tnU:p*xuzASM'
print ('').join(gg[(lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args))))(lambda f: lambda n: 1 if n < 3 else f(n - 1) + f(n - 2))(i + 2)] for i in range(16)) % ('').join(data[pow((__import__('fractions').gcd(z[(i % 5)], z[((i + 1) % 5)]) * 2 + 1) * g, F[(i % 5)] * (i * 2 + 1), len(data))] for i in range(32))

但是在windows下运行还是

img

此题非预期?本网站的中等难度的逆向题大概能有四五十个成功解答的,但是此题有将近一百个拿到flag的。不应该啊?

后来在kail下直接运行成功(我怀疑是递归那里出的问题)

img

此题的心得:

1、不一定非要理解算法,可以特殊途径绕过算法。

2、程序运行出错可以考虑换平台,不要拘束。

045 accumulator

题目名称的意思是累加器,让你不好好学英语。。。

主函数:

输入字符串

img

加密代码

img

先对sha后的字符串加密,再对原字符串加密

sub_4008C0

img

根据实际含义我修改了变量名。

关键代码就是28行,累加。29行判断累计后的值和数据库中的值是否一致。

使用IDC脚本提取数据库数据。https://blog.csdn.net/qq_35078631/article/details/79849977

shift+f2(或file->script command)

img

static main()
{
    auto i,fp;
    fp = fopen("d:\\dump","wb");
    auto start = 0x601080;
    auto size = 0x601398 - 0x601080;
    for(i=start;i<start+size;i++)
    {
        fputc(Byte(i),fp);
    }
    fp.close();
}

点击run。相关数据写入d:dump文件中。

python解密脚本

import binascii

with open('dump','rb')as f:
    data = f.read()
num = []
for i in range(len(data)//4):
    d = data[4*i : 4*i+4][::-1]    #b'\x00\x00C\xdf'
    d = str(binascii.hexlify(d))[2:-1]    #000043df
    d = int(d,16)    #17375
    num.append(d)

for i,n in enumerate(num):
    if i<len(num)-1:
        a = num[i]
        b = num[i+1]
        print(chr(b-a),end='')

输出为

img

后半段为flag

046 GCCC

img

这是c#写的.net程序。

NET是个平台,理论上,各种语言都可以编译成它的IL,在上面运行。.NET开发,就是把它当作目标平台的开发。(除非你在极少数的公司,那是真正做.NET开发的。做的是开发.NET这个平台本身。)然而实际上,.NET上还分了阶级。C#是全能的亲儿子,ASP/VB/F#是能力较弱的亲儿子,其他语言那是干儿子或者过继的。所以,实际中,你可以认为就是在搞C#了。

使用ILSpy逆向

img

关键代码

img

num是输入的数字,正确则进行解密并输出flag。解密时需要用到num,所以无法绕过,必须求出num。

程序对num进行了32轮验证,每次num右移1位。

最后num为0。

num需要满足以下条件:

范围在[2^31, 2^32)

FLAG{开头,

}结尾,

中间字符 in "ABCDEFGHIJKLMNOPQRSTUVWXYZ{} "

可以用z3约束性求解。

我写的python3:

from z3 import *
array = [164,25,4,130,126,158,91,199,173,252,239,143,150,251,126,39,104,104,146,208,249,9,219,208,101,182,62,92,6,27,5,46]
b = 0
num = BitVec('num', 64)
solver = Solver()
solver.add(num >= 2**31)    #.add()添加约束性条件
solver.add(num < 2**32)

for num2 in range(32):
    if num2 < 5:
        solver.add((array[num2] ^ num ^ b) & 0x7f == ord('FLAG{'[num2]))

    elif num2 == 31:
        solver.add((array[num2] ^ num ^ b) & 0x7f == ord('}'))

    else:
        solver.add(
            Or(
                And(
                    ((array[num2] ^ num ^ b) & 0x7f >= ord('A')),
                    ((array[num2] ^ num ^ b) & 0x7f <= ord('Z'))
                ),
                ((array[num2] ^ num ^ b) & 0x7f == ord(' '))
            )
        )
    b ^= array[num2]
    num >>= 1
if solver.check() == sat:    #ok为sat,否则为unsat,不是字符串
    print(solver.model())    #结果

针对脚本的注释:

1、 Int类型函数无法顺利表示过大的数,使用x = BitVec('x',64)可以声明在64bit之内的变量。第一个参数是变量名(字符串),第二个参数不一定非是64

2、注意Or和And。条件之间要有逗号,最后一个条件后没有逗号

3、坑死我的游标卡尺:第26、27行一开始被我搞在了else的域内。

4、&0x7f的原因:原代码char c = (char)(array[num2] ^ (byte)num ^ b); (char),强制转换为char类型,char的范围是0~127,而&0x7f可以将符号位归零。

之前参考的大佬的题解中solver.add((array[num2] ^ (num & 0x7f) ^ b) & 0x7f == ord('FLAG{'[num2])),对byte类型的num也&0x7f,还解释称:java中的byte函数要用&0x7f来处理。

两个错误:一不是java,二byte类型-128~127,不需要&0x7f。虽然他的代码也能跑出结果。

这位大佬的题解http://myhackerworld.top/2018/10/24/hackme-inndy-tw-Reversing-wp/

运行脚本,输出[num = 3658134498]

则在gccc.exe中输入3658134498,拿到flag。

要在cmd下运行程序哦,否则程序输出flag后一闪而过,根本来不及看到flag。

047 ccc

主函数

img

加密函数verify

img

关键代码是第13行,分别对flag的前三位,前六位,前九位...进行crc32加密(我之前错误地理解成了对前三位,四至六位,七至九位crc32加密)。

加密后地数据存在hashes处

提取hashes处数据,winhex保存成文件。

写的解密脚本:

import binascii

def decode(dword, flag):
    print(dword,end=' ')
    import string
    char = string.printable    #所有可打印字符
    for i in char:
        for j in char:
            for k in char:
                s = flag + i + j + k
                crc32 = hex(binascii.crc32(s.encode()))[2:]    #去掉0x开头
                crc32 = crc32 if len(crc32)==8 else '0'+crc32
                if crc32 == dword:
                    print(s)
                    return s


with open('11.txt','rb')as f:
    data = f.read()
flag = ''
for i in range(len(data)//4):
    d = data[4*i : 4*i+4][::-1]   #原来是小端,反转显示大端
    d = str(binascii.hexlify(d))[2:-1]    #去除b''
    flag = decode(d, flag)

写这个脚本有好几个坑:

1、crc32加密:binascii.crc32()

在python2中,binascii.crc32(v) & 0xffffffff

& 0xffffffff可以由符号数得到无符号数

在python3中,binascii.crc32(s.encode())

字符串要encode(),由str型得到字节(bytes)型,否则出现报错TypeError: a bytes-like object is required, not ‘str‘

2、python3返回二进制数据 data 的十六进制表示形式:binascii.hexlify(d)

前:b'\xd6AYo'

后:b‘d641596f’

python2只需要在后面.encode('hex')即可

3、hex(binascii.crc32(s.encode()))的结果,不算0x的前缀,如果第一位应该是0,结果会只有七位,需要手动添上0。坑死我了

4、关于数据读入,特别是大头小头的,可以学习一下python的struct

https://codeday.me/bug/20181225/466201.html

https://segmentfault.com/a/1190000016851956

https://www.docs4dev.com/docs/zh/python/3.7.2rc1/all/library-struct.html

运行截图

img

过几天仔细学一下编码吧,读一读《深入理解计算机系统》。python2和3的编码异同也要了解一下,不然很多函数的参数的类型总是搞不对。

048 bitx

img

命令行运行,参数为flag。将flag地址转换为int传入verify

verify代码:

signed int __cdecl verify(int input_address)
{
  int i; // [esp+Ch] [ebp-4h]

  for ( i = 0; *(_BYTE *)(i + input_address) && *(_BYTE *)(i + 0x804A040); ++i )
  {
    if ( *(_BYTE *)(i + input_address) + 9 != ((unsigned __int8)((*(_BYTE *)(i + 0x804A040) & 0xAA) >> 1) | (unsigned __int8)(2 * (*(_BYTE *)(i + 0x804A040) & 0x55))) )// |是bit的或,不是条件或。。。
      return 0;
  }
  return 1;
}

关键第7行,进行位变换。

我一开始把|当成了||,卡了很久。

提取0x804A040处的数据用winhex保存在文件中后,运行python脚本

with open('11.txt','rb')as f:
    data = f.read()
for byte in data:
    #print(byte,end=' ')
    s = (((byte & 0xAA) >> 1) | (2 * (byte & 0x55))) -9
    print(chr(s),end='')

FLAG{Swap tw6bits is easy 0xaa wit60x55}

img

但是提交时不正确,明天再看看。

重新把数据通过winhex搞成文件后再运行,拿到FLAG{Swap two bits is easy 0xaa with 0x55},估计是之前那次winhex数据搞错了。但是,输入错误的flag,为什么也是Good?搞不明白。难受。过两天需要学一下idaPython了。

050 what-the-hell

分析

输入两个key,求出第三个key,然后解密输出flag.

1579339786622

key1,key2可以通过下面代码的数据求出来。

what函数是斐波那契数列(Fibonacci sequence)。

斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34

假定斐波那契数列中数值为key1的项是第i项,则key3 = key2 * i + 1

1579339820009

所以,其实本程序本身就是可以输出flag的。

但是what这个求斐波那契数列的函数,是递归实现的,速度极其缓慢。

1579352196214

不过,出题人还给我们留了一个迭代实现的求斐波那契数列的函数fast_what,速度就快多了。

1579352267734

所以解题思路是通过z3求出key1和key2,然后通过ida把calc_key3中的call whatpatch成call fast_what

z3求key1,key2

不过z3求key有个大坑,求出的解有两组,但是正常写法z3只给出一组,参考了M4x师傅-0x09 what-the-hell的代码,学到了z3多解输出的新知识。

from z3 import *

def isPrime(n): 
    if n <= 1: 
        return False
    if n == 2: 
        return True
    if n % 2 == 0: 
        return False
    i = 3
    while i * i <= n: 
        if n % i == 0: 
          return False
        i += 2
    return True

a = BitVec('a', 32)
b = BitVec('b', 32)
s = Solver()

s.add(a * b == 0xDDC34132)
s.add((a ^ 0x7E) * (b + 16) == 0x732092BE )
s.add(((a - b) & 0xFFF) == 3295)

while s.check() == sat:
    if isPrime(s.model()[a].as_long()):
        print(s.model())
    s.add(Or(a != s.model()[a], b != s.model()[b]))
else:
    print('unset')
#输出:
#[b = 1234567890, a = 2136772529]
#[b = 1234567890, a = 4284256177]
#unset

我最初只拿到第一组解,运行下一步patch后的程序,输入这组key,程序一直没有输出flag,按说应该很快就拿到flag。这是因为程序一直没有满足斐波那契数列的第i项与key1相等,所以一直在循环中。

IDA patch 程序

来到函数calc_key3中调用函数what的地方:

1579352707642

1579352740083

1579352761610

1579352782196

最后还要将改动写入文件。

1579352860255

运行

将文件拷贝到linux机器中并运行。

1579353068607

秒出flag.

051 unpackme

(2020.4.2补充:此为UPXPR保护,可参考《加密与解密》第四版P626)

upxshell脱壳失败,观察十六进制数据,发现壳的某些关键信息被改掉了。

找一个正常upx加壳的程序做对比:

1579362953863

使用010 editor,修改如下信息:

!The flag is not FLAG{Hello,DOS section} -> !This program cannot be run in DOS mode.
CTF0 -> UPX0
CTF1 -> UPX1
CTF2 -> UPX2
CTF? -> UPX!

然后脱壳:1579363117211

脱壳后无法正常运行,但是可以通过ida查看源代码。

1579363249530

第60行求得flag(Text),且byte_410A80pbData的值均已知,所以只需要爆破v11即可。

byte_410A80 = [0x1a,0x8b,0x24,0x28,0x58,0x37,0xac,0x52,0x53,0xb5,0x1e,0x3e,0x4a,0x25,0x4a,0x27,0x6b,0xb2,0x17,0x1,0x3,0x0b,0xf4,0x14,0,0xf1,0x61,0x70,0x0c,0x55,0x20,0x7a]
print(len(byte_410A80))
pbData = [0x34,0xaf,0x0d,0x7,0x4b,0x17,0xf4,0x4d,0x1b,0xb9,0x39,0x76,0x5b,0x2,0x77,0x6f]
for i in range(32, 128):
    flag = []
    for j in range(len(byte_410A80)):
        flag.append((i ^ byte_410A80[j] ^ pbData[j & 0xf]) & 0x7f)
    print(i, ''.join(list(map(chr,flag))))

参考:

Last modification:April 2nd, 2020 at 06:32 pm