]> git.somenet.org - pub/jan/ctf-seminar.git/blob - writeups/chrztoph/hxp36C3CTF.md
Add hxp 36C3 CTF writeup
[pub/jan/ctf-seminar.git] / writeups / chrztoph / hxp36C3CTF.md
1 # hxp 36C3 CTF
2
3 ## Challenge 1337 skills
4
5 Time: about 4h (with all the Android stuff setup maybe more) without writeup
6
7 ### Task description
8
9 ```
10 It’s too hard to gain all 1337 h4x0r skills required by nowadays CTFs ._.!
11 I am glad a friendly hacker told me about an App he got during a (growth) hacking course.
12 Sadly, he didn’t wrote down any activations codes.
13
14 Ready for your hacking exam?
15
16 Connection:
17 nc 88.198.154.132 7002
18 ```
19
20 ### Overview
21
22 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.
23
24 ### Exploitation
25
26 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/.
27
28 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.
29
30 I found the text inside the function `activateApp` where the following code
31 can be found:
32
33 ```
34 Calendar instance = Calendar.getInstance();
35 if (i == ((int) (Math.pow((double) (instance.get(3) * instance.get(1)), 2.0d) % 999983.0d))) {
36     ...
37 }
38 ```
39
40 I created a new Java application and ran the code
41
42 ```
43 Calendar instance = Calendar.getInstance();
44 int x = ((int) (Math.pow((double) (instance.get(3) * instance.get(1)), 2.0d) % 999983.0d));
45 System.err.println(x);
46 ```
47
48 to get the activation code `76429`. The code might be different depending on the date.
49 After entering the correct activation code the server responds with the following:
50
51 ```
52 Activation code:
53 76429
54 activated!
55 Sales activation code:
56 ```
57
58 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".
59
60 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.
61
62 The server responds with the following:
63
64 ```
65 Activation code:
66 76429
67 activated!
68 Sales activation code:
69 sgk258
70 activated!
71 Leadership activation code:
72 ```
73
74 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:
75
76 ```
77 Activation code:
78 76429
79 activated!
80 Sales activation code:
81 sgk258
82 activated!
83 Leadership activation code:
84 wmt275
85 activated
86 Service Roadmap (SRM) activation code:
87 ```
88
89 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
90
91 ```
92 Activation code:
93 76429
94 activated!
95 Sales activation code:
96 sgk258
97 activated!
98 Leadership activation code:
99 wmt275
100 activated
101 Service Roadmap (SRM) activation code:
102 udh736
103 activated!
104 Congratulations please give me your name:
105 Chrztoph
106    ______________________________
107  / \                             \.
108 |   |                            |.
109  \_ |                            |.
110     | Certificate of Attendance  |.
111     |                            |.
112     |  This is to certify that   |.
113     |                            |.
114     |          Chrztoph          |.
115     |                            |.
116     |        has attended        |.
117     |                            |.
118     | **The baby rev challenge** |.
119     |                            |.
120     |                            |.
121     |                       hxp  |.
122     |                            |.
123     | -------------------------- |.
124     |                            |.
125     |hxp{thx_f0r_4773nd1n6_70d4y}|.
126     |                            |.
127     |   _________________________|___
128     |  /                            /.
129     \_/____________________________/.
130 ```
131
132 The flag is included in the "certificate".
133
134
135
136
137 ## Challenge WriteupBin
138
139 Time: about 8h without writeup
140
141 ### Task description
142
143 ```
144 Finally (again), a minimalistic, open-source social writeup hosting solution.
145
146 Connection:
147 http://78.46.216.67:8001/
148 ```
149
150 ### Overview
151
152 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.
153
154 ### Exploitation
155
156 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.
157
158 One thing I noticed when trying to execute a call via Postman is that there is a CSRF token needed named `c`.
159
160 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:
161
162 ```
163 default-src 'none';
164 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;
165 base-uri 'self';
166 form-action 'self';
167 frame-ancestors 'none';
168 require-sri-for script style;
169 ```
170
171 So there can't be done much because the CSP blocks all kind of stuff which is interesting for getting the flag.
172
173 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" />`.
174
175 It was clear that the input element is clicked for a reason but I couldn't find any further ways in exploiting this.