chall.py

#!/usr/bin/python3
from Crypto.Util.number import getPrime, long_to_bytes, inverse
flag = open('flag.txt', 'r').read().strip().encode()

class RSA:
    def __init__(self):
        self.p = getPrime(512)
        self.q = getPrime(512)
        self.e = 3
        self.n = self.p * self.q
        self.d = inverse(self.e, (self.p-1)*(self.q-1))
    def encrypt(self, data: bytes) -> bytes:
        pt = int(data.hex(), 16)
        ct = pow(pt, self.e, self.n)
        return long_to_bytes(ct)
    def decrypt(self, data: bytes) -> bytes:
        ct = int(data.hex(), 16)
        pt = pow(ct, self.d, self.n)
        return long_to_bytes(pt)

def main():
    crypto = RSA()
    print ('Flag:', crypto.encrypt(flag).hex())

if __name__ == '__main__':
    main()

 

output.txt

Flag: 05c61636499a82088bf4388203a93e67bf046f8c49f62857681ec9aaaa40b4772933e0abc83e938c84ff8e67e5ad85bd6eca167585b0cc03eb1333b1b1462d9d7c25f44e53bcb568f0f05219c0147f7dc3cbad45dec2f34f03bcadcbba866dd0c566035c8122d68255ada7d18954ad604965

 

주어진 두 코드를 보면 ct와 e가 주어진 RSA 문제라는 것을 알 수 있다

n 또한 주어지지 않았기 때문에 ct와 매우 작은 e를 사용하여 낮은지수 공격을 수행하면 될 것 같다

 

sol.py

from gmpy2 import *
from Crypto.Util.number import long_to_bytes

c = int('05c61636499a82088bf4388203a93e67bf046f8c49f62857681ec9aaaa40b4772933e0abc83e938c84ff8e67e5ad85bd6eca167585b0cc03eb1333b1b1462d9d7c25f44e53bcb568f0f05219c0147f7dc3cbad45dec2f34f03bcadcbba866dd0c566035c8122d68255ada7d18954ad604965', 16)
e = 3
 
with local_context() as ctx:
    ctx.precision=3000
    m=iroot(c,e)[0]
 
    print(long_to_bytes(m))

 

'wargame > hack the box' 카테고리의 다른 글

HTB RSAisEasy writeup  (0) 2023.03.30
HTB xorxorxor writeup  (0) 2023.03.30
HTB BabyEncryption writeup  (0) 2022.10.23

chall.py

#!/usr/bin/env python3
from Crypto.Util.number import bytes_to_long, getPrime
from secrets import flag1, flag2
from os import urandom

flag1 = bytes_to_long(flag1)
flag2 = bytes_to_long(flag2)

p, q, z = [getPrime(512) for i in range(3)]

e = 0x10001

n1 = p * q
n2 = q * z

c1 = pow(flag1, e, n1)
c2 = pow(flag2, e, n2)  

E = bytes_to_long(urandom(69))

print(f'n1: {n1}')
print(f'c1: {c1}')
print(f'c2: {c2}')
print(f'(n1 * E) + n2: {n1 * E + n2}')

 

output.txt

n1: 101302608234750530215072272904674037076286246679691423280860345380727387460347553585319149306846617895151397345134725469568034944362725840889803514170441153452816738520513986621545456486260186057658467757935510362350710672577390455772286945685838373154626020209228183673388592030449624410459900543470481715269
c1: 92506893588979548794790672542461288412902813248116064711808481112865246689691740816363092933206841082369015763989265012104504500670878633324061404374817814507356553697459987468562146726510492528932139036063681327547916073034377647100888763559498314765496171327071015998871821569774481702484239056959316014064
c2: 46096854429474193473315622000700040188659289972305530955007054362815555622172000229584906225161285873027049199121215251038480738839915061587734141659589689176363962259066462128434796823277974789556411556028716349578708536050061871052948425521408788256153194537438422533790942307426802114531079426322801866673
(n1 * E) + n2: 601613204734044874510382122719388369424704454445440856955212747733856646787417730534645761871794607755794569926160226856377491672497901427125762773794612714954548970049734347216746397532291215057264241745928752782099454036635249993278807842576939476615587990343335792606509594080976599605315657632227121700808996847129758656266941422227113386647519604149159248887809688029519252391934671647670787874483702292498358573950359909165677642135389614863992438265717898239252246163

 

주어진 코드와 값을 보면 n1을 이용해서 p와 q를 구해볼 수 있다

factordb에 n1을 돌려보면 다음과 같이 p, q가 나온다

(이때 소수 두개가 나오는데 이 중에서 뭐가 p이고 q인지 알 수 없음 -> flag1을 구할 때는 p,q가 바뀌어도 딱히 상관없음)

p = 12040644312371555810530782070969893153760288255333349208608058511112776958879208815174991008199408527954332776642365069284747758115478414463195873149420483
q = 8413387656561188778435613942028835678781206299389177514340760123063579360223360470566083306606450007991287094526418200038784207648097820069671213638771543

이렇게 p, q값을 구했으니 flag1은 구할 수 있지만 n2를 아직 모르기 때문에 flag2는 구할 수 없다

output.txt의 마지막 값인 (n1 * E) + n2를 이용해서 n2를 구해볼 것인데 n1*E+n2에서 n2를 구하려면 (n1*E+n2)%n1 을 하면된다

n1_E_n2 = 601613204734044874510382122719388369424704454445440856955212747733856646787417730534645761871794607755794569926160226856377491672497901427125762773794612714954548970049734347216746397532291215057264241745928752782099454036635249993278807842576939476615587990343335792606509594080976599605315657632227121700808996847129758656266941422227113386647519604149159248887809688029519252391934671647670787874483702292498358573950359909165677642135389614863992438265717898239252246163
n1 = 101302608234750530215072272904674037076286246679691423280860345380727387460347553585319149306846617895151397345134725469568034944362725840889803514170441153452816738520513986621545456486260186057658467757935510362350710672577390455772286945685838373154626020209228183673388592030449624410459900543470481715269

n2 = n1_E_n2%n1
n2 = 100136903041423020991425823526737746365573197640035952973693624809721624428963253203282593974533722584391447008912397042291986993273828302711324440847902763039627790146764630023926517236880457533976468679976683705170312329736955922713306570804595070537102421450884645497775455984735279182873866159334387494837

그리고 이제 z의 값도 구할 수 있다

(처음 문제를 풀 때는 p, q의 값을 바꿔서 써서 n2 = n1_E_n2 % n1의 값과 n2//q로 구한 z의 값을 이용한 n2 = q*z의 값이 달랐었다)

z값은 n2//q를 이용해서 구한다

 

그럼 필요한 값은 모두 구했기 때문에 flag1과 flag2를 구해서 전체 플래그를 구할 수 있다

 

sol.py

from Crypto.Util.number import inverse, long_to_bytes

n1 = 101302608234750530215072272904674037076286246679691423280860345380727387460347553585319149306846617895151397345134725469568034944362725840889803514170441153452816738520513986621545456486260186057658467757935510362350710672577390455772286945685838373154626020209228183673388592030449624410459900543470481715269
c1 = 92506893588979548794790672542461288412902813248116064711808481112865246689691740816363092933206841082369015763989265012104504500670878633324061404374817814507356553697459987468562146726510492528932139036063681327547916073034377647100888763559498314765496171327071015998871821569774481702484239056959316014064
c2 = 46096854429474193473315622000700040188659289972305530955007054362815555622172000229584906225161285873027049199121215251038480738839915061587734141659589689176363962259066462128434796823277974789556411556028716349578708536050061871052948425521408788256153194537438422533790942307426802114531079426322801866673
n1_e_n2 = 601613204734044874510382122719388369424704454445440856955212747733856646787417730534645761871794607755794569926160226856377491672497901427125762773794612714954548970049734347216746397532291215057264241745928752782099454036635249993278807842576939476615587990343335792606509594080976599605315657632227121700808996847129758656266941422227113386647519604149159248887809688029519252391934671647670787874483702292498358573950359909165677642135389614863992438265717898239252246163
e = 0x10001

p = 12040644312371555810530782070969893153760288255333349208608058511112776958879208815174991008199408527954332776642365069284747758115478414463195873149420483
q = 8413387656561188778435613942028835678781206299389177514340760123063579360223360470566083306606450007991287094526418200038784207648097820069671213638771543

n2 = n1_e_n2%n1
z = n2//q

phi1 = (p-1) * (q-1)
d1 = inverse(e, phi1)

phi2 = (q-1) * (z-1)
d2 = inverse(e, phi2)

flag1 = pow(c1, d1, n1)
flag2 = pow(c2, d2, n2)

print(long_to_bytes(flag1) + long_to_bytes(flag2))

'wargame > hack the box' 카테고리의 다른 글

HTB Lost Modulus writeup  (0) 2023.03.30
HTB xorxorxor writeup  (0) 2023.03.30
HTB BabyEncryption writeup  (0) 2022.10.23

chall.py

#!/usr/bin/python3
import os
flag = open('flag.txt', 'r').read().strip().encode()

class XOR:
    def __init__(self):
        self.key = os.urandom(4)
    def encrypt(self, data: bytes) -> bytes:
        xored = b''
        for i in range(len(data)):
            xored += bytes([data[i] ^ self.key[i % len(self.key)]])
        return xored
    def decrypt(self, data: bytes) -> bytes:
        return self.encrypt(data)

def main():
    global flag
    crypto = XOR()
    print ('Flag:', crypto.encrypt(flag).hex())

if __name__ == '__main__':
    main()

 

output.txt

Flag: 134af6e1297bc4a96f6a87fe046684e8047084ee046d84c5282dd7ef292dc9

 

밑의 chall.py 코드를 살펴보면

xored += bytes([data[i] ^ self.key[i % len(self.key)]])

len(self.key)는 os.urandom(4)로 작성했기 때문에 4로 항상 동일하다

따라서 self.key[i % len(self.key)]] 는 i가 4보다 작으면 i값 그대로 리턴해주고 4보다 크면 i-4를 리턴해준다

 

이때 self.key[]는 self.key[0], self.key[1], self.key[2], self.key[3] 이렇게 4개만 있다

-> 그래서 플래그 길이만큼 10진수 4개가 반복해서 플래그 인덱스 i와 xor되어서 이를 바이트로 차례대로 저장한다

 

그리고 이를 16진수로 바꾼게 제공받은 output.txt이다

 

플래그 중 일부분인 HTB{ 라는 플래그 형식을 알고있고 4글자라는 것을 이용해 self.key를 찾아낼 수 있다

output으로 제공받은 16진수에서 2글자 당 평문 글자 하나를 암호화한다

이를 이용해서 키를 구하는 코드를 작성해보면 다음과 같다

a = ['H', 'T', 'B', '{']
b = ['13', '4a', 'f6', 'e1']

key = []
for i in range(4):
    a[i] = hex(ord(a[i]))[2:]
    key.append(int(hex(int(a[i],16)^int(b[i], 16))[2:], 16))

print(key)

그럼 키는 [91, 30, 180, 154] 라는 것을 알 수 있다

 

이제 이 키를 이용해서 제공받은 16진수 플래그를 2글자씩 끊어서 xor해주면 평문인 플래그가 나올 것이다

 

sol.py

#a = ['H', 'T', 'B', '{']
#b = ['13', '4a', 'f6', 'e1']
#
#key = []
#for i in range(4):
#    a[i] = hex(ord(a[i]))[2:]
#    key.append(int(hex(int(a[i],16)^int(b[i], 16))[2:], 16))
#
#print(key)

key = [91, 30, 180, 154]

flag = '134af6e1297bc4a96f6a87fe046684e8047084ee046d84c5282dd7ef292dc9'

arr = []

for i in range(0, len(flag), 2):
    arr.append(int(flag[i] + flag[i+1], 16))

msg = b""
for i in range(len(arr)):
    msg += bytes([arr[i] ^ key[i % 4]])

print(msg)

 

'wargame > hack the box' 카테고리의 다른 글

HTB Lost Modulus writeup  (0) 2023.03.30
HTB RSAisEasy writeup  (0) 2023.03.30
HTB BabyEncryption writeup  (0) 2022.10.23

주말에 이것저것 찾아보다가 새로운 워게임 사이트를 발견했다

Crypto - noisy

encrypt.py

from Crypto.Util.number import *

flag = "UNKNOWN"

p = getPrime(2048)
q = getPrime(2048)
e = 3
phi = (p - 1) * (q - 1)
d = pow(e, -1, phi)
N = p * q

a = getPrime(256)
b = getPrime(256)
flag = bytes_to_long(flag)
flag1 =  a * flag + b

c1 = pow(flag1, e, N)
c2 = pow((flag), e, N)

assert(pow(c1, d, N) == flag1)
assert(pow(c2, d, N) == flag)

print(N)
print(e)
print(c1)
print(c2)
print(a)
print(b)

encrypt.py를 보면 내가 구하려는 것은 flag이기 때문에 주어진 6개의 요소 중 c1, a, b는 사용하지 않았다.
다운받은 enc.txt도 보면 e값이 3으로 매우 작은것을 알 수 있었고 낮은지수 공격을 이용하여 문제를 풀었다.

from gmpy2 import *
from Crypto.Util.number import *
import time 
n = 317040651679373211203052920616005723678020156043628323332424772070975737453408838469787064188786011573404860315719531289497744855149648693106833220893566469137933367925417989088393428081488338940326190378085032657287146700415402636680277863355428263621630525484435545273639843015411759501613170657498993265825219268635185095788704667818488133253959599802463638649406699422719391733724583724025291694081932388296146208021483007849056796340521197771858162785429158848258434728868971277822370788477078046638988244145956273926422409006854446490844902097353140906585907615729831021135264713171213218099904040054190835213689864989036128553169219265026898127693711592592146507088549862468638817790078090116453255902533987667528301890465974635865742293209293806778416593653897850790336390681201239324555097941294112232117306893385741521626628689787545632725387549814767531756371737740572219769069441283585425896640819299563592008738345302900504187795287179485677802770486028077737997406541494777650298180989153685352404527946553530659987383623342371095072298448494604853114349302537264362538517244435429874419107749816127165211721817516961841383469631957904885678760629435470386620807103484614770446981317888580422731368821491703012190183243
c = 8297423020022584155011048994131832532824769074603023730133414978795876083975829767265894418737130405482092398749557510849356438382806334207752350424328189587538835124850818790342725062432577666660785216065345678061943982215620548836592472455231224905601436909814422212405387665285635705441455639510030326136599676781656710020740773913531981988901910524876336689922252137646035508407628715768925469851812056183896960489642237162363954459588105185425583983516407862459239754702318180363135870652414123417287108500334785797074965659493879646074666170795550533107295994421467507825853297020990968465269194425974012716422816703183529876173808423121297943817528992643716946584739099328084201918671645348445667073297906942267193317797356444500014074902610476607216717889696917598060829137189261664903853879838844091472012719908117333187156067157240412062289054821454999696908286081864861687576456825071844285971295647010885157801032909560332164820250910702287272446130959717
e = 3


with local_context() as ctx:
    ctx.precision=3000
    m=iroot(c,e)[0]

flag = long_to_bytes(m)

print(flag)

chall.py

import string
from secret import MSG

def encryption(msg):
    ct = []
    for char in msg:
        ct.append((123 * char + 18) % 256)
    return bytes(ct)

ct = encryption(MSG)
f = open('./msg.enc','w')
f.write(ct.hex())
f.close()

msg.enc

6e0a9372ec49a3f6930ed8723f9df6f6720ed8d89dc4937222ec7214d89d1e0e352ce0aa6ec82bf622227bb70e7fb7352249b7d893c493d8539dec8fb7935d490e7f9d22ec89b7a322ec8fd80e7f8921

sol.py

from Crypto.Util.number import *

ct = '6e0a9372ec49a3f6930ed8723f9df6f6720ed8d89dc4937222ec7214d89d1e0e352ce0aa6ec82bf622227bb70e7fb7352249b7d893c493d8539dec8fb7935d490e7f9d22ec89b7a322ec8fd80e7f8921'

def decryption(ct):
    pt = []
    for char in ct:
        pt.append((char - 18) * inverse(123, 256) % 256)
    return bytes(pt)

print(decryption(bytes.fromhex(ct)))

주어진 코드를 보고 암호문을 대상으로 거꾸로 실행하면 된다.

 

output

b'Th3 nucl34r w1ll 4rr1v3 0n fr1d4y.\nHTB{l00k_47_y0u_r3v3rs1ng_3qu4710n5_c0ngr475}'

HTB{l00k_47_y0u_r3v3rs1ng_3qu4710n5_c0ngr475}

'wargame > hack the box' 카테고리의 다른 글

HTB Lost Modulus writeup  (0) 2023.03.30
HTB RSAisEasy writeup  (0) 2023.03.30
HTB xorxorxor writeup  (0) 2023.03.30

문제에 접속하여 view source에 들어가보면 위 사진과 같은 소스코드가 나온다.

소스코드를 보면 몇가지 사실을 알 수 있는데

1. SetCookie 함수로 user_lv 쿠키를 1로 설정함.

2. user_lv 쿠키값을 확인해서 숫자가 아니면 user_lv 쿠키값을 1로 설정함

if(!is_numeric($_COOKIE['user_lv'])) $_COOKIE['user_lv']=1;

3. user_lv cookie 값이 4보다 크거나 같으면 cookie 값이 1로 설정되고 user_lv cookie 값이 3보다 크면 문제가 해결된다.

if($_COOKIE['user_lv']>=4) $_COOKIE['user_lv']=1;
if($_COOKIE['user_lv']>3) solve(1);

이를 통해 쿠키값을 바꾸면 문제를 풀 수 있다는 것을 알 수 있다.

난 크롬 확장 프로그램에서 쿠키 변조 툴을 설치하여 풀었다 (EditThisCookie 설치)

 

php 구문을 보면 3보다 크고 4보다 작은 값을 넣어야 문제를 풀 수 있다는 것을 알 수 있다.

위 사진처럼 난 쿠키값에 3.5를 넣어서 3보다 크고 4보다 작다는 조건에 성립하도록 만들어줬다.

3.5로 설정하고 페이지를 다시 접속하면 문제가 풀린다.