pwn+crypto?
__import__("os").environ["TERM"] = "xterm-256color"
from pwn import *
from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature, encode_dss_signature
from binascii import unhexlify, hexlify
import warnings
warnings.filterwarnings("ignore", category=BytesWarning)
# context.log_level = "debug"
# r = process("./chall")
r = remote("13.209.82.80", 5333)
def register(id, pw):
r.sendlineafter("Enter choice: ", "1")
r.sendlineafter("Enter name: ", id)
r.sendlineafter("Enter role: ", "admin")
r.sendlineafter("Enter password: ", pw)
def login(id, pw):
r.sendlineafter("Enter choice: ", "2")
r.sendlineafter("Enter name: ", id)
r.sendlineafter("Enter password: ", pw)
def update_role(id, role):
r.sendlineafter("Enter choice: ", "3")
r.sendlineafter("Enter name: ", id)
r.sendlineafter("Enter a new role: ", role)
def reset_password(pw):
r.sendlineafter("Enter choice: ", "4")
r.sendlineafter("Enter new password: ", pw)
def sig(msg):
r.sendlineafter("Enter choice: ", "5")
r.sendlineafter("Enter message: ", msg)
r.recvuntil("Message: ")
used_msg = r.recvline()[:-1]
r.recvuntil("Sig: ")
used_sig = r.recvline()[:-1]
der_signature = unhexlify(used_sig)
r_, s = decode_dss_signature(der_signature)
# return used_msg, used_sig
return r_, s
def reset_nonce():
r.sendlineafter("Enter choice: ", str(0xdeadbeef))
list_r = []
list_s = []
list_hm = []
register(str(1), str(1)*2)
login(str(1), str(1)*2)
update_role("admin", "a" * 32)
login("admin", b"\x00")
import os
num = 150
for _ in range(num):
reset_password("a"*32)
m = os.urandom(8).hex().encode()
r_, s_ = sig(m)
reset_nonce()
list_r.append(r_)
list_s.append(s_)
list_hm.append(int(hashlib.sha256(m).hexdigest(), 16))
from Crypto.Util.number import *
n = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551
ln = len(list_r)
R = 2**248
A = Matrix(QQ, ln+2, ln+2)
for i in range(ln):
r_ = list_r[i]
s = list_s[i]
hm = list_hm[i]
tm = inverse(s, n) * r_
am = -inverse(s, n) * hm
A[i, i] = n
A[ln, i] = tm
A[ln+1, i] = am
A[ln, ln] = R/n
A[ln+1, ln+1] = R
from ecdsa import NIST256p, ellipticcurve, numbertheory
# P-256 타원 곡선 설정
curve = NIST256p.curve
generator = NIST256p.generator
order = generator.order()
B = A.LLL()
for row in B:
if row[-1] == R:
d = int(row[-2] * n // R) % n
print("개인키", d)
print("개인키2", order - d)
t = generator * d
print("공개키", t.to_affine())
t = generator * (order - d)
print("공개키2", t.to_affine())
d = order - d
break
r.sendlineafter("Enter choice: ", str(6))
r.sendlineafter("Enter name: ", "admin")
pem_key = r.recvuntil("1.")[:-2]
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
import base64
import gmpy2
# 공개키 로드
public_key = serialization.load_pem_public_key(pem_key, backend=default_backend())
# 공개키에서 숫자 좌표 추출
numbers = public_key.public_numbers()
Qx = numbers.x
Qy = numbers.y
print("공개키", Qx, Qy)
curve = NIST256p.curve
a = curve.a()
b = curve.b()
p = curve.p()
# 특정 x 값 설정
x = Qx
# y^2 계산
rhs = (pow(x, 3, p) + a * x + b) % p
# y 계산 (모듈로 p에서의 제곱근)
y1 = gmpy2.powmod(rhs, (p + 1) // 4, p) # 양의 제곱근
y2 = (-y1) % p # 음의 제곱근
# 결과 출력
print("x:", x)
print("y1:", y1)
print("y2:", y2)
from ecdsa import SigningKey, NIST256p, BadSignatureError
curve = NIST256p
# 개인키 생성 (개인키 d를 사용하여 생성)
# private_key = SigningKey.from_secret_exponent(d, curve=curve)
# 메시지 정의
message = b"SHOW ME THE FLAG"
# 메시지 서명 생성
# signature = private_key.sign(message)
# rr, ss = decode_dss_signature(signature)
# # r과 s 값을 DER 형식의 서명으로 인코딩
# signature_der = encode_dss_signature(rr, ss)
# # 서명을 16진수 문자열로 변환하여 출력
# signature_hex = signature_der.hex()
# print("DER 형식의 서명 (hex):", signature_hex)
z = int.from_bytes(hashlib.sha256(message).digest(), byteorder='big')
# # 랜덤 값 k 선택
k = 156165121
# # R 계산 (R = k * G)
R = k * generator
# # r 계산 (R의 x 좌표를 사용)
r_ = R.x() % order
from ecdsa import NIST256p, ellipticcurve, numbertheory
# k의 모듈러 역수 계산
k_inv = numbertheory.inverse_mod(k, order)
# s 계산
s_ = (k_inv * (z + r_ * d)) % order
r_ = int(r_)
s_ = int(s_)
# r과 s 출력
print("r:", r_)
print("s:", s_)
# public_key = private_key.get_verifying_key()
# print(public_key.verify(signature, message))
from ecdsa import SigningKey, NIST256p, util
# rr, ss = util.sigdecode_string(signature, private_key.curve.order)
print(f"r: {r_}")
print(f"s: {s_}")
sig_ = encode_dss_signature(r_, s_).hex()
assert r_, s_ == decode_dss_signature(sig_)
print(sig_)
r.sendlineafter("Enter choice: ", str(0x13371337))
r.sendlineafter("Enter MessageLen: ", str(len(message) + 1))
msg = message.hex() + "00"
r.recvuntil("Enter Message: ")
for i in range(0, len(msg), 2):
r.sendline(msg[i:i+2])
r.sendlineafter("Enter sigLen: ", str(len(sig_)//2))
r.recvuntil("Enter sig: ")
for i in range(0, len(sig_), 2):
r.sendline(sig_[i:i+2])
r.interactive()
'writeups' 카테고리의 다른 글
2024 Blaz CTF - solana challs (0) | 2024.10.08 |
---|---|
SekaiCTF 2024 - solana (0) | 2024.08.26 |
CrewCTF 2024 - blockchain(lightbook) (0) | 2024.08.05 |
HITCON CTF 2024 Quals(Lustrous, No-Exit Room, Flag Reader) (0) | 2024.07.15 |
justctf2024 teaser (0) | 2024.06.17 |