mcfx's blog - 2020年2月 /2020/02/ 个人博客,(曾经)基本只放题解,现在随便写点啥了吧( HackTM CTF Quals 2020 Writeup /archives/278/ 2020-02-06T03:32:00+08:00 由于寒假比较闲,所以找点比赛打。由于需要上交 wp,所以是英文的。 # Crypto ## RSA is easy #1 Since $$N$$ is known, we can compute the encrypted value of each printable character. Then match them with the given encrypted flag, we can decrypt it. ```python e=65537 n=... s=[...(encrypted flag)] from gmpy2 import * f={} for j in range(32,127): f[j**e%n]=j r='' for i in s: r+=chr(f[i]) print r ``` ## RSA is easy #2 We doesn't know $$N$$, but we know that $$c=n^e\ mod\ N$$. So $$N$$ is a factor of $$n^e-c$$. Then for two $$c$$, we can check all $$n$$, and calculate their $$gcd$$. Then just follow #1. ```python from gmpy2 import * s=open('c').read() s1='Encrypted flag:' s=s[s.find(s1)+len(s1):] s=eval(s.strip()) a=s[0] b=s[1] for i in range(97,97+26): for j in range(97,97+26): t=gcd(i**65537-a,j**65537-b) if t>100: print '|',t print i ``` ## Prison Break Maintain the difference of every two adjacent numbers. ```cpp #include typedef unsigned int uint; typedef long long ll; typedef unsigned long long ull; typedef double lf; typedef long double llf; typedef std::pair pii; #define xx first #define yy second template inline T max(T a,T b){return a>b?a:b;} template inline T min(T a,T b){return a0?a:-a;} template inline bool repr(T &a,T b){return ab?a=b,1:0;} template inline T gcd(T a,T b){T t;if(a> >>.>*./N>.NN/N>N . /N >N>/>/>N/ WN V*\\NVW\WVN* NVNN WN\ \ . *.NN . N NWW\\.W\ W\\ NW N\W ``` ```python from Crypto.Cipher import AES c='059fd04bca4152a5938262220f822ed6997f9b4d9334db02ea1223c231d4c73bfbac61e7f4bf1c48001dca2fe3a75c975b0284486398c019259f4fee7dda8fec'.decode('hex') iv = '42042042042042042042042042042042'.decode('hex') def chk(key): aes = AES.new(key,AES.MODE_CBC, iv) r=aes.decrypt(c) for i in r: if ord(i)126: return False print(r) return True def chkn(x): r='' for i in range(32): r+=chr(x&255) x>>=8 assert x==0 r=r[::-1] return chk(r) a,b=open('key.txt').readlines()[:2] a=a.strip() b=b.strip() va={'>':2, '/':1, 'N':3, ' ':0, '.':0} vb={'N':3, 'W':4, ' ':0, '\\':1, '.':0, 'V':2} unk=[] tot=0 for i in range(59): p=58-i po=20**i if a[p]=='*': assert b[p]=='*' unk.append((po,i)) else: tot+=(va[a[p]]*5+vb[b[p]])*po def dfs(x,cur): if x==len(unk): return chkn(cur) for i in range(20): dfs(x+1,cur+unk[x][0]*i) dfs(0,tot) ``` # Forensics ## RR It seems to be raid5. After some observation, I found the way to decrypt it. (decrypt script, 2.img is the $$xor$$ of 1.img and 3.img) ```cpp #include typedef unsigned int uint; typedef long long ll; typedef unsigned long long ull; typedef double lf; typedef long double llf; typedef std::pair pii; #define xx first #define yy second template inline T max(T a,T b){return a>b?a:b;} template inline T min(T a,T b){return a0?a:-a;} template inline bool repr(T &a,T b){return ab?a=b,1:0;} template inline T gcd(T a,T b){T t;if(a>3 return s[:xt]+bytes([s[xt]^(13 return s[:xt]+bytes([s[xt]^(1