Crypto easymath 1 2 3 assert (len (open ('flag.txt' , 'rb' ).read()) < 50 )assert (str (int .from_bytes(open ('flag.txt' , 'rb' ).read(), byteorder='big' ) << 10000 ).endswith( '1862790884563160582365888530869690397667546628710795031544304378154769559410473276482265448754388655981091313419549689169381115573539422545933044902527020209259938095466283008' ))
代码很短,也可以直接搜到原题
bytesorder='big'
可以理解是正常的顺序
主要是觉得很神奇,左移10000位,然后只告诉了低579位,真的可以还原吗?
不过用数学语言来表达就习惯多了 $$ c=flag\times 2^{10000}\ mod\ 10^{175}\notag $$ 相当于取了个余;只要求出$2^{10000}$在模$10^{175}$下的逆元就行,这不是有手就行,但显然这个逆元并不存在,但问题不大,稍微变一下 $$ c=flag\times 2^{10000}\ mod\ 5^{175}\notag $$
因为有性质,如果$a\equiv b\ (mod\ n),\ a\equiv b\ (mod\ m),\ (m, n)=1$,则$a\equiv b(mod\ mn)$
感觉反着来也成立的吧,显然$(2^{175},\ 5^{175})=1$
1 2 3 4 5 6 7 8 9 10 from Crypto.Util.number import *from gmpy2 import *n = 5 ** 175 c = 1862790884563160582365888530869690397667546628710795031544304378154769559410473276482265448754388655981091313419549689169381115573539422545933044902527020209259938095466283008 c = c phi = 5 ** 174 e = 2 ** 10000 d = invert(e, n) print (long_to_bytes(c * d % n))
ezRSA 直接转化成等于的形式,然后取个gcd,因为取出来可能不是正好是n和p,所以用分解攻击factordb剔除小因子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 from Crypto.Util.number import *plain1 = 3796374001 cipher1 = 10814407739419442187905858785036186878265127046318055454993453460552141704269761831133605965488334657725928223663072928135729092442048892277444747664105855191494328013597494843840801624660190005877515193495251116322331333145225214492628388272052283297261629247983765384231471683884012700575979269960065526415802023634510913009036934242220680865773837250316443624988133196570064551438174112950794689256211630478109685814880608384948776450292755634359375937804770120858228075005653177911703351120582838064680054557165091424216996781206537691443956931890710761301856045586473958014856501026856223946554632634123695548179 plain2 = 4274439796 cipher2 = 87226798597265930735797832586236279967789468186786741246367414679613517601654025942029826295922574046522178393263827646913102970456195019295401416652274787934598801006209685121040719655143935749480878915637540137699100422932935519357118466505812144970497483991623024823375063776302868706571808198638413485212863316779488625319157322436072639726910982871292474427111853478193221459564153774349503133897947087219144794655871631028877397232372688447849203202066982834256420368807780090246093374914035033275326840206150648030439511140807548259558987343365751983159445433804444373606478977126329710773866415852267322001 plain3 = 3325291543 cipher3 = 9382727308462526071828291861625444755821341794212101844314359460079432045375739882063652976611283182057033881092525502333782051326520856709162727825183042333495142759484340360567209663928461296371430651153068234201274220444046746723715852931539307137462642852266744794350148429783596186264775135674497726336356558991142315096962405777053398974439740872315007701981484005150026915096332916499718849929261683668753849212760142928383699802276667736418472263282318556853006287601969938973761042341846844526359073801116843895009315716346895596793683181704835335051683309743931741006154082213663428178283831538866255884755 plain4 = 1344652736 cipher4 = 4321964026676773781748104809247153356237715067039867231031624087256207483823813596319043458347848480918702592529113491431289681396399509022324524505867856178311958890363168588728856811216344821674576551978795805425938895529979965804450330107190184989162075120112336133813443406172261019202954524704870212620162773467949822492505161759519710435619043135693162949516270801813957833639117255071409629966835262468558867355399456489652824578176999147239152024128878816180401772196756218195440508847291475372211289300191672193680292568402473128269561454972660235893426215596184157205084579301349999511988743927089317168711 c = 7676870019429280974392994820719779231294040954319033563743135447473572416831050516949578774541281865709413894823796173396916557712257817949278444474172193939467995392598453462557057904995693840979847693206445078435907817047607948884368740596897139479299803522434307154541548742050088306413312454547460881877229439237898277933224023743845054110141568593673519203476919586868299617487091772845879027851695029674390129630380608842037317291970843742534837090616445063709778227810263198355145168049129671663511533431798983910771539362325095830241252453404715144468588527605118717772056998732396545216696090692231228929195 e = 0x10001 n = gcd(plain1**e-cipher1, plain3**e-cipher3) // 2 p = gcd(plain2**e-cipher2, plain4**e-cipher4) // 65 print (long_to_bytes(pow (c, invert(e, (p-1 )*(q-1 )), n)))
let’s play with rsa~ 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 from sympy import isprime,nextprimefrom Crypto.Util.number import getPrime as getprime ,long_to_bytes,bytes_to_long,inverseflag='flag{***************}' def play (): p=getprime(1024 ) q=getprime(1024 ) n=p*q e=65537 print "Hello,let's play rsa~\n" print 'Now,I make some numbers,wait a second\n' n1=getprime(200 ) n2=getprime(200 ) number=n1*n2 print "Ok,i will send two numbers to you,one of them was encoded.\n" print "Encode n1:%d,\n" %(pow (n1,e,n)) print "And n2:%d.\n" %n2 print "Information that can now be made public:the public key (n,e):(%d,%d)\n" %(n,e) while True : try : c=int (raw_input("ok,now,tell me the value of the number (encode it for safe):" )) except : print "Sorry,the input is illeagal, and the integer is accept~" else : break d=inverse(e,(p-1 )*(q-1 )) m=pow (c,d,n) if m==number: print "It's easy and interesting,didn't it?\n" print "This is the gift for you :" +flag else : print "Emmmmm,there is something wrong, bye~\n" if __name__ == '__main__' : play()
简单性质的应用,想让我们给出$c=(n_1\times n_2)^e\ mod\ n$,提供了n和e,以及$c_1=n_1^e\ mod\ n$和$n_2$ $$ c=(n_1^e\ mod\ n\cdot n_2^e\ mod\ n)\ mod\ n=(c_1\cdot n_2^e\ mod\ n)\ mod\ n\notag $$
Re py 看出的人比较多,想肯定有原题,然后就搜到了这位师傅的博客,逆向ctf-2020湖湘杯Re_03 ,一些python的反编译操作
首先用PE工具看下
不知道哪里不对,但是用PEiD看,会告诉你是一个无效的exe文件
说是用python打包的exe文件,反编译一下,使用github的pyinstxtractor.py
工具
python pyinstxtractor.py py.exe
会得到一个文件夹,需要关注没有后缀名的py
和struct
,用查看内码的软件打开,将struct
文件开头和py
不一样的代码给拷贝到py
处,保存成.pyc
文件
然后用uncompyle6
反编译的成源文件,直接用pip install uncompyle
即可安装
uncompyle6 py.pyc py.py
得到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def encode (s ): str = '' for i in range (len (s)): res = ord (s[i]) ^ 32 res += 31 str += chr (res) return str m = 'ek`fz13b3c5e047b`bd`0/c268e600e7c5d1`|' strings = '' strings = input ('Input:' ) if encode(strings) == m: print 'Correct!' else : print 'Try again!'
然后逆回去就好了
apkrev(not solve) 用模拟器打开,发现要输入一个注册码,然后安卓逆向工具去分析,找到MainActivity中的onClick,发现关键的函数myCheck
被隐藏了,搜了下,藏在.so
文件里了,所以将.apk
改成.zip
然后解压找到
说是类似RC4的流密码
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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 __int64 __fastcall Java_com_example_re_MainActivity_myCheck (__int64 a1, __int64 a2, __int64 a3) { const char *v3; unsigned __int64 v4; __int64 v5; char *v6; unsigned __int64 v7; char v8; void *v9; const char *v10; size_t v11; unsigned int v12; _DWORD *v13; int32x4_t v14; __int64 v15; int32x4_t v16; int32x4_t v17; char *v18; int32x4_t v19; __int64 v20; unsigned __int8 v21; int v22; char *v23; int v24; char *v25; __int64 v26; __int64 v27; __int64 v28; char *v29; int v30; int v31; __int64 v32; unsigned __int64 v34; __int64 v35; char *v36; __int128 dest[33 ]; _ReadStatusReg(ARM64_SYSREG(3 , 3 , 13 , 0 , 2 )); v3 = (const char *)(*(__int64 (__fastcall **)(__int64, __int64, _QWORD))(*(_QWORD *)a1 + 1352LL ))(a1, a3, 0LL ); v34 = 0LL ; v35 = 0LL ; v36 = 0LL ; v4 = strlen (v3); v5 = v4; if ( v4 >= 0x17 ) { v7 = (v4 + 16 ) & 0xFFFFFFFFFFFFFFF0 LL; v6 = (char *)operator new (v7); v35 = v5; v36 = v6; v34 = v7 | 1 ; goto LABEL_5; } v6 = (char *)&v34 + 1 ; LOBYTE(v34) = 2 * v4; if ( v4 ) LABEL_5: memcpy (v6, v3, v5); v6[v5] = 0 ; dest[30 ] = 0u ; dest[31 ] = 0u ; dest[28 ] = 0u ; dest[29 ] = 0u ; dest[26 ] = 0u ; dest[27 ] = 0u ; dest[24 ] = 0u ; dest[25 ] = 0u ; dest[22 ] = 0u ; dest[23 ] = 0u ; dest[20 ] = 0u ; dest[21 ] = 0u ; dest[18 ] = 0u ; dest[19 ] = 0u ; dest[16 ] = 0u ; dest[17 ] = 0u ; dest[14 ] = 0u ; dest[15 ] = 0u ; dest[12 ] = 0u ; dest[13 ] = 0u ; dest[10 ] = 0u ; dest[11 ] = 0u ; dest[8 ] = 0u ; dest[9 ] = 0u ; dest[7 ] = 0u ; dest[5 ] = 0u ; dest[6 ] = 0u ; dest[3 ] = 0u ; dest[4 ] = 0u ; dest[1 ] = 0u ; dest[2 ] = 0u ; dest[0 ] = 0u ; fflush(&_sF); v8 = v34; v9 = v36; if ( (v34 & 1 ) != 0 ) v10 = v36; else v10 = (char *)&v34 + 1 ; v11 = strlen (v10); memcpy (dest, v10, v11); v12 = 0 ; if ( strlen ((const char *)dest) != 32LL ) { LABEL_23: if ( (v8 & 1 ) == 0 ) return v12; LABEL_24: operator delete (v9) ; return v12; } v13 = malloc (0x408 u); v14 = (int32x4_t )xmmword_29F00; v15 = 0LL ; v16.n128_u64[0 ] = 0x400000004 LL; v16.n128_u64[1 ] = 0x400000004 LL; v17.n128_u64[0 ] = 0x800000008 LL; v17.n128_u64[1 ] = 0x800000008 LL; *(_QWORD *)v13 = 0LL ; do { v18 = (char *)&v13[v15]; v15 += 8LL ; v19 = vaddq_s32(v14, v16); *(int32x4_t *)(v18 + 8 ) = v14; v14 = vaddq_s32(v14, v17); *(int32x4_t *)(v18 + 24 ) = v19; } while ( v15 != 256 ); v20 = 0LL ; v21 = 0 ; v22 = 0 ; v23 = (char *)(v13 + 2 ); do { v24 = *(_DWORD *)&v23[v20]; v21 += a12345678[v22] + v24; v25 = (char *)&v13[v21]; if ( v22 + 1 < 8 ) ++v22; else v22 = 0 ; *(_DWORD *)&v23[v20] = *((_DWORD *)v25 + 2 ); v20 += 4LL ; *((_DWORD *)v25 + 2 ) = v24; } while ( v20 != 1024 ); v26 = 0LL ; LOBYTE(v27) = 0 ; LOBYTE(v28) = 0 ; do { v27 = (unsigned __int8)(v27 + 1 ); v29 = (char *)(v13 + 2 ); v30 = v13[v27 + 2 ]; v28 = (unsigned __int8)(v30 + v28); v31 = v13[v28 + 2 ]; *(_DWORD *)&v29[4 * v27] = v31; *(_DWORD *)&v29[4 * v28] = v30; *((_BYTE *)dest + v26++) ^= LOBYTE(v13[(unsigned __int8)(v31 + v30) + 2 ]); } while ( v26 != 32 ); *v13 = v27; v13[1 ] = v28; v32 = 0LL ; while ( *((unsigned __int8 *)dest + v32) == enc[v32] ) { if ( (unsigned __int64)++v32 > 0x1F ) { v12 = 1 ; goto LABEL_23; } } v12 = 0 ; if ( (v8 & 1 ) != 0 ) goto LABEL_24; return v12; }
窝好累