]> git.somenet.org - pub/jan/ctf-seminar.git/blob - writeups/Ch4s3r/36c3.md
Update writeups/Ch4s3r/36c3.md, writeups/Ch4s3r/36c3/game.png, writeups/Ch4s3r/36c3...
[pub/jan/ctf-seminar.git] / writeups / Ch4s3r / 36c3.md
1 # hxp 36c3 CTF 2019
2
3 ## Challenge: 1337_skills
4
5 Goal: Download the [WILD Skills](https://play.google.com/store/apps/details?id=com.progressio.wildskills&hl=en) android app and find the unlock codes for the courses.
6
7 In `com.progressio.wildskills.Mainactivity` we could find the activation algorithm to be able to open the app:
8 ```java
9  public void activateApp(View view) {
10         int i;
11         try {
12             i = Integer.parseInt(this.editTextActivation.getText().toString());
13         } catch (NumberFormatException unused) {
14             i = -1;
15         }
16         Calendar instance = Calendar.getInstance();
17         if (i == ((int) (Math.pow((double) (instance.get(3) * instance.get(1)), 2.0d) % 999983.0d))) {
18             findViewById(R.id.scrollViewActivation).setVisibility(4);
19             ((InputMethodManager) getSystemService("input_method")).hideSoftInputFromWindow(this.editTextActivation.getWindowToken(), 0);
20             Editor edit = this.prefsmain.edit();
21             edit.putBoolean("Activated", true);
22             long time = new Date().getTime();
23             edit.putLong("Installed", time);
24             edit.putLong("ActivationDate", time);
25             edit.commit();
26             return;
27         }
28         Toast.makeText(this, "Ungültiger Aktivierungscode", 1).show();
29         this.editTextActivation.requestFocus();
30         ((InputMethodManager) getSystemService("input_method")).showSoftInput(this.editTextActivation, 1);
31     }
32 ```
33
34 Created a small java app to generate the activation code for today:
35 ```java
36 import java.util.Calendar;
37
38 class Scratch {
39     public static void main(String[] args) {
40         Calendar instance = Calendar.getInstance();
41         System.out.print((int) (Math.pow((double) (instance.get(3) * instance.get(1)), 2.0d) % 999983.0d));
42     }
43 }
44 ```
45 Result: 667518
46
47 Then we needed to activate all courses and we found the codes in this code snippet:
48 ```java
49 public void courseActivation(View view) {
50         String obj = ((EditText) findViewById(R.id.editTextCourseActivation)).getText().toString();
51         int i = activateCourse;
52         if (i != 3) {
53             switch (i) {
54                 case 0:
55                     if (obj.equals("sgk258")) {
56                         course = activateCourse;
57                         activateCourse = -1;
58                         setCourse();
59                         ((InputMethodManager) getSystemService("input_method")).hideSoftInputFromWindow(this.editTextActivation.getWindowToken(), 0);
60                         Editor edit = this.prefsmain.edit();
61                         StringBuilder sb = new StringBuilder();
62                         sb.append("Activated");
63                         sb.append(course);
64                         edit.putBoolean(sb.toString(), true);
65                         edit.apply();
66                         return;
67                     }
68                     Toast.makeText(this, "Ungültiger Aktivierungscode", 1).show();
69                     return;
70                 case 1:
71                     if (obj.equals("wmt275")) {
72                         course = activateCourse;
73                         activateCourse = -1;
74                         setCourse();
75                         ((InputMethodManager) getSystemService("input_method")).hideSoftInputFromWindow(this.editTextActivation.getWindowToken(), 0);
76                         Editor edit2 = this.prefsmain.edit();
77                         StringBuilder sb2 = new StringBuilder();
78                         sb2.append("Activated");
79                         sb2.append(course);
80                         edit2.putBoolean(sb2.toString(), true);
81                         edit2.apply();
82                         return;
83                     }
84                     Toast.makeText(this, "Ungültiger Aktivierungscode", 1).show();
85                     return;
86                 default:
87                     return;
88             }
89         } else if (obj.equals("udh736")) {
90             course = activateCourse;
91             activateCourse = -1;
92             setCourse();
93             ((InputMethodManager) getSystemService("input_method")).hideSoftInputFromWindow(this.editTextActivation.getWindowToken(), 0);
94             Editor edit3 = this.prefsmain.edit();
95             StringBuilder sb3 = new StringBuilder();
96             sb3.append("Activated");
97             sb3.append(course);
98             edit3.putBoolean(sb3.toString(), true);
99             edit3.apply();
100         } else {
101             Toast.makeText(this, "Ungültiger Aktivierungscode", 1).show();
102         }
103     }
104 ```
105 Sales -> sgk258
106
107 Leadership -> wmt275
108
109 Service Roadmap (SRM) -> udh736
110
111
112 Connecting to the nc server and entering all the codes:
113 ```
114 Activation code: 
115 667518
116 activated!
117 Sales activation code: 
118 sgk258
119 activated!
120 Leadership activation code: 
121 wmt275
122 activated
123 Service Roadmap (SRM) activation code: 
124 udh736
125 activated!
126 Congratulations please give me your name: 
127 Ch4s3r
128    ______________________________
129  / \                             \.
130 |   |                            |.
131  \_ |                            |.
132     | Certificate of Attendance  |.
133     |                            |.
134     |  This is to certify that   |.
135     |                            |.
136     |           Ch4s3r           |.
137     |                            |.
138     |        has attended        |.
139     |                            |.
140     | **The baby rev challenge** |.
141     |                            |.
142     |                            |.
143     |                       hxp  |.
144     |                            |.
145     | -------------------------- |.
146     |                            |.
147     |hxp{thx_f0r_4773nd1n6_70d4y}|.
148     |                            |.
149     |   _________________________|___
150     |  /                            /.
151     \_/____________________________/.
152 ```
153 ---
154 ## Challenge: tetres2019-rev (unsolved)
155
156 Goal of this challenge was to solve a custom tetris game.
157 The binary was a windows executable file.
158 The game looked like this:
159 ![Game overview](36c3/game.png)
160
161 This game was designed to be unplayable, but it was said that they don't know if it was actually impossible to solve it normally, so we should have a look if we can solve it.
162 So at fist I started to play some rounds and I couldn't get a single point by completing a full line.
163 The elements came at random and where consisting of these object: `H, X, P, Line, Block`.
164 Sometime later I noticed that the random elements always came in the same order, so I guess the seed is fixed for the random number generator.
165 But if you press down and make the element go quicker the next random element would be another one, so also the frame changes the next element not only the random number generator.
166 I then started to tinker around with the tool `Cheat Engine` and after some time i found the random number generator.
167 It was located in `ucrtbase.dll` and was called `rand`.
168 Modifying the return value of `ucrtbase::rand` now let us choose the elements we want to have next and this is the table for the elements:
169
170 | H | X | P | Block | Line |
171 |:---:|:---:|:---:|:---:|:---:|
172 | 0 | 1 | 2 | 3 | 5 |
173
174 It seemed to be best to take 2 blocks (4 tiles width) and 2 lines (6 tiles width) to fill the 14 tiles to get a full line.
175 I thought maybe i can play it now by hand and get the flag, but after 54 points not getting the flag i gave up doing it manually.
176
177 Trying to automate the game by sending the inputs to play the elements always in this order failed, because the process wouldn't take the inputs when emulated.
178
179 ![Game overview](36c3/win_strategy.png)
180
181 Using `Cheat Engine` I tried to isolate some interesting functions with a tool named `Ultimap 2`, by recording all calls made and filtering them afterwards.
182 But it didn't find the function for getting points or losing the game.
183 What I found was the main loop of openGL with the rand function in there and where the user input is processed.
184 I spent about 8 hours searching for them by now.
185
186 After many hours spend I also tried to investigate the application with `Ghidra` and `IDA` but some sections of the binary were destroyed/unreadable.
187 There were only displayed 3 function, with calls to `LoadLibrary` and `GetProcAddress`.
188 So i guess it had some library inside the exe that loaded the real game logic.
189 In `Cheat Engine` when anaylsing some of the code if found 30 small functions that looked very weird, they could have been either used for getting the flag or generating some code on the fly which get exectued.
190
191 Another attempt to getting the points/winning/losing function was to make a move, trace its execution flow and compare it with a move that gave me points/won the game/lost the game.
192 But they all took the same path in the application so I couldn't isolate a new funtion which could have gotten executed.
193
194
195 At this point the CTF was nearing to an end and I couldn't finish the challenge. I spent most of the 2 days on this challene (about 18 hours).
196
197 Official solution: https://martinradev.github.io/jekyll/update/2019/12/29/tetris-re.html
198
199 After reading the solution I found out that I searched in the wrong address space with `Ultimap`, because the points incrementation, checking win condition and flag generation happens in the shader and this function is located in the `nvoglv32.dll` address space and not in `tetris.exe` directly.