]> git.somenet.org - pub/jan/ctf-seminar.git/blob - writeups/hah/asis2019/yet_funny.py
Add Bit Game exploit
[pub/jan/ctf-seminar.git] / writeups / hah / asis2019 / yet_funny.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 import subprocess
5 import random
6 import sys, os, string
7 from hashlib import *
8 from flag import flag
9  
10  
11 def genrandstr(N):
12     return ''.join(random.choice(string.ascii_uppercase + string.digits + string.ascii_lowercase) for _ in range(N))
13  
14  
15 def isprintable(mystr):
16     return all(c in string.printable for c in mystr)
17  
18
19 def PoW():
20     r = random.randint(0, 5)
21     HASH = [md5, sha1, sha224, sha256, sha384, sha512]
22     X = genrandstr(14)
23     l = random.randint(10, 40)
24     pr("Please submit a printable string X, such that", HASH[r].__name__.split('_')[1] + "(X)[-6:] =",
25        HASH[r](X).hexdigest()[-6:], 'and len(X) =', l)
26     Y = sc()
27     return isprintable(Y) and HASH[r](Y).hexdigest()[-6:] == HASH[r](X).hexdigest()[-6:] and len(Y) == l
28  
29  
30 def aux(inp):
31     pm = set(inp)
32     try:
33         vux = inp.replace(list(pm)[0] * 2, chr(0)).replace(list(pm)[1] * 2, chr(1))
34         if set(vux) == set([chr(0), chr(1)]) and len(inp) <1<<10:
35             return True and len(inp) > 4
36     except:
37         pass
38     return False
39  
40  
41 def GCD(x, y):
42     while (y):
43         x, y = y, x % y
44     return x
45
46 def rangen():
47         return [random.randint(32, 64), random.randint(-64, -32)][random.randint(0, 1)]
48  
49 def rancof():
50     rs = (random.randint(0, 128) + 128, random.randint(0, 128) + 128)
51     while True:
52         if GCD(rs[0], rs[1]) == 1:
53             break
54         rs = (random.randint(0, 128) + 128, random.randint(0, 128) + 128)
55     return rs
56  
57 code = r'''
58         #include <stdio.h>
59         int main(){
60            int c = 0, d = 0;
61            c = first_number, d = second_number;
62            int a = first_random, b = second_random;
63            if((a*c + b*d) == 1)
64                return 0;
65            return -1;
66         }
67         '''
68  
69 def var_handler(first_var, second_var, first_rand, second_rand, first_number, second_number):
70     global code
71     tmp_code = code
72     tmp_code = str(tmp_code).replace("first_random", str(first_rand))
73     tmp_code = str(tmp_code).replace("second_random", str(second_rand))
74     tmp_code = str(tmp_code).replace("first_number", str(first_var) + "c+" + str(first_number))
75     tmp_code = str(tmp_code).replace("second_number", str(second_var) + "d+" + str(second_number))
76     random_name = genrandstr(16)
77     full_random_name = '/tmp/' + random_name + '.cpp'
78     c_file = open(full_random_name, 'w')
79     c_file.write(tmp_code)
80     c_file.flush()
81     c_file.close()
82     command1 = "g++ " + full_random_name + " -o " + "/tmp/" + random_name
83     command2 = "/tmp/" + random_name
84     os.system(command1)
85     process = subprocess.Popen(command2, shell=True, stdout=subprocess.PIPE)
86     process.wait()
87     os.remove("/tmp/" + random_name)
88     os.remove('/tmp/' + random_name + '.cpp')
89     if str(process.returncode) == '0':
90         return True
91     else:
92         return False
93  
94 border = "█"
95
96 def main():
97     if PoW():
98         pr(border * 82)
99         pr(border, "Elliot has been trying to defeat the Red Army since May 9th hacking incident. ", border)
100         pr(border, "He has ultimately found a way to their hidden bank using a Mr.Robot!          ", border)
101         pr(border, "You have to play your role in the story and help Elliot to arrange his attack!", border)
102         pr(border * 82)
103         first_number, second_number = [rangen() for _ in range(2)]
104         first_rand, second_rand = rancof()
105         while True:
106             pr("| Options: \n|\t[G]et the C source code \n|\t[T]ry to solve \n|\t[Q]uit!")
107             ans = sc().lower()
108             if ans == 'g':
109                 global code
110                 tmp_code = code
111                 tmp_code = str(tmp_code).replace("second_number", str(second_number))
112                 tmp_code = str(tmp_code).replace("first_number", str(first_number))
113                 tmp_code = str(tmp_code).replace("first_random", str(first_rand))
114                 tmp_code = str(tmp_code).replace("second_random", str(second_rand))
115                 pr(tmp_code)
116             elif ans == 't':
117                 pr("Please enter first variable:")
118                 first_var = sc()
119                 pr("Please enter second variable:")
120                 second_var = sc()
121                 if isprintable(first_var) and isprintable(second_var) and aux(first_var) and aux(second_var):
122                     if var_handler(first_var, second_var, first_rand, second_rand, first_number, second_number):
123                         die("You win the battle, here you are :", flag)
124                     else:
125                         die("Bye Loser...")
126                 else:
127                     die("000ps... Inappropriate variable")
128             elif ans == 'q':
129                 die(border, "Quiting ...")
130             else:
131                 die(border, "Bye ...")
132     else:
133         die('PoW challenge failed :P')
134  
135  
136 def die(*args):
137     pr(*args)
138     quit()
139
140 def pr(*args):
141     s = " ".join(map(str, args))
142     sys.stdout.write(s + "\n")
143     sys.stdout.flush()
144
145 def sc():
146     return sys.stdin.readline().strip()
147
148 if __name__ == '__main__':
149     main()