]> git.somenet.org - pub/jan/ctf-seminar.git/blob - writeups/chrztoph/hxp36C3CTF.md
Improve writeups
[pub/jan/ctf-seminar.git] / writeups / chrztoph / hxp36C3CTF.md
1 # hxp 36C3 CTF
2
3 ## CTF Retrospective
4
5 The challenges are really good made and I had a lot of fun at trying them even though I found them very hard. I would love if the CTF would last longer so you have more time to try the different challenges.
6
7 ## Challenge 1337 skills
8
9 Time: about 4h (with all the Android stuff setup maybe more) without writeup
10
11 ### Task description
12
13 ```
14 It’s too hard to gain all 1337 h4x0r skills required by nowadays CTFs ._.!
15 I am glad a friendly hacker told me about an App he got during a (growth) hacking course.
16 Sadly, he didn’t wrote down any activations codes.
17
18 Ready for your hacking exam?
19
20 Connection:
21 nc 88.198.154.132 7002
22 ```
23
24 ### Overview
25
26 So we are given a server we can connect to and on clicking on `App` in the task description we are redirected to the website `https://play.google.com/store/apps/details?id=com.progressio.wildskills`. Our goal is to find activation codes.
27
28 ### Exploitation
29
30 After connecting to server we are asked to enter an activation code. Entering a random number results in `:(` and when entering a letter the server just closes the connection. So I tried to analyze the Android app. I downloaded the app by using https://apkcombo.com/en-at/apk-downloader/.
31
32 I then started the app on my AVD and was asked for an activation code. After entering some text and clicking activate the message "Ungültiger Aktivierungscode" was shown. I decompiled the app with `jadx` and searched for this string in the source code.
33
34 I found the text inside the function `activateApp` where the following code
35 can be found:
36
37 ```
38 Calendar instance = Calendar.getInstance();
39 if (i == ((int) (Math.pow((double) (instance.get(3) * instance.get(1)), 2.0d) % 999983.0d))) {
40     ...
41 }
42 ```
43
44 I created a new Java application and ran the code
45
46 ```
47 Calendar instance = Calendar.getInstance();
48 int x = ((int) (Math.pow((double) (instance.get(3) * instance.get(1)), 2.0d) % 999983.0d));
49 System.err.println(x);
50 ```
51
52 to get the activation code `76429`. The code might be different depending on the date.
53 After entering the correct activation code the server responds with the following:
54
55 ```
56 Activation code:
57 76429
58 activated!
59 Sales activation code:
60 ```
61
62 So we need to get a sales activation code. Entering the code also works in the app. Clicking on the the two arrows in the upper right corner opens a menu with an option `Sales`. Clicking on it opens another windows where you are asked to entern an sales activation code. Enter a wrong value shows again the same message "Ungültiger Aktivierungscode".
63
64 There are multiple places where this message is shown but I went with the function `courseActivation` because the title of the screen says "AKTIVIERUNGSCODE FÜR KURS EINGEBEN". From the three strings that are compared only the string `sgk258` worked.
65
66 The server responds with the following:
67
68 ```
69 Activation code:
70 76429
71 activated!
72 Sales activation code:
73 sgk258
74 activated!
75 Leadership activation code:
76 ```
77
78 I followed the same procedure for the leadership code as for the sales activation code and found out that the code `wmt275` works. The server now responds with:
79
80 ```
81 Activation code:
82 76429
83 activated!
84 Sales activation code:
85 sgk258
86 activated!
87 Leadership activation code:
88 wmt275
89 activated
90 Service Roadmap (SRM) activation code:
91 ```
92
93 So one more time the same procedure as before but this time the code is `udh736`. The server then asks for your name where you can enter anything as seen below
94
95 ```
96 Activation code:
97 76429
98 activated!
99 Sales activation code:
100 sgk258
101 activated!
102 Leadership activation code:
103 wmt275
104 activated
105 Service Roadmap (SRM) activation code:
106 udh736
107 activated!
108 Congratulations please give me your name:
109 Chrztoph
110    ______________________________
111  / \                             \.
112 |   |                            |.
113  \_ |                            |.
114     | Certificate of Attendance  |.
115     |                            |.
116     |  This is to certify that   |.
117     |                            |.
118     |          Chrztoph          |.
119     |                            |.
120     |        has attended        |.
121     |                            |.
122     | **The baby rev challenge** |.
123     |                            |.
124     |                            |.
125     |                       hxp  |.
126     |                            |.
127     | -------------------------- |.
128     |                            |.
129     |hxp{thx_f0r_4773nd1n6_70d4y}|.
130     |                            |.
131     |   _________________________|___
132     |  /                            /.
133     \_/____________________________/.
134 ```
135
136 The flag is included in the "certificate".
137
138 ### Conclusion
139
140 I really liked the challenge. It is solveable in a feasible amount of time and is a good intro into Android challenges.
141
142
143
144
145 ## Challenge WriteupBin
146
147 Time: about 8h without writeup
148
149 ### Task description
150
151 ```
152 Finally (again), a minimalistic, open-source social writeup hosting solution.
153
154 Connection:
155 http://78.46.216.67:8001/
156 ```
157
158 ### Overview
159
160 A website is given where we should get the flag from and also the source code of the service is given. It is a simple service where you can post writeups, like writeups and show them to the admin.
161
162 ### Exploitation
163
164 When entering text in the textfied for the writeup an error message is shown, that the text is too short. The writeup must contain at least 140 characters or more. As a first try I tried to enter a simple `<script>alert(1)</script>` but this doesn't work because the website immediately shows `This value seems to be invalid.` So I checked why this is happening. A JS library called Parsley (https://parsleyjs.org/) is used for form validation and I found that the `textarea` contains the following `data-parsley-pattern="[^<>]+"` which means that no `<` and `>` are allowed. So I used Postman for further exploitation of the site.
165
166 One thing I noticed when trying to execute a call via Postman is that there is a CSRF token needed named `c`.
167
168 By issuing a request to `/add.php` with the content `</code><h1>hello</h1><code>` and the required `c` it is possible to add arbitrary HTML to the website. There is no server-side validation done so by closing the first `<code>` tag and then entering any HTML we are able to add anything to the website. Unfortunately there is a CSP in place:
169
170 ```
171 default-src 'none';
172 script-src 'nonce-NzM0NTE5NTc5Y2NhZDQxMg==' https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js https://cdnjs.cloudflare.com/ajax/libs/parsley.js/2.8.2/parsley.min.js;
173 base-uri 'self';
174 form-action 'self';
175 frame-ancestors 'none';
176 require-sri-for script style;
177 ```
178
179 So there can't be done much because the CSP blocks all kind of stuff which is interesting for getting the flag.
180
181 After setting up the server locally I found that there is an `admin.py` script. This script starts a browser and clicks the element which matches the following selector: `input[@id="like"]` which means it will click an element like this one `<input id="like" />`.
182
183 It was clear that the input element is clicked for a reason but I couldn't find any further ways in exploiting this.
184
185 ### Conclusion
186
187 The challenge overall was fun even though I haven't solved it. It is also nice to see how they realized the challenge and that it is possible to set it up locally for testing.