[GUET-CTF2019]re UPX壳,Kali脱壳 elf文件,IDA64打开 通过字符串找到这里 看if判断里面的函数sub_4009AE()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 _BOOL8 __fastcall sub_4009AE (char *a1) { if ( 1629056 * *a1 != 166163712 ) return 0LL ; if ( 6771600 * a1[1 ] != 731332800 ) return 0LL ; if ( 3682944 * a1[2 ] != 357245568 ) return 0LL ; if ( 10431000 * a1[3 ] != 1074393000 ) return 0LL ; if ( 3977328 * a1[4 ] != 489211344 ) return 0LL ; if ( 5138336 * a1[5 ] != 518971936 ) return 0LL ; if ( 7532250 * a1[7 ] != 406741500 ) return 0LL ; if ( 5551632 * a1[8 ] != 294236496 ) return 0LL ; if ( 3409728 * a1[9 ] != 177305856 ) return 0LL ; if ( 13013670 * a1[10 ] != 650683500 ) return 0LL ; if ( 6088797 * a1[11 ] != 298351053 ) return 0LL ; if ( 7884663 * a1[12 ] != 386348487 ) return 0LL ; if ( 8944053 * a1[13 ] != 438258597 ) return 0LL ; if ( 5198490 * a1[14 ] != 249527520 ) return 0LL ; if ( 4544518 * a1[15 ] != 445362764 ) return 0LL ; if ( 3645600 * a1[17 ] != 174988800 ) return 0LL ; if ( 10115280 * a1[16 ] != 981182160 ) return 0LL ; if ( 9667504 * a1[18 ] != 493042704 ) return 0LL ; if ( 5364450 * a1[19 ] != 257493600 ) return 0LL ; if ( 13464540 * a1[20 ] != 767478780 ) return 0LL ; if ( 5488432 * a1[21 ] != 312840624 ) return 0LL ; if ( 14479500 * a1[22 ] != 1404511500 ) return 0LL ; if ( 6451830 * a1[23 ] != 316139670 ) return 0LL ; if ( 6252576 * a1[24 ] != 619005024 ) return 0LL ; if ( 7763364 * a1[25 ] != 372641472 ) return 0LL ; if ( 7327320 * a1[26 ] != 373693320 ) return 0LL ; if ( 8741520 * a1[27 ] != 498266640 ) return 0LL ; if ( 8871876 * a1[28 ] != 452465676 ) return 0LL ; if ( 4086720 * a1[29 ] != 208422720 ) return 0LL ; if ( 9374400 * a1[30 ] == 515592000 ) return 5759124 * a1[31 ] == 719890500 ; return 0LL ; }
输入的每一位乘上一个数字之后是另一个数字用来检验,那么除回去就行了,记得取整除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 a0 = 166163712 // 1629056 a1 = 731332800 // 6771600 a2 = 357245568 // 3682944 a3= 1074393000 // 10431000 a4= 489211344 // 3977328 a5 = 518971936 // 5138336 a6='_' a7= 406741500 // 7532250 a8= 294236496 // 5551632 a9= 177305856 // 3409728 a10= 650683500 // 13013670 a11= 298351053 // 6088797 a12= 386348487 // 7884663 a13= 438258597 // 8944053 a14= 249527520 // 5198490 a15= 445362764 // 4544518 a16= 981182160 //10115280 a17= 174988800 // 3645600 a18= 493042704 // 9667504 a19= 257493600 // 5364450 a20= 767478780 // 13464540 a21= 312840624 // 5488432 a22= 1404511500 // 14479500 a23= 316139670 // 6451830 a24= 619005024 // 6252576 a25= 372641472 // 7763364 a26= 373693320 // 7327320 a27= 498266640 // 8741520 a28= 452465676 // 8871876 a29= 208422720 // 4086720 a30= 515592000 // 9374400 a31= 719890500 // 5759124 print(chr (a0),chr (a1),chr (a2),chr (a3),chr (a4),chr (a5),a6,chr (a7),chr (a8),chr (a9),chr (a10),chr (a11),chr (a12),chr (a13),chr (a14),chr (a15),chr (a16),chr (a17),chr (a18),chr (a19),chr (a20),chr (a21),chr (a22),chr (a23),chr (a24),chr (a25),chr (a26),chr (a27),chr (a28),chr (a29),chr (a30),chr (a31))
flag{e_65421110ba03099a1c039337} 少了第6位,爆破得到1 flag是flag{e165421110ba03099a1c039337}
[SUCTF2019]SignIn 这题以前做过,elf文件,ida64打开 程序调用了 __gmpz_init_set_str
函数,这是一个 GNU 高精度算法库,在RSA加密中见过几次,看下格式确定了这是RSA加密
1 2 3 4 5 int mpz_init_set_str (mpz_t rop, char *str, int base) mpz_t rop:多精度整数变量 char *str: 字符串int base: 进制将str按照base进制转换为rop
1 2 void mpz_powm (mpz_t rop, const mpz_t base, const mpz_t exp, const mpz_t mod) [Function] 函数功能: rop = base^exp 取余mod
从题目中得到数据
1 2 3 密文:ad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35 N(十进制):103461035900816914121390101299049044413950405173712170434161686539878160984549 E:65537
分解N得到p,q,分解教程参考这个
1 2 p = 366669102002966856876605669837014229419 q = 282164587459512124844245113950593348271
1 2 3 4 5 6 7 8 9 10 11 12 import gmpy2import binasciip = 282164587459512124844245113950593348271 q = 366669102002966856876605669837014229419 e = 65537 c = 0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35 n = p * q d = gmpy2.invert(e, (p-1 ) * (q-1 )) m = gmpy2.powmod(c, d, n) print(binascii.unhexlify(hex (m)[2 :]).decode(encoding="utf-8" ))
suctf{Pwn_@_hundred_years}
flag是:flag{Pwn_@_hundred_years}
相册 apk逆向,打开jeb,通过字符串找到关键函数 最下面有一个函数,跟进去查看 提示了邮箱,这里有new了新的邮箱,点击MAILUSER那一行跟进去查看 可以看到MAILSERVER,这是是加载外部so文件中NativeMethod.m()函数所返回的值,再进行base64解密。因此我们只需要找到so文件中经过base64加密的字符串。 导出,使用ida打开,通过字符串搜索找到类似base64加密后的字符串 有3个都解一下发现第二个是个邮箱地址 flag是:flag{18218465125@163.com}
[ACTF新生赛2020]usualCrypt 找到main函数 12 和 26 行的sub_403CF8是输出函数,21 - 25 行的while()是字符串比较的过程, 输入 flag 加密验证正确性的模型 看19行的函数sub_401080
先执行了sub_401000
,这是一个改变密钥对应表的函数,后面是base64加密算法,最后还有一个函数sub_401030
,这是交换大小写字母的。
看函数sub_401000
将两个数组里的数据进行了交换,根据地址两个数组连在一起,也可以当成一个数组看,从下标为6开始到下标为15,往后偏移了10(0xA)位,也就是QRSTUVWXY和GHIJKLMNOP相互交换了一下 新的密码表是ABCDEFQRSTUVWXYGHIJKLMNOPZabcdefghijklmnopqrstuvwxyz0123456789+/
逆向推导: 首先要对byte_40E0E4
数组进行大小写转换;然后是还原经 base64(更改密钥表后)加密字符的原含义;最后得到了真实的加密字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 import base64flag = '' ; dict = {}; offset = 10 orgin = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' for i in range (len (orgin)): dict [orgin[i]] = orgin[i] for i in range (6 , 15 ): dict [orgin[i]] , dict [orgin[i+offset]] = dict [orgin[i+offset]] , dict [orgin[i]] secret = 'zMXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9' .swapcase() for i in range (len (secret)): flag += dict [secret[i]] flag = base64.b64decode(flag) print(flag)
flag是:flag{bAse64_h2s_a_Surprise}