WriteUp-第六届安洵杯网络安全挑战赛-010101
首次发表于个人网站:https://yumlii33.github.io/
赛事名称
i-SOON_CTF_2023
第六届安洵杯网络安全挑战赛
赛事描述
https://dce.i-soon.net/#/examineDetails
赛事网址
https://dce.i-soon.net/#/examineDetails
010101
题目
# -*- coding:utf-8 -*-
import os
import random
import string
import hashlib
import socketserver
from Crypto.Util.number import isPrime, long_to_bytes, getStrongPrime, bytes_to_long
flag = b"D0g3{******************************************}"
class MyServer(socketserver.BaseRequestHandler):
def proof(self):
random.seed(os.urandom(8))
random_str = ''.join([random.choice(string.ascii_letters + string.digits) for _ in range(20)])
str_sha256 = hashlib.sha256(random_str.encode()).hexdigest()
self.request.sendall(('SHA256(XXXX + %s):%s\n' % (random_str[4:], str_sha256)).encode())
self.request.sendall('Give Me XXXX:\n'.encode())
XXXX = self.request.recv(2048).strip()
if hashlib.sha256((XXXX + random_str[4:].encode())).hexdigest() != str_sha256:
return False
return True
def getPQN(self):
while True:
p = getStrongPrime(2048)
q = getStrongPrime(2048)
n = p * q
if p.bit_length() == 2048 and q.bit_length() == 2048 and n.bit_length() == 4096:
return p, q, n
def encrypt(self):
p, q, n = self.getPQN()
m = bytes_to_long(flag)
e = 0x10001
c = pow(m, e, n)
p = bin(p)[2:]
p1 = list(p[:1024])
p2 = list(p[1024:])
p1[random.choice([i for i, c in enumerate(p1) if c == '1'])] = '0'
p2[random.choice([i for i, c in enumerate(p1) if c == '0'])] = '1'
return n, ''.join(p1) + ''.join(p2), c
def handle(self):
if not self.proof():
self.request.sendall(b'Error Hash!')
return
n, p, c = self.encrypt()
self.request.sendall('Press 1 to get ciphertext\n'.encode())
number = self.request.recv(512).strip().decode()
if number == '1':
self.request.sendall((str(n) + '\n').encode())
self.request.sendall((str(p) + '\n').encode())
self.request.sendall((str(c) + '\n').encode())
else:
self.request.sendall('Incorrect input!\n'.encode())
return
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
if __name__ == '__main__':
sever = socketserver.ThreadingTCPServer(('0.0.0.0', 10001), MyServer)
ThreadedTCPServer.allow_reuse_address = True
ThreadedTCPServer.allow_reuse_port = True
sever.serve_forever()
考点
crypto
SHA256
RSA
WriteUp
- 分析代码逻辑:
proof
:- 随机生成一个字符串
random_str
- 计算字符串的哈希值
str_sha256
- 给出
random_str[4:]
和str_sha256
,让用户计算random_str[:4]
- 如果用户给定的
random_str[:4]
和random_str[4:]
的哈希值相同,则验证通过
- 随机生成一个字符串
getPQN
:- 随机生成两个大素数
p
和q
,满足以下要求:p.bit_length() == 2048 and q.bit_length() == 2048 and (p*q).bit_length() == 4096
return p, q, n
- 随机生成两个大素数
encrypt
:- 通过
getPQN
生成p
和q
和n
- 计算密文
c = pow(m, e, n)
- 对
p
进行变换:前1024位随机挑选一个1变成0,后1024位随机挑选一位变成1,得到fake_p
return n, fake_p, c
- 通过
handle
:- 通过
proof
函数判断用户输入的XXXX
和random_str[4:]
的哈希值是否相同 - 相同的话,通过
encrypt
函数对flag
进行加密,返回n, fake_p, c
- 通过
- 解题步骤:
-
nc
连入服务器,获取random_str[4:]
和str_sha256
-
通过
getXXXX.py
爆破random_str[:4]
,并将结果发送给服务器,获得n,fake_p,c
import hashlib import itertools from string import digits, ascii_letters, punctuation alpha_bet=digits+ascii_letters+punctuation strlist = itertools.product(alpha_bet, repeat=4) sha256="5ccd4cda1dc33d20a072cddf2cf921c865b274da912edb7ac3f157404c3fe4e3" tail="uLBLoFfDko5h5uA9" xxxx='' for i in strlist: data=i[0]+i[1]+i[2]+i[3] data_sha=hashlib.sha256((data+str(tail)).encode()).hexdigest() if(data_sha==str(sha256)): xxxx=data break print(xxxx)
-
基于
encrypt
函数,编写decrypt.py
脚本,破解p
,解密得到flag
# -*- coding:utf-8 -*- import os import random import string import hashlib import socketserver from Crypto.Util.number import long_to_bytes n=909467367699122020071016988650306999295228108976638769699035391871165765547800730173871546690865275123375066230171521311068819816852640125745292539541259006023609504769135551654529045891894185101263480691408339167146959806826342796151867522273018753414683125578415962666829770904166690498846087399777025030862122796483743577214854248422262763202974262015130017066825754008160259189414818697567284326444565265735329976239935592453543076795651573576794776003238789860869381589213987112412732442793109900427324085928201408085720252507826509949584097216821241278182597257299885172782505117521436358744947983811939554943145617958259867137670519879871430621545154465019553001205911580515698810275961361004704605451591223643427530911392689056988136336912424730785373902092658701108834786609423741166892942322112744091173801215997979197781791157780385712374075574951133435122784372704793303399699730638707098947178219189508884581830248871075957102690166621382729933821529281361101591281902812061185346676660877303782149165897420682724683205662866974137418732285231256810541807361468193401184858075051706155601176563558866315093106261534227649361408522136583934234512184301782185760219449297423394506961283209453334215176208906015567865682661 fake_p='11100000100010111111010011100000110011001000001001111011001010011100001101000000001010000010101000011110000001000000010111000110101000101101011101111010001110110000000001101110100011101001100011101010110011111001001011101000110100011011101011110110001111100110101000010110110001001110001101111111100001101101110010011110100101110001101101101011011100111110101111000111000010011101001000011110000101111000010110000001100001111001011100011001110110110110000110000110111010111101110111100100111101111001100110010000000110011011111011111100000010010111111000010110010000110000111100011001111010101000111110011110001010101010010100001010100110111111101010010000000100101011001011100100111111001000111011111010101011111111010011101110111111110011101111001000011011000000000011100101101000001101110101100001110000110101011001000010110110000110110001101010110001100010110010110000000001110001101111011100011011110101010010011010100011010100010101100000010111100000101100010110000100001001101001001001111011011000101010001011010001100101110111111100111111001011100001100001011101011000000001101111011011001001100100111101100100111100100000000111110100011100011110001101100000100000101001101100010100000110111010001111011010110100101010101100000000001111001111010100011000010010010001010011100111100001101100111100010101111101011001100011111011000011101111110101110010100011000111010100000000111110111001111110100011100100111101001101011010110001100000101010001111000110100110101110001011100010011100111110111111010001110111000001000010111110100000110110110010111101101111010010110100011110110011011010010000000000101110101001001111100110111111001000000101101011111011110110111111001101001111011100110101101010101100000010100111101110110101101010100110011010011101101000010011101011001011110001011110011000101110000100000110100011101001100101110000001110100111010110110000101000011011010011100101101011010010010100110011011100001110001000000111101111000001010110111111010110101111000100111111111111101111001110101101111111101111011011101111111000100000110111' c=694500789519839583373480124753870609796624184368847740052659890684952282469412685843793893336588959688292535565388961237054382061607809034620598317779687541764120119851622500197513641485700221545824097256986828990721130988465432457926804939623885349284941907683524562179105951076405178191916974212394857571647273209891325684133975190612454243345915122493599006273649156588911638621279271660577286076492174133379924878816759449537816258877983535822071467357826352013991371273144147958254806851665648862909470014188217381547444474766611515043375595448634817257201321537710925281810846187991415244304258902323932755496219900194257710795367213151869032406828586461628113793387618900293473170817978068346842472541499877290335671510770413540109295368927586613167172537907784632075379648806105818669008103026164730513033786875076959900405998112656279798642754984874654321483935047414576483030634418889375971016788408747123075626184286939742532706576269950026208168650867226593584227608482405783125152467929531339747039920420671850985997912834217484356948372454631601487864570640693252550030654681522447089126289751692094672022733644147229926742656125552935762042624836326359406490008032106080800094693108856102201450516929541344003829402493 e = 0x10001 fake_p1=list(fake_p[:1024]) fake_p2=list(fake_p[1024:]) p=0 q=0 for i, x in enumerate(fake_p1): if x == '0': p1=fake_p1[:i]+['1']+fake_p1[i+1:] p2=fake_p2 p=int(''.join(p1)+''.join(p2),2) if n%p==0: q=n//p if p.bit_length() == 2048 and q.bit_length() == 2048 and n.bit_length() == 4096: print("Get p q!\n") break else: print("bad format1!") else: for j,y in enumerate(fake_p2): if y== '1': p2=fake_p2[:j]+['0']+fake_p2[j+1:] p=int(''.join(p1)+''.join(p2),2) if n%p==0: q=n//p if p.bit_length() == 2048 and q.bit_length() == 2048 and n.bit_length() == 4096: print("Get p q!\n") break else: print("bad format2!") print(p) print(q) phi_n = (p - 1) * (q - 1) print("phi_n:") print(phi_n) d = pow(e, -1, phi_n) m = pow(c, d, n) print(long_to_bytes(m))
-
FLAG
D0g3{sYuWzkFk12A1gcWxG9pymFcjJL7CqN4Cq8PAIACObJ}