Saturday, January 29, 2022

null byte injection prevention


ftp site has public and secret file links

click public file link shows public file

click secret file link, a warning message displays
text in secret file: This is a secret file for admin

try to view files outside ftp folder, access is denied
%2e%2e%2f%2e%2e%2f%65%74%63%2f%70%61%73%73%77%64%2f 
is encoded url for ../../etc/passwd/

try to inject null byte %00 to bypass file type check, attempt failed
//logs

Example app listening at http://localhost:8080
/home/kali/Documents/ftp/public.txt .txt
/home/kali/Documents/ftp/secret.md .md
/home/kali/etc/passwd/public.txt .txt
/home/kali/Documents/ftp/secret.md%00.txt .txt
//app.js

const express = require('express')
const app = express()
const port = 8080
const path = require('path');

var fs = require('fs'),
    http = require('http');

var bodyParser = require('body-parser')
app.use(bodyParser.json());       // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({     // to support URL-encoded bodies
    extended: true
}));

//render html
app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);

app.get('/ftp/', function (req, res) {
    res.render('ftp');
});

app.get('/ftp/:fileName', function (req, res) {
    var ftpDir = path.join(__dirname, "ftp")
    var downloadLink = path.join(ftpDir, req.params.fileName)

    console.log(downloadLink, path.extname(downloadLink))

    if (downloadLink.indexOf(ftpDir) !== 0) {
        res.send('trying to sneak out of the ftp directory?');
        return
    }

    if (req.params.fileName.indexOf('\0') !== -1) {
        res.send('trying to breach file type filter?');
        return
    }

    if (path.extname(downloadLink) !== ".txt") {
        res.send('trying to download secret file?');
        return
    }

    fs.readFile(downloadLink, function (err, data) {
        if (err) {
            res.writeHead(404);
            res.end(JSON.stringify(err));
            return;
        }
        res.writeHead(200);
        res.end(data);
    });

});

app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`)
})

--------------------
//views/ftp.ejs

<html>

<head>
    <%- include('partials/header'); %>
</head>

<body>
    <div style="margin:100px;">
        <%- include('partials/nav'); %>

            <div class="jumbotron" style="padding:40px;">
                <h3>ftp</h3>
                <a href="/ftp/public.txt">public txt file</a>
                <a href="/ftp/secret.md">secret md file</a>
            </div>
    </div>
</body>

</html>

reference:

No comments:

Post a Comment