1 00:00:19,003 --> 00:00:20,825 We are about to start the next talk right 2 00:00:20,825 --> 00:00:23,348 here. So, I am very happy to introduce 3 00:00:23,348 --> 00:00:25,538 Hanemile. Who is going to talk a little 4 00:00:25,538 --> 00:00:28,281 bit about the struggles you are facing 5 00:00:28,281 --> 00:00:30,650 when trying to find the next capture the 6 00:00:30,650 --> 00:00:32,762 flag (CTF) adventure and how he is 7 00:00:32,762 --> 00:00:34,357 proposing to solve the problem. 8 00:00:36,045 --> 00:00:37,885 Please join me in welcoming Emile. 9 00:00:43,485 --> 00:00:45,934 Hi, I am going to talk about CTF in a box. 10 00:00:45,934 --> 00:00:47,958 It is the story of what problems we 11 00:00:47,958 --> 00:00:50,536 found when playing CTFs. How we plan 12 00:00:50,536 --> 00:00:52,216 to solve the problems; we built a 13 00:00:52,216 --> 00:00:55,482 prototype, tested it and the problems 14 00:00:55,900 --> 00:00:59,599 that came after that. So, first who am I 15 00:00:59,599 --> 00:01:04,508 I am Emile, @hanmile at post platforms. 16 00:01:05,143 --> 00:01:06,914 Studying computer science at Düsseldorf. 17 00:01:06,914 --> 00:01:09,489 Playing CTF with @flexerilla or sometimes 18 00:01:09,489 --> 00:01:11,293 as a single player. 19 00:01:12,497 --> 00:01:14,672 Lets start with the current solutions. 20 00:01:15,029 --> 00:01:18,630 Playing CTF we currently have, like, 3 21 00:01:18,880 --> 00:01:22,706 main platforms. The most used framework 22 00:01:22,736 --> 00:01:25,532 used currently is CTFd. 23 00:01:25,884 --> 00:01:30,248 CTFd is the first thing you'll find if you 24 00:01:30,248 --> 00:01:32,805 google "hey I want to host a CTF, what 25 00:01:32,805 --> 00:01:33,603 do I do?" 26 00:01:34,490 --> 00:01:36,445 Second thing is hack the box 27 00:01:36,712 --> 00:01:39,920 that is another case study, well case 28 00:01:39,920 --> 00:01:45,285 study. More so a framework to host CTFs 29 00:01:45,285 --> 00:01:47,584 but you can't use it, because it is 30 00:01:47,584 --> 00:01:49,754 actually close sourced. Meaning that 31 00:01:49,754 --> 00:01:51,835 you can only play with that. The last 32 00:01:52,820 --> 00:01:55,310 solution is custom frameworks. So, 33 00:01:55,511 --> 00:01:58,018 these are frameworks used by teams. 34 00:01:58,018 --> 00:01:59,488 They build them themselves, like 35 00:02:00,097 --> 00:02:01,778 at this years CTF. 36 00:02:01,978 --> 00:02:04,602 So, CTFd looks like this. People may have 37 00:02:04,804 --> 00:02:08,245 played CTF may have seen it since most 38 00:02:08,430 --> 00:02:11,171 CTFs are hosted on CTFd. Overall 39 00:02:11,372 --> 00:02:15,263 it is pretty basic, looks bit bootstrappy. 40 00:02:15,263 --> 00:02:17,302 I´ll come back to what the problems are 41 00:02:17,302 --> 00:02:21,982 later. Hack the box, the people who have 42 00:02:21,982 --> 00:02:23,085 not seen it, it looks like this. This is 43 00:02:23,085 --> 00:02:25,983 the machine view. Because hack the 44 00:02:25,983 --> 00:02:28,865 box differentiate between machines 45 00:02:28,865 --> 00:02:31,538 and challenges. Challenges are simply 46 00:02:31,538 --> 00:02:33,709 files from where you need to find the 47 00:02:33,709 --> 00:02:36,298 flag. Machines are a bit more, where 48 00:02:36,298 --> 00:02:39,027 you an actual machine from where 49 00:02:39,027 --> 00:02:40,635 you need to find the flag in the actual 50 00:02:40,635 --> 00:02:42,570 services running on the machine. 51 00:02:42,570 --> 00:02:43,523 So, it is a bit more. 52 00:02:43,523 --> 00:02:45,561 And custom ones. This is an image of 53 00:02:45,561 --> 00:02:51,979 a current CTF organised by HXV. 54 00:02:51,979 --> 00:02:55,804 It is pretty much CTFd but, but built by 55 00:02:55,804 --> 00:02:57,572 their own. 56 00:02:57,572 --> 00:03:00,234 So, what are the problems with this? 57 00:03:00,234 --> 00:03:02,089 Well, lets start with CTFd, where there 58 00:03:02,089 --> 00:03:03,611 aren't actual problems, in my opinion. 59 00:03:03,611 --> 00:03:06,149 It is mostly a static hoster, for files 60 00:03:06,149 --> 00:03:09,709 you want people to use for the CTF and 61 00:03:09,709 --> 00:03:12,667 some custom infrastructure for score 62 00:03:12,667 --> 00:03:17,564 board, registration and stuff like that. 63 00:03:17,564 --> 00:03:26,771 Hack the box is kind of close sourced, 64 00:03:26,771 --> 00:03:28,191 why I say "kind of" because you can 65 00:03:28,191 --> 00:03:29,413 actually use it, you can see how it is 66 00:03:29,413 --> 00:03:32,688 built up, you could build it your self 67 00:03:32,688 --> 00:03:40,391 and the problem we had when playing 68 00:03:40,391 --> 00:03:41,879 with hack the box was that we had some 69 00:03:41,879 --> 00:03:43,098 reverse shells at the root of the 70 00:03:43,098 --> 00:03:45,004 challenges. As well as other problems like 71 00:03:45,004 --> 00:03:47,059 multiple people writing in to some 72 00:03:47,059 --> 00:03:49,182 challenges and that some files where 73 00:03:49,182 --> 00:03:51,622 there, that should not have been. Which 74 00:03:51,622 --> 00:03:55,464 was really annoying sometimes. Like we 75 00:03:55,464 --> 00:03:57,537 started a challenges and saw that there 76 00:03:57,537 --> 00:03:59,810 is a reverse shell for getting root in 77 00:03:59,810 --> 00:04:03,469 root, you don't have to do anything. 78 00:04:03,469 --> 00:04:07,649 There are shared challenge instances 79 00:04:07,649 --> 00:04:10,239 the problem we saw that was you 80 00:04:10,239 --> 00:04:13,379 have multiple hundre people playing the 81 00:04:13,379 --> 00:04:16,738 same instance, where we could see what 82 00:04:16,738 --> 00:04:21,084 other people where uploading to the 83 00:04:21,084 --> 00:04:23,124 instance. Which kind of helped us and 84 00:04:23,124 --> 00:04:25,212 found out that it could be kind of 85 00:04:25,212 --> 00:04:28,219 optimised. The third problem, well 86 00:04:28,219 --> 00:04:31,813 problem, but it is custom frameworks. 87 00:04:31,813 --> 00:04:34,937 You might find errors in custom frameworks 88 00:04:34,937 --> 00:04:37,945 allowing to get flags that aren't used 89 00:04:37,945 --> 00:04:44,547 without solving the challenge. So, it is 90 00:04:44,547 --> 00:04:46,669 now a ping pong between finding a problem 91 00:04:46,669 --> 00:04:51,649 and finding a solution. The simplest 92 00:04:51,649 --> 00:04:54,622 solution we tried to implement at our CTF 93 00:04:54,622 --> 00:04:56,880 at a local hackrrspace was to generate 94 00:04:56,880 --> 00:04:59,219 a single challenge instance for every 95 00:04:59,219 --> 00:05:01,240 player/ team. This means that every 96 00:05:01,240 --> 00:05:04,015 challenge we built was simply a docker 97 00:05:04,015 --> 00:05:06,239 container somewhere and for everyone 98 00:05:06,239 --> 00:05:08,361 who wanted to play it started a new docker 99 00:05:08,361 --> 00:05:12,312 contianer. We first thought that this 100 00:05:12,312 --> 00:05:14,637 would bring a lot of overhead, but it 101 00:05:14,637 --> 00:05:16,174 didn't. We started multiple hundred 102 00:05:16,174 --> 00:05:19,810 containers and it worked out fine. The 103 00:05:19,810 --> 00:05:21,464 problem with this is that if you put 104 00:05:21,464 --> 00:05:23,519 everything in a doker container docker 105 00:05:23,519 --> 00:05:26,999 escapes and sandbox escapes get really 106 00:05:26,999 --> 00:05:30,287 useful. It would be fatal if someone could 107 00:05:30,287 --> 00:05:33,529 breakout of the container. We got 108 00:05:33,529 --> 00:05:35,551 solutions for the possible problems. 109 00:05:35,551 --> 00:05:44,624 You could place everything in a VM or 110 00:05:44,624 --> 00:05:49,171 nsjail in order to isolate the process. 111 00:05:49,171 --> 00:05:53,885 Stopping people from actually breaking 112 00:05:53,885 --> 00:05:56,272 out. Another possible solution would be 113 00:05:56,272 --> 00:05:59,598 to make it possible for people to break 114 00:05:59,598 --> 00:06:01,387 out, which you don't actually want to 115 00:06:01,387 --> 00:06:04,210 make possible. But you don't want people 116 00:06:04,210 --> 00:06:07,521 to have anything in case; custom flags 117 00:06:07,521 --> 00:06:09,641 for custom teams. 118 00:06:09,641 --> 00:06:12,465 We did by implementing our docker 119 00:06:12,465 --> 00:06:15,172 containers as - or we implemented the 120 00:06:15,172 --> 00:06:19,668 challenges or the flags get put into the 121 00:06:19,668 --> 00:06:22,410 docker via environment variables. 122 00:06:22,410 --> 00:06:24,666 So when you are starting your docker 123 00:06:24,666 --> 00:06:27,042 container you just set an environment 124 00:06:27,042 --> 00:06:28,776 variable with you flag. And in the docker 125 00:06:28,776 --> 00:06:30,146 container you have a little scrip that is 126 00:06:30,146 --> 00:06:32,051 pushing your flag to the place you want 127 00:06:32,051 --> 00:06:34,257 it to be. Then unsetting the environment 128 00:06:34,257 --> 00:06:36,430 variable and deleting everything else. 129 00:06:36,430 --> 00:06:38,336 Meaning no trace of the flag, where there 130 00:06:38,336 --> 00:06:40,123 should not be. That worked out pretty 131 00:06:40,123 --> 00:06:42,912 well. So, that is the CIRCUS prototype 132 00:06:42,912 --> 00:06:44,360 that we used. 133 00:06:44,360 --> 00:06:46,898 A little story for that - we had the 134 00:06:46,898 --> 00:06:48,629 18th anniversary of our hackerspace 135 00:06:48,629 --> 00:06:49,942 this year and we thought that we 136 00:06:49,942 --> 00:06:51,551 need a CTF for that. 137 00:06:51,551 --> 00:06:54,273 In a week before we realised that it is 138 00:06:54,273 --> 00:06:56,872 in a week so we quickly started building 139 00:06:56,872 --> 00:06:58,171 a prototype for it. 140 00:06:58,171 --> 00:06:58,902 And called it CIRCUS. 141 00:06:58,902 --> 00:07:01,021 Because it looks like a circus. 142 00:07:01,021 --> 00:07:03,460 That is a graph showing how the 143 00:07:03,460 --> 00:07:06,124 containers interact with each other. 144 00:07:07,715 --> 00:07:10,242 The goal with this was that we wanted a 145 00:07:10,242 --> 00:07:12,010 place where the teams could register 146 00:07:12,010 --> 00:07:13,181 and get a known companion. 147 00:07:13,181 --> 00:07:15,576 A companion in our system was a place 148 00:07:15,576 --> 00:07:17,429 where people could go and spawn 149 00:07:17,429 --> 00:07:19,357 individual contianers. 150 00:07:19,357 --> 00:07:21,345 Because companion spawns in VPN 151 00:07:21,345 --> 00:07:22,800 containers impacts s all other containers 152 00:07:22,800 --> 00:07:25,258 in to that network. 153 00:07:25,258 --> 00:07:27,151 So, people would go and get the VPN 154 00:07:27,151 --> 00:07:29,535 config and can access the challenges. 155 00:07:29,535 --> 00:07:32,358 It is really similar to how hack the box 156 00:07:32,358 --> 00:07:35,139 works. A problem with this was that 157 00:07:35,139 --> 00:07:39,996 we got one companion container per user 158 00:07:39,996 --> 00:07:41,068 or per team. And we got n challenges 159 00:07:41,068 --> 00:07:44,107 that can be spawn. Meaning that we got 160 00:07:44,107 --> 00:07:46,766 n teams with m challenge computers 161 00:07:46,766 --> 00:07:49,363 we end up with a lot of containers. 162 00:07:49,363 --> 00:07:52,128 What you are seeing here is just a listing 163 00:07:52,128 --> 00:07:53,665 of all the containers that we had spawn 164 00:07:53,665 --> 00:07:55,541 after day 1 of the CTF, with 10 165 00:07:55,541 --> 00:07:58,898 participants or so. But we had like 166 00:07:58,898 --> 00:08:01,171 50 containers at that point. 167 00:08:02,571 --> 00:08:04,381 Which was quite a bit. 168 00:08:04,381 --> 00:08:06,975 At the end of the CTF we had about 169 00:08:06,975 --> 00:08:09,457 120 container up and running. 170 00:08:09,865 --> 00:08:12,017 You might think that a lot of contianers 171 00:08:12,017 --> 00:08:13,689 and people doing stuff in the contaienrs 172 00:08:13,689 --> 00:08:15,650 that must cost a lot of computational 173 00:08:15,650 --> 00:08:17,428 power. But it actually worked out. 174 00:08:17,428 --> 00:08:20,777 We had set up a virtual machine 175 00:08:20,777 --> 00:08:24,871 8 core 16 bit of RAM, and it always 176 00:08:24,871 --> 00:08:25,901 looked like nothing at all was 177 00:08:25,901 --> 00:08:29,899 happening. Until someone set up 178 00:08:29,899 --> 00:08:32,315 a cryptominer and had fun with that. 179 00:08:32,315 --> 00:08:33,729 Since, we went on a machine and saw 180 00:08:33,729 --> 00:08:35,582 "Where is this load coming from?" 181 00:08:35,582 --> 00:08:38,596 We identified that this was a container 182 00:08:38,596 --> 00:08:40,167 that some of the team set up. 183 00:08:40,167 --> 00:08:41,367 Not me. 184 00:08:42,937 --> 00:08:45,734 We had some people try with names, 185 00:08:45,734 --> 00:08:48,274 we screwed up the sanitation a bit 186 00:08:48,274 --> 00:08:49,660 because it was all really quick and that 187 00:08:49,660 --> 00:08:51,750 is a learning for everything - that 188 00:08:51,750 --> 00:08:53,317 it doesn't work. 189 00:08:53,317 --> 00:08:55,886 The XSS you are seeing here didn't also 190 00:08:55,886 --> 00:08:58,519 work for the person trying it 191 00:08:58,519 --> 00:09:00,336 - which was kind of weird. 192 00:09:00,336 --> 00:09:01,870 We did set up a super basic scoreboard. 193 00:09:01,870 --> 00:09:04,091 So, as you can see we tried to build a 194 00:09:04,091 --> 00:09:06,006 CTF framework on our own. 195 00:09:06,006 --> 00:09:08,362 And it kind of worked, it was all 196 00:09:08,362 --> 00:09:11,321 built in a few days and very much 197 00:09:11,321 --> 00:09:14,411 like shitty CTFd. 198 00:09:15,706 --> 00:09:17,163 What we want to do now is to find out 199 00:09:17,730 --> 00:09:20,372 what we want to do and what we don't. 200 00:09:20,658 --> 00:09:23,221 What we want to do is to allow 201 00:09:23,221 --> 00:09:25,171 people to spawn containers 202 00:09:25,171 --> 00:09:26,193 with their challenges. So, we solved 203 00:09:26,193 --> 00:09:27,768 the problem of multiple people 204 00:09:27,768 --> 00:09:30,646 acting on one challenge or instance 205 00:09:30,646 --> 00:09:31,924 of a challenge. 206 00:09:33,214 --> 00:09:36,919 By allowing this we don't allow them to 207 00:09:36,919 --> 00:09:39,021 spawn infinite containers. 208 00:09:39,175 --> 00:09:41,729 Maybe some of you have played Alice CTF 209 00:09:41,729 --> 00:09:42,577 or GM CTF. 210 00:09:43,369 --> 00:09:45,732 That was pretty fun because there 211 00:09:45,902 --> 00:09:47,295 was a challenge exciting 212 00:09:47,462 --> 00:09:49,937 devops challenge and it was exactly like 213 00:09:50,083 --> 00:09:51,672 this. You could spawn containers/ 214 00:09:51,826 --> 00:09:55,109 a complete set up for you to play in. 215 00:09:55,246 --> 00:09:57,376 But you had to do a proof of work, meaning 216 00:09:57,516 --> 00:09:59,923 to calculate something so that you could 217 00:09:59,923 --> 00:10:02,563 not just spawn challenge instances as much 218 00:10:02,563 --> 00:10:04,119 as you liked. 219 00:10:04,119 --> 00:10:06,710 Another thing you might keep in mind 220 00:10:06,710 --> 00:10:09,836 when doing this is to not mount the 221 00:10:10,001 --> 00:10:13,055 docker socket into everything. 222 00:10:13,225 --> 00:10:15,517 As fun as it is to spawn docker 223 00:10:15,517 --> 00:10:17,326 containers from docker containers, it is 224 00:10:18,225 --> 00:10:21,208 a giant security risk. If people have 225 00:10:21,208 --> 00:10:22,971 access to the docker socket they can 226 00:10:22,971 --> 00:10:26,792 docker containers and do shit. 227 00:10:29,248 --> 00:10:30,721 Dos and don'ts. 228 00:10:30,721 --> 00:10:32,014 A lot of players do execute stuff in 229 00:10:32,014 --> 00:10:33,616 containers. Just having a container with 230 00:10:33,749 --> 00:10:38,167 just static files are fun, but we wanted 231 00:10:38,344 --> 00:10:40,575 to have more. Allowing people to 232 00:10:40,705 --> 00:10:44,187 execute stuff in containers can be 233 00:10:44,342 --> 00:10:47,852 problem, but you can limit what people can 234 00:10:48,018 --> 00:10:50,915 do. Meaning that allow people to do stuff 235 00:10:51,093 --> 00:10:53,566 but don't allow them to do too much. 236 00:10:53,753 --> 00:10:56,776 And that worked out in our case. 237 00:10:56,984 --> 00:10:59,325 As said before, we tried it with like 10 238 00:10:59,500 --> 00:11:01,081 people in our local CTF. 239 00:11:01,272 --> 00:11:03,653 Seeing where the problems get when we 240 00:11:03,821 --> 00:11:04,968 put really good CTF teams on it, and to 241 00:11:05,156 --> 00:11:06,605 see if they can break out would be really 242 00:11:06,605 --> 00:11:07,407 interesting to see. 243 00:11:09,281 --> 00:11:11,611 As I said, don't allow, or allow people 244 00:11:11,611 --> 00:11:13,937 to do stuff, but don't allow them to do 245 00:11:13,937 --> 00:11:15,007 too much stuff. 246 00:11:15,441 --> 00:11:18,323 Implement techniques so that it works 247 00:11:18,649 --> 00:11:22,549 out. One thing that I had to keep in mind 248 00:11:22,549 --> 00:11:25,048 was to keep things simple. 249 00:11:25,048 --> 00:11:28,641 During the CTF I realised that, we built 250 00:11:28,641 --> 00:11:30,863 a lot of stuff and it was a little bit 251 00:11:30,863 --> 00:11:33,116 overcomplicated and made things a little 252 00:11:33,116 --> 00:11:36,707 bit too hard to fix. I would keep in mind 253 00:11:36,707 --> 00:11:39,546 for future CTF frameworks to keep it as 254 00:11:39,546 --> 00:11:41,978 simpel as possible, in case anything 255 00:11:41,978 --> 00:11:44,100 breaks it will be a 5 minute job to fix it 256 00:11:48,297 --> 00:11:50,852 If you where to lazy to lisen, here is a 257 00:11:50,852 --> 00:11:53,711 recap. Create new platforms, CTF 258 00:11:53,711 --> 00:11:56,258 platforms are really interesting. 259 00:11:56,258 --> 00:11:58,651 I found a lot of topics I could work in to 260 00:11:58,651 --> 00:12:01,888 while building this and I am not at the 261 00:12:01,888 --> 00:12:04,570 end yet. There is still a lot of things 262 00:12:04,570 --> 00:12:07,868 that I need to look into. But to allow 263 00:12:07,868 --> 00:12:10,024 for a place to play the game and limit 264 00:12:10,157 --> 00:12:12,312 the bad stuff. For people thinking why 265 00:12:12,512 --> 00:12:15,076 docker, people at our local hackerspace 266 00:12:15,211 --> 00:12:17,066 ask all the time "why are you using docker 267 00:12:17,211 --> 00:12:18,596 since there are so many known exploits for 268 00:12:18,761 --> 00:12:19,487 that?" 269 00:12:19,693 --> 00:12:22,531 Finding alternativs would have been an 270 00:12:22,678 --> 00:12:25,677 option, but I am used to docker - and 271 00:12:25,860 --> 00:12:27,547 I actually wanted to used docker. 272 00:12:27,749 --> 00:12:28,770 So, that was kind of nice. 273 00:12:28,954 --> 00:12:34,304 So if you know a better solution: find the 274 00:12:34,429 --> 00:12:36,256 solution, implement it and try out the 275 00:12:36,415 --> 00:12:39,030 CTF. Another thing I wanted to say here 276 00:12:39,194 --> 00:12:42,577 that while using docker it might be 277 00:12:42,727 --> 00:12:44,979 insecure, but you could also implement a 278 00:12:45,183 --> 00:12:47,021 lot of stuff inorder to secure it. 279 00:12:47,278 --> 00:12:50,783 Like implementing custom flags for teams, 280 00:12:50,980 --> 00:12:53,316 so if a teams has got a custom flag 281 00:12:53,457 --> 00:12:55,463 it can't just break out of the container 282 00:12:55,463 --> 00:12:57,561 and get the flag from another team. 283 00:12:57,561 --> 00:12:58,641 Since it is really team specific. 284 00:12:58,826 --> 00:13:00,921 That was what we wanted to do with the 285 00:13:01,122 --> 00:13:03,785 environment variable in the challenge 286 00:13:03,981 --> 00:13:09,494 containers. Because then we could start 287 00:13:09,676 --> 00:13:11,283 the containers as we went. 288 00:13:13,452 --> 00:13:15,138 That's actually the end. 289 00:13:17,486 --> 00:13:20,332 What I still want to say is that sometimes 290 00:13:20,516 --> 00:13:23,103 next year we want to play the CIRCLE CTF 291 00:13:23,262 --> 00:13:25,054 with the platform we built, just to try it 292 00:13:25,220 --> 00:13:27,351 out, but at a larger scale. So, if you 293 00:13:27,547 --> 00:13:30,888 are an active CTF player we are going to 294 00:13:31,068 --> 00:13:35,051 be there and organise a complete new CTF 295 00:13:35,242 --> 00:13:38,830 with us with fun challenges. 296 00:13:38,830 --> 00:13:42,171 I got some of the challenges with me so, 297 00:13:42,323 --> 00:13:44,010 if you are interested in how this might 298 00:13:44,010 --> 00:13:47,411 look or what can be done then just come 299 00:13:47,411 --> 00:13:48,951 to my table. 300 00:13:55,197 --> 00:13:57,607 Also, if you are interested in discussing 301 00:13:57,607 --> 00:13:59,378 solutions on how this could be done better 302 00:13:59,546 --> 00:14:01,748 then just drop by. 303 00:14:01,924 --> 00:14:04,520 If you got questions, watching the live 304 00:14:04,761 --> 00:14:08,103 stream then just tweet me at: @hanemile. 305 00:14:10,426 --> 00:14:11,482 That was it. 306 00:14:19,664 --> 00:14:22,761 Does anyone got any direct questions. 307 00:14:45,542 --> 00:14:47,663 Thanks again Emile. 308 00:14:47,663 --> 00:14:48,752 Translated by CS (ITKST56 course assignment at JYU.FI)