'2019/11/15'에 해당되는 글 4건

문제에서 제공하는 파일은 클라이언트용 파이썬 코드와 pcap 파일 두가지이다.


먼저 클라이언트 파이썬 코드를 보면 아래와 같다.


client.py


from socket import *

from ssl import *

import time


def recv_until(s, string):

    result = ''

    while string not in result:

        result += s.recv(1)

    return result


client_socket=socket(AF_INET, SOCK_STREAM)

tls_client = wrap_socket(client_socket, ssl_version=PROTOCOL_TLSv1_2, cert_reqs=CERT_NONE)


print "[+] Connecting with server.."


tls_client.connect(('ch41l3ng3s.codegate.kr',443))


print "[+] Connect OK"


while 1:

    data = recv_until(tls_client, "Input : ")

    print data

    #message

    user_input = raw_input()

    

    if user_input == "u":

        print "Sorry.. Not support function.."

        exit()

    elif user_input == "d": 

        tls_client.send("6423e47152f145ee5bd1c014fc916e1746d66e8f5796606fd85b9b22ad333101\n")

    elif user_input == "r":

        tls_client.send("34660cfdd38bb91960d799d90e89abe49c1978bad73c16c6ce239bc6e3714796\n")

    elif user_input == "l":

        print "Sorry.. Not support function.."

        exit()

    else:

        print "Invalid input!"

        exit()    


client_socket.shutdown(SHUT_RDWR)

client_socket.close()



예전 문제라 현재 서버가 존재하지 않지만 코드를 보면 방향키 입력 시 해당 방향과 매칭되는 해쉬값을 서버에 보내 실제 방향 이동을 하는 것 같았다.

근데 이 때 4가지 방향 중 2가지 방향에 대한 해쉬 값이 없어 방향 이동 제한이 존재하는 것 같았고 실제 문제 출제가 어떻게 되었었는지 확인해보니 게임을 통해 플래그 위치까지 가려면 4가지 방향에 대해 모두 이동을 해야만 하는 상황이었었다.


해당 코드만 가지고 뭔가 할만한건 없으니 pcap 파일을 보면 통신이 TLS로 이루어져 패킷 내용을 확인할 수 없는 상황이었다.


여기서 뭘 해야할지 감이 안왔는데 크립토 문제였기 때문에 일단 와이어샤크를 통해 TLS 통신 시 사용된 인증서를 추출한 뒤 공개키가 소인수분해가 되거나, factor db를 통해 p,q를 구할 수 있는지 확인해보는식으로 진행해봤다.


인증서 추출은 아래 글을 참고

https://5kyc1ad.tistory.com/57


추출한 인증서에서 n 값을 확인


openssl x509 -inform der -in test.crt -pubkey -noout > pub.key


python RsaCtfTool.py --dumpkey --key pub.key

[*] n: 316033277426326097045474758505704980910037958719395560565571239100878192955228495343184968305477308460190076404967552110644822298179716669689426595435572597197633507818204621591917460417859294285475630901332588545477552125047019022149746524843545923758425353103063134585375275638257720039414711534847429265419

[*] e: 65537


factordb에서 p,q 값 확인

p = 17777324810733646969488445787976391269105128850805128551409042425916175469168770593916088768472336728042727873643069063316671869732507795155086000807594027


q = 17777324810733646969488445787976391269105128850805128551409042425916175469483806303918279424710789334026260880628723893508382860291986009694703181381742497


인증서에 사용된 공개키를 통해 d를 구할 수 있는 상황이기 때문에 RsactfTool을 이용해 private key를 생성한 뒤 wireshark에 생성한 private key를 적용해줬다.


python RsaCtfTool.py --publickey pub.key --private > pri.key


아래 게시글을 참조하여 생성한 개인키 와이어 샤크에 적용

https://hiseon.me/network/decrypt-ssl-traffic/


위 과정들을 통해 pcap 파일에 존재하는 패킷 내용을 복호화 할 수 있었고, 통신 내용을 확인해보니 아래와 같이 나머지 두 방향키에 대한 해쉬 값을 확인할 수 있었다.



이제 모든 방향 이동이 가능하기 때문에 게임 클리어가 가능하고 이를 통해 플래그를 구해주면 된다.

블로그 이미지

JeonYoungSin

메모 기록용 공간

,

source.py


import multiprocessing


from Crypto.Cipher import AES


from secret import key, flag


counter = 0

aes = AES.new(key, AES.MODE_ECB)



def chunk(input_data, size):

    return [input_data[i:i + size] for i in range(0, len(input_data), size)]



def xor(*t):

    from functools import reduce

    from operator import xor

    return [reduce(xor, x, 0) for x in zip(*t)]



def xor_string(t1, t2):

    t1 = map(ord, t1)

    t2 = map(ord, t2)

    return "".join(map(chr, xor(t1, t2)))



def pad(data):

    pad_byte = 16 - len(data) % 16

    return data + (chr(pad_byte) * pad_byte)



def worker_function(block):

    global counter

    key_stream = aes.encrypt(pad(str(counter)))

    result = xor_string(block, key_stream)

    counter += 1

    return result



def distribute_work(worker, data_list, processes=8):

    pool = multiprocessing.Pool(processes=processes)

    result = pool.map(worker, data_list)

    pool.close()

    return result



def encrypt_parallel(plaintext, workers_number):

    chunks = chunk(pad(plaintext), 16)

    results = distribute_work(worker_function, chunks, workers_number)

    return "".join(results)



def main():

    plaintext = """The Song of the Count


You know that I am called the Count

Because I really love to count

I could sit and count all day

Sometimes I get carried away

I count slowly, slowly, slowly getting faster

Once I've started counting it's really hard to stop

Faster, faster. It is so exciting!

I could count forever, count until I drop

1! 2! 3! 4!

1-2-3-4, 1-2-3-4,

1-2, i love couning whatever the ammount haha!

1-2-3-4, heyyayayay heyayayay that's the sound of the count

I count the spiders on the wall...

I count the cobwebs in the hall...

I count the candles on the shelf...

When I'm alone, I count myself!

I count slowly, slowly, slowly getting faster

Once I've started counting it's really hard to stop

Faster, faster. It is so exciting!

I could count forever, count until I drop

1! 2! 3! 4!

1-2-3-4, 1-2-3-4, 1,

2 I love counting whatever the

ammount! 1-2-3-4 heyayayay heayayay 1-2-3-4

That's the song of the Count!

""" + flag

    encrypted = encrypt_parallel(plaintext, 32)

    print(encrypted.encode("hex"))



if __name__ == '__main__':

    multiprocessing.freeze_support()

    main()



solve.py


from Crypto.Util.strxor import strxor


def pad(data):

    pad_byte = 16 - len(data) % 16

    return data + (chr(pad_byte) * pad_byte)


def unpad(data):

    last_char = data[-1]

    if ord(last_char) < 16:

        return data.rstrip(last_char)

    else:

        return data


def chunk(input_data, size):

    return [input_data[i:i + size] for i in range(0, len(input_data), size)]


def xor(*t):

    from functools import reduce

    from operator import xor

    return [reduce(xor, x, 0) for x in zip(*t)]


def xor_string(t1, t2):

    t1 = map(ord, t1)

    t2 = map(ord, t2)

    return "".join(map(chr, xor(t1, t2)))


def is_printable(data):

    for i in data:

        if ord(i)<32 or ord(i)>127:

            return False

    return True


plaintext = """The Song of the Count


You know that I am called the Count

Because I really love to count

I could sit and count all day

Sometimes I get carried away

I count slowly, slowly, slowly getting faster

Once I've started counting it's really hard to stop

Faster, faster. It is so exciting!

I could count forever, count until I drop

1! 2! 3! 4!

1-2-3-4, 1-2-3-4,

1-2, i love couning whatever the ammount haha!

1-2-3-4, heyyayayay heyayayay that's the sound of the count

I count the spiders on the wall...

I count the cobwebs in the hall...

I count the candles on the shelf...

When I'm alone, I count myself!

I count slowly, slowly, slowly getting faster

Once I've started counting it's really hard to stop

Faster, faster. It is so exciting!

I could count forever, count until I drop

1! 2! 3! 4!

1-2-3-4, 1-2-3-4, 1,

2 I love counting whatever the

ammount! 1-2-3-4 heyayayay heayayay 1-2-3-4

That's the song of the Count!

"""


output = "9d5c66e65fae92af9c8a55d9d3bf640e8a5b76a878cbf691d3901392c9b8760ebd5c62b22c88dca9d1c55098cbbb644ae9406ba32c8293bdd29139bbc2b4605bba51238f2cb399a9d0894ad9cbb8774be9406ce66fae89a6c8ef7ad9c4b87442ad1470af78e19da6d8c55096d2b9750ea8586fe668a085c2ef8a5e9cd3be6c4bba144ae66ba488e8df84418bceb2650ea84362bf0688dcabd3905d8d87a46d414626be04a58215b84263a620de3203fa4626be08e2940da35c61b82c98201ce15438cd67eb921cf77c28a969de321bf4433ea24ca59216a25b7bb662996106e11639e75ae09015bb4c2fb76d8c254fe15e6ab45cea817391547cab698c6d4ff35039b34df7df599e412fb67fde3200b55432a441f19817b01405962c9d2e1af9556aa447f09f0df75360ad6988241db91129a85deb8559a25b7bb660de084ff1cc3a0e8041bc71d71fb29883931d9d3e8f784ca743b065c91ea386909e1a9100925f4fa742b1718c1efec4d4d609df5bcb3b17e417bd268d5fe6ced4d65b9c40d6305eeb1df03e9050e68bcad241dd15b46453b85dae7cd112b2c3c7ca50dd4ddf2c1ff350f5349c5febcadbd2509c40d6340aad03bd258d5bb2d8cdc647d814d1335efe18f8718651e7c5d6b9609c57d12010fe50e939801ee1dbcbd74cce4739c1eeceba8ef87360b629ed82a6eb9d508ee381bb88e97363bf20a1cfe7a7e07cccf3cea788bd277fb265e9cde4a9b937808aa7ee85f22679a365f5c4ede5f478c0e482ab95bd3c79f731e9c9a8b6ff7cc2e6c0e0c897047fb22ba1e5afa8b778c2ef80abcabd1a37b42af4c2fce5fa60dde582a8c7971a37b42af4c2fce5e475c1f782b7cabd207bb832edd5a4e5e4130a976ad4a2fe86ac99c18491f9f6c86adae59cc4a9f33072f70ca6daede5e40b049272c8e6b980b798c69e9fb7f7891611c7758df0fc82b481d1ca9eb8e2cd5f118f26def6f693d2abc99982bce2855f038175d9e7ebcdf8a4dcca9faab0da1045857eceebed8ab68a89e0bff9f3c60a098426ceedec8daccdce8584bce6cc0d49c065c2f7f797f898c69e9fb5b0e05f019269dd88a8c2f8df89cac5f8b09d00ad16dc760ead7c3518baed47603c5b5251cc269cae93d1f8a4888699aff58942c8529f304af0362143f2bd1e37670d538753992129ff3c6c5befb21e7331590c950ac26917be39644dfba50b2b70117fcbccba57b209ae95721a1c9d36073d934b75014109102be14fb6a044a7cf9e468748976457f6342177f5a9042630622f97d2ba5a8c04a7890d4e5fcb445b7600d7c1be71b711b6b32b4444f078557ef82e4f0559225437b455aa9a0bbaff89c834531a45115125c933d6cd6cdca8f8".decode("hex")

chunks = chunk(pad(plaintext), 16)


keyStream_list = []

for i in range(0,len(chunks)-1):

    keyStream_list.append(strxor(chunks[i],output[i*16:(i*16)+16]).encode("hex"))


keyStream_list = list(set(keyStream_list))


for i in range(len(chunks)-1,len(output)/16):

    print "------------------------"

    for j in range(0,len(keyStream_list)):

        result = unpad(strxor(keyStream_list[j].decode("hex"), output[i * 16:(i * 16) + 16]))

        if is_printable(result):

            print result


'Crypto & Network & Etc > Crypto Practice' 카테고리의 다른 글

Codegate 2018 CTF Miro  (0) 2019.11.15
Prayan CTF 2019 Crypto Write up  (0) 2019.11.15
TAMUCTF 2019 Crypto Writeup  (0) 2019.11.15
Seccon CTF 2017 Ps and Qs  (0) 2019.11.12
TokyoWesterns CTF 2018 Revolutional Secure Angou  (0) 2019.11.12
블로그 이미지

JeonYoungSin

메모 기록용 공간

,

Decode This


문제에서 주어진 코드와 암호문은 다음과 같다.


암호문

vuqxyugfyzfjgoccjkxlqvguczymjhpmjkyzoilsxlwtmccclwizqbetwthkkvilkruufwuu


source.py

import random


file = open("secret.txt","r")

secret = file.read()


flag = ""

for i in secret:

    if i.isalpha():

        flag += i

l = len(flag)


key = [[int(random.random()*10000) for e in range(2)] for e in range(2)]

# [[7156, 9059], [9366, 2474]]


i = 0

ciphertext = ""


while i <= (l-2):

    x = ord(flag[i]) - 97

    y = ord(flag[i+1]) - 97

    z = (x*key[0][0] + y*key[0][1])%26 + 97

    w = (x*key[1][0] + y*key[1][1])%26 + 97

    ciphertext = ciphertext + chr(z) + chr(w)

    i = i+2


cipherfile = open('ciphertext.txt','w')

cipherfile.write(ciphertext)


암호화 과정에서 0~10000 범위의 랜덤 키 4가지가 사용된다.


간단히 생각하면 10000**4의 경우의 수를 브포해서 유의미한 문자열을 찾으면 될 것 같긴한데 범위가 크기도하고 이런걸 의도한 문제는 아닌 것 같아서 다른 방향으로 생각해봤다.


암호화 코드를 좀 더 보니 코드에 나온 수식이 아래와 같이 변경 가능했고 이를 통해 실질적으로 키 값의 범위가 0~10000가 아닌 0~26인 것을 알 수 있었다.


z = (x*key[0][0] + y*key[0][1])%26 + 97

z = ((x%26)*(key[0][0]%26))%26+((y%26)*(key[0][1]%26))%26+97


이를 통해 키 범위를 26**4=456976으로 줄일 수 있었고 추가로 문자열 복호화 시 플래그 포멧인 pctf 문자열을 생성하는 키들을 따로 추출해 복호화 하는식으로 키 범위를 더 줄여서 플래그를 구했다.


solve.py


def get_key(enc_flag):

    flag_format = "pctf"

    for j in range(0,26):

        for k in range(0,26):

                x = ord(flag_format[0]) - 97

                y = ord(flag_format[1]) - 97

                p = ord(flag_format[2]) - 97

                q = ord(flag_format[3]) - 97

                z = (x * j + y * k) % 26 + 97

                w = (x * j + y * k) % 26 + 97

                r = (p * j + q * k) % 26 + 97

                u = (p * j + q * k) % 26 + 97

                if z==ord(enc_flag[0]) and r==ord(enc_flag[2]):

                    k1=[j,k]

                if w==ord(enc_flag[1]) and u==ord(enc_flag[3]):

                    k2=[j,k]

    return [k1,k2]


def decrypt_flag(key,enc_flag):

    flag = ""


    for i in range(0, len(enc_flag), 2):

        for j in range(ord('a'), ord('z') + 1):

            for k in range(ord('a'), ord('z') + 1):

                x = j - 97

                y = k - 97

                z = (x * key[0][0] + y * key[0][1]) % 26 + 97

                w = (x * key[1][0] + y * key[1][1]) % 26 + 97

                if z == ord(enc_flag[i]) and w == ord(enc_flag[i + 1]):

                    flag += chr(j) + chr(k)

    if "pctf" in flag:

        print flag


enc_flag = "vuqxyugfyzfjgoccjkxlqvguczymjhpmjkyzoilsxlwtmccclwizqbetwthkkvilkruufwuu"

for i in range(0,len(enc_flag)-4,2):

    key = get_key(enc_flag[i:i+4])

    decrypt_flag(key,enc_flag)


result


pctfaqnrrfqhcscypuqthzmkxpesklxcpurfeubkqtrvekcyzwtrrrdprvzclxnbnlugduug

bkidyqgrkvbtmaigpctfybqggdkinztqpckvakbotfilyaigvsapchabilryepibklcibgci

utndygtvjbxesmoyidpctfagxbworgkbidjbmsevpchhkyoysrfbbzjhhhodlfvpxjkgkrkg

vxknqmedeldsyweunrpouduagfeypctfnrelggnppouxwseutjwjqhyluxzhezoryfosdfos

telpiepbtfyhoieqpcexrzwenfgsyrnspctfumboexbjcqeqpurfzvpjbjfcnzhxztoeluoe

ramhasalittlesecretforyourighthereitispctfilikeclimbinghillswhataboutyou

rsjxwczhlpsvausytecddxsujlyckrjytelpemdccdhraosypctfvxdjhrhgtddfhdygfiyg

bvdiawnmpgiloeowbxivxegqfqcgsrfdbxpgcmhfivpcciowtndspqvwpctfzcnqnukmvlkm

lkltouxfffuhmeosrayjzzwmjbssmjjoraffkopayjtzyiosnopvjhbrtzpctfjlvrkyhuky


위 결과 중 의미있는 문장이 딱 하나 나온다.


ramhasalittlesecretforyourighthereitispctfilikeclimbinghillswhataboutyou


Flag = pctf{ilikeclimbinghillswhataboutyou}



Easy RSA

주어진 정보는 아래와 같다.

e=217356749319385698521929657544628507680950813122965981036139317973675569442588326220293299168756490163223201593446006249622787212268918299733683908813777695992195006830244088685311059537057855442978678020950265617092637544349098729925492477391076560770615398034890984685084288600014953201593750327846808762513
n=413514550275673527863957027545525175432824699510881864021105557583918890022061739148026915990124447164572528944722263717357237476264481036272236727160588284145055425035045871562541038353702292714978768468806464985590036061328334595717970895975121788928626837881214128786266719801269965024179019247618967408217
c=337907824405966440030495671003069758278111764297629248609638912154235544001123799434176915113308593275372838266739188034566867280295804636556069233774555055521212823481663542294565892061947925909547184805760988117713501561339405677394457210062631040728412334490054091265643226842490973415231820626551757008360

e 값이 엄청 커서 위너 어택 코드를 돌려보면 개인키를 구할 수 있고 이걸로 그냥 복호화하면 된다.


solve.py


from gmpy2 import *

  

d = 12978409760901509356642421072925801006324287746872153539187221529835976408177


n = 413514550275673527863957027545525175432824699510881864021105557583918890022061739148026915990124447164572528944722263717357237476264481036272236727160588284145055425035045871562541038353702292714978768468806464985590036061328334595717970895975121788928626837881214128786266719801269965024179019247618967408217


c = 337907824405966440030495671003069758278111764297629248609638912154235544001123799434176915113308593275372838266739188034566867280295804636556069233774555055521212823481663542294565892061947925909547184805760988117713501561339405677394457210062631040728412334490054091265643226842490973415231820626551757008360


print("%x"%pow(c,d,n)).decode("hex")


Help Rabin


문제에서 주어진 정보는 다음과 같다.

- public pem file

- 암호문

- 암호화 시 사용한 코드


먼저 암호화 시 사용된 코드를 보면 다음과 같다.


encrypt.py


from Crypto.Util.number import *

import random


def nextPrime(prim):

    if isPrime(prim):

        return prim

    else:

        return nextPrime(prim+1)


p = getPrime(512)

q = nextPrime(p+1)

while p%4 != 3 or q%4 !=3:

    p = getPrime(512)

    q = nextPrime(p+1)


n = p*q

m = open('secret.txt').read()

m = bytes_to_long(m)


m = m**e

c = (m*m)%n

c = long_to_bytes(c)

c = c.encode('hex')


cipherfile = open('ciphertext.txt','w')

cipherfile.write(c)


암호화 코드를 보면 p,q 값이 거의 차이가 나지 않기 때문에 n 값만 알아도 p,q를 구할 수 있다. n 값은 pem 파일을 통해 확인했고, 추가로 조금 특이한게 암호화 코드를 잘 보면 결국 수행하는 행위가 c=(m**2)%n 이다. e가 2라는 건데 이런 경우에는 d가 생성이 안된다. rsa라고 생각했는데 rsa가 아닌거 같았고 e가 2인경우에 대해 찾아보니 rabin이라는 암호화가 존재하는 걸 알 수 있었다. 문제이름도 마침 rabin이었고 실제로 찾아보니 암호화 과정이 동일해서 해당 암호를 복호화하는 python 코드를 통해 플래그를 찾았다. 


solve.py


from Crypto.Util.number import *

from gmpy2 import *


def egcd(a, b):

    if a == 0:

        return b, 0, 1

    else:

        gcd, y, x = egcd(b % a, a)

        return gcd, x - (b // a) * y, y



# python RsaCtfTool.py --dumpkey --key pub.key

n = 68367741643352408657735068643514841659753216083862769094847066695306696933618090026602354837201210914348646470450259642887798188510482019698636160200778870456236361521880907328722252080005877088416283896813311117096542977573101128888124000494645965045855288082328139311932783360168599377647677632122110245577


p = isqrt(n)


while True:

    q, r = t_divmod(n, p)

    if r == 0:

        break

    p += 1


c = 0x4f741fe93dd7e383ff527caa9a2f27d27fd74b53b62123837b74a2b024d0fbbe052f3b330ce5208ba989fc68e2f5235ac4e9dd9e091e7cb80c02745d9b2aad10cab9431590ae63117ce539ebf747b4bc81f2a293aea52f0b1fee746158dc45d0c8d60769a8a8e671fb049b52669a010a1ca6f5de851d715bf1821d8771bbeb47


r = pow(c, long((p+1)/4), long(p))

s = pow(c, long((q+1)/4), long(q))


gcd, c, d = egcd(p, q)

x = (r * d * q + s * c * p) % n

y = (r * d * q - s * c * p) % n

plain_list = [x, n - x, y, n - y]


for plain in plain_list:

    flag = long_to_bytes(plain)

    print flag




'Crypto & Network & Etc > Crypto Practice' 카테고리의 다른 글

Codegate 2018 CTF Miro  (0) 2019.11.15
CONFidence CTF 2019 Count me in  (0) 2019.11.15
TAMUCTF 2019 Crypto Writeup  (0) 2019.11.15
Seccon CTF 2017 Ps and Qs  (0) 2019.11.12
TokyoWesterns CTF 2018 Revolutional Secure Angou  (0) 2019.11.12
블로그 이미지

JeonYoungSin

메모 기록용 공간

,

-.-

주어진 암호문은 다음과 같다.


dah-dah-dah-dah-dah dah-di-di-dah di-di-di-di-dit dah-dah-di-di-dit dah-dah-di-di-dit dah-dah-dah-dah-dah di-di-dah-dah-dah di-dah dah-di-di-di-dit dah-di-dah-dit di-di-di-di-dit dah-dah-dah-di-dit dah-dah-di-di-dit di-di-di-di-dah di-di-di-di-dah dah-dah-di-di-dit di-di-di-di-dit di-dah-dah-dah-dah di-di-di-dah-dah dah-dah-dah-di-dit dah-di-di-di-dit di-di-di-di-dit di-di-di-dah-dah dah-dah-dah-di-dit dah-dah-di-di-dit di-dah-dah-dah-dah dah-di-di-di-dit dit dah-di-di-di-dit dah-di-dit di-di-di-di-dah dah-di-dit di-di-di-di-dit dah-dah-dah-dah-dit di-di-di-di-dit di-di-di-di-dit di-di-dah-dah-dah di-dah dah-dah-di-di-dit di-di-di-dah-dah dah-dah-di-di-dit dah-di-di-di-dit di-di-di-di-dah dah-di-di-di-dit di-di-di-di-dah dah-dah-dah-di-dit dah-di-di-di-dit dah-di-di-dit dah-di-di-di-dit di-dah di-di-di-di-dah dah-dah-dah-dah-dit dah-dah-di-di-dit di-di-di-di-dah di-di-dah-dah-dah di-dah di-di-di-di-dit di-di-dah-dah-dah di-di-di-di-dit di-dah-dah-dah-dah di-di-dah-dah-dah dah-di-di-di-dit di-di-di-di-dah di-dah dah-dah-di-di-dit dah-dah-dah-dah-dah di-di-di-di-dit di-dah dah-dah-di-di-dit dah-di-di-di-dit dah-di-di-di-dit di-dah dah-di-di-di-dit dah-di-dit di-di-dah-dah-dah di-dah-dah-dah-dah di-di-dah-dah-dah di-di-di-di-dit di-di-dah-dah-dah di-di-di-di-dit di-di-di-di-dah dah-di-di-dit di-di-di-di-dah di-di-di-di-dah dah-di-di-di-dit dah-di-di-dit dah-di-di-di-dit dah-di-di-di-dit dah-dah-di-di-dit dah-dah-dah-dah-dah di-di-dah-dah-dah di-di-di-dah-dah di-di-di-di-dit dit di-di-di-di-dah dit di-di-di-dah-dah dah-dah-dah-dah-dit dah-di-di-di-dit dah-di-di-di-dit dah-di-di-di-dit dah-di-di-dit di-di-di-dah-dah di-di-di-di-dah dah-di-di-di-dit di-di-di-di-dah di-di-di-di-dit di-di-di-di-dit di-di-di-dah-dah di-di-di-di-dah dah-di-di-di-dit dah-di-dah-dit di-di-di-di-dah di-di-dah-dah-dah di-di-di-dah-dah di-di-di-dah-dah dah-dah-di-di-dit di-di-dah-dah-dah di-di-di-di-dit di-di-di-di-dah dah-di-di-di-dit di-di-dah-dit di-di-di-di-dit di-di-di-di-dah di-di-di-dah-dah dah-dah-dah-dah-dah di-di-di-di-dit dah-dah-dah-dah-dah di-di-di-di-dit di-dah di-di-di-di-dit di-dah-dah-dah-dah dah-di-di-di-dit dah-di-dit di-di-di-di-dah di-di-di-dah-dah di-di-di-di-dit di-dah-dah-dah-dah di-di-di-di-dah di-di-di-di-dit di-di-di-di-dah dah-di-di-dit di-di-di-di-dit dah-dah-dah-dah-dit di-di-di-di-dah di-di-dah-dah-dah di-di-di-dah-dah di-di-di-di-dah di-di-di-di-dit di-dah di-di-di-di-dah dah-di-dit dah-dah-di-di-dit dah-di-di-di-dit di-di-dah-dah-dah di-dah di-di-dah-dah-dah di-dah-dah-dah-dah di-di-di-di-dah dah-di-di-di-dit dah-di-di-di-dit dah-di-di-dit di-di-di-dah-dah dah-dah-dah-di-dit dah-di-di-di-dit dah-di-dah-dit di-di-dah-dah-dah di-di-di-di-dit dah-di-di-di-dit di-di-dah-dah-dah dah-di-di-di-dit di-dah dah-dah-di-di-dit di-dah-dah-dah-dah dah-di-di-di-dit dah-di-dah-dit di-di-di-di-dit dah-dah-dah-dah-dah di-di-di-di-dah dah-di-dit dah-di-di-di-dit dah-di-di-di-dit di-di-di-di-dah dah-dah-dah-dah-dit di-di-di-di-dah dah-dah-di-di-dit dah-di-di-di-dit dah-di-dit dah-di-di-di-dit di-dah-dah-dah-dah di-di-dah-dah-dah di-di-di-di-dit di-di-dah-dah-dah di-di-di-di-dit di-di-di-di-dah dah-di-di-di-dit dah-dah-di-di-dit di-dah di-di-di-di-dah dah-dah-di-di-dit di-di-dah-dah-dah dah-dah-dah-dah-dah dah-di-di-di-dit dah-dah-di-di-dit dah-di-di-di-dit dah-dah-dah-dah-dit dah-di-di-di-dit dah-dah-di-di-dit dah-di-di-di-dit di-di-di-di-dit dah-di-di-di-dit dah-di-dit dah-dah-di-di-dit dah-di-di-dit di-di-di-di-dah di-di-di-dah-dah di-di-di-dah-dah di-dah-dah-dah-dah dah-di-di-di-dit dah-dah-dah-dah-dit dah-di-di-di-dit di-di-di-dah-dah di-di-di-di-dah dah-di-di-dit di-di-di-di-dit di-di-dah-dit dah-di-di-di-dit di-di-di-dah-dah dah-di-di-di-dit dah-di-dah-dit di-di-di-dah-dah di-dah-dah-dah-dah di-di-di-di-dah di-di-di-dah-dah di-di-di-di-dah dah-di-di-dit di-di-dah-dah-dah dah-di-dit dah-dah-di-di-dit dah-dah-dah-dah-dit di-di-di-dah-dah dah-dah-dah-dah-dah dah-dah-di-di-dit di-di-di-di-dit di-di-di-di-dit di-di-dah-dit dah-di-di-di-dit dah-dah-dah-di-dit di-di-di-dah-dah di-di-di-di-dah dah-dah-di-di-dit dah-di-di-di-dit di-di-di-dah-dah di-di-di-dah-dah di-di-di-di-dit di-di-dah-dit dah-di-di-di-dit dah-di-dit di-di-di-dah-dah di-di-di-di-dah di-di-di-di-dah dah-dah-dah-dah-dit di-di-di-dah-dah di-dah-dah-dah-dah dah-dah-di-di-dit dah-di-dit di-di-dah-dah-dah dah-dah-dah-dah-dah dah-dah-di-di-dit di-di-di-di-dit dah-dah-di-di-dit dah-di-di-di-dit di-di-di-dah-dah di-di-di-di-dah dah-dah-di-di-dit dah-di-di-di-dit dah-dah-di-di-dit di-dah di-di-di-di-dah dah-di-di-dit di-di-di-di-dit di-dah dah-dah-di-di-dit di-di-di-di-dah di-di-di-dah-dah di-di-di-di-dah dah-dah-di-di-dit dah-dah-dah-dah-dit dah-di-di-di-dit di-di-dah-dit dah-di-di-di-dit dah-di-dit dah-di-di-di-dit dah-dah-dah-dah-dit di-di-di-di-dah di-di-di-di-dah di-di-di-di-dit di-di-di-dah-dah dah-di-di-di-dit dah-dah-dah-di-dit di-di-di-di-dah dah-di-dah-dit dah-di-di-di-dit dah-di-dit di-di-di-dah-dah dah-dah-dah-di-dit di-di-di-di-dit di-dah-dah-dah-dah di-di-di-di-dah di-di-di-di-dit di-di-di-di-dah dah-di-di-di-dit dah-di-di-di-dit dit di-di-di-di-dit di-di-di-di-dit dah-dah-di-di-dit di-di-di-di-dah dah-dah-di-di-dit dah-dah-di-di-dit di-di-di-di-dah di-dah di-di-di-di-dah dah-dah-dah-dah-dah di-di-di-di-dah dit dah-dah-di-di-dit di-di-di-di-dit di-di-di-di-dah di-di-dah-dit di-di-di-di-dit dah-dah-dah-dah-dit dah-di-di-di-dit dah-di-di-di-dit di-di-di-di-dit dah-dah-dah-di-dit di-di-dah-dah-dah dah-di-di-di-dit di-di-di-dah-dah dah-dah-dah-di-dit dah-dah-di-di-dit di-di-di-di-dit di-di-di-di-dah dah-dah-dah-dah-dah di-di-di-di-dah dah-dah-di-di-dit dah-di-di-di-dit dit di-di-dah-dah-dah di-dah-dah-dah-dah di-di-di-dah-dah di-dah-dah-dah-dah di-di-dah-dah-dah di-di-di-di-dit di-di-di-di-dit di-di-di-di-dah dah-dah-di-di-dit di-dah-dah-dah-dah dah-dah-di-di-dit dah-di-di-di-dit di-di-di-dah-dah dah-dah-dah-dah-dah di-di-di-di-dit dah-di-di-di-dit dah-di-di-di-dit di-di-di-dah-dah di-di-di-di-dit di-di-dah-dah-dah dah-dah-di-di-dit di-dah di-di-di-di-dit dah-di-di-di-dit di-di-dah-dah-dah di-dah-dah-dah-dah dah-di-di-di-dit di-dah di-di-dah-dah-dah di-dah-dah-dah-dah dah-dah-di-di-dit dah-di-di-di-dit dah-dah-di-di-dit di-di-di-di-dit dah-dah-di-di-dit di-di-di-di-dit dah-dah-di-di-dit dah-dah-dah-dah-dah di-di-di-dah-dah dah-dah-dah-di-dit di-di-di-di-dah di-di-dah-dah-dah dah-di-di-di-dit di-dah dah-di-di-di-dit di-di-di-di-dah di-di-di-di-dah dit di-di-di-di-dah dah-dah-dah-dah-dit dah-dah-di-di-dit di-dah-dah-dah-dah di-di-di-di-dah di-di-di-di-dit di-di-di-dah-dah di-di-di-di-dit dah-dah-di-di-dit dah-dah-di-di-dit di-di-dah-dah-dah di-di-di-dah-dah di-di-dah-dah-dah di-di-di-di-dah di-di-dah-dah-dah di-di-di-di-dit di-di-di-di-dit dah-di-di-di-dit di-di-di-dah-dah di-di-di-di-dah di-di-di-di-dit di-di-di-di-dit di-di-di-di-dit di-dah di-di-di-di-dah di-di-dah-dit di-di-di-di-dit dah-dah-dah-dah-dit di-di-di-di-dit di-dah di-di-di-dah-dah di-di-dah-dah-dah dah-dah-di-di-dit di-dah di-di-di-dah-dah dah-dah-di-di-dit di-di-di-di-dit di-di-di-di-dah di-di-di-dah-dah di-di-dah-dah-dah di-di-di-dah-dah di-di-di-di-dit dah-dah-di-di-dit di-di-di-di-dah di-di-di-dah-dah dah-dah-di-di-dit di-di-dah-dah-dah dah-di-di-di-dit dah-dah-di-di-dit dah-dah-dah-di-dit di-di-di-di-dah dah-di-dah-dit di-di-di-di-dah dah-dah-dah-dah-dah di-di-di-di-dit dah-dah-di-di-dit di-di-di-di-dah di-di-dah-dit di-di-di-dah-dah dah-dah-di-di-dit di-di-di-dah-dah di-di-di-di-dah di-di-di-dah-dah di-dah-dah-dah-dah di-di-di-dah-dah dah-dah-dah-dah-dah di-di-di-di-dit di-dah-dah-dah-dah di-di-di-di-dah dah-dah-dah-dah-dit


-,공백은 구분자이고 실질적으로는 di,dah,dit로 이루어져있다. 구성 요소가 3개라 3진수인가 싶었는데 아니었고, 문제이름이 딱봐도 morse code였는데 구성 요소가 3개라

아닌가 싶었다. 여기서 좀 헤매다 결국 morse code 같아서 morse code 테이블이랑 하나씩 비교하면서보니 di,dit를 그냥 둘다 .으로 치환해버리면 구조가 딱 들어맞는것 같길래 싹다 치환해서 온라인 디코더로 돌려보니 hex값이 나왔고 이거 디코딩하니 플래그가 나왔다.


solve.py


a = """dah-dah-dah-dah-dah dah-di-di-dah di-di-di-di-dit dah-dah-di-di-dit dah-dah-di-di-dit dah-dah-dah-dah-dah di-di-dah-dah-dah di-dah dah-di-di-di-dit dah-di-dah-dit di-di-di-di-dit dah-dah-dah-di-dit dah-dah-di-di-dit di-di-di-di-dah di-di-di-di-dah dah-dah-di-di-dit di-di-di-di-dit di-dah-dah-dah-dah di-di-di-dah-dah dah-dah-dah-di-dit dah-di-di-di-dit di-di-di-di-dit di-di-di-dah-dah dah-dah-dah-di-dit dah-dah-di-di-dit di-dah-dah-dah-dah dah-di-di-di-dit dit dah-di-di-di-dit dah-di-dit di-di-di-di-dah dah-di-dit di-di-di-di-dit dah-dah-dah-dah-dit di-di-di-di-dit di-di-di-di-dit di-di-dah-dah-dah di-dah dah-dah-di-di-dit di-di-di-dah-dah dah-dah-di-di-dit dah-di-di-di-dit di-di-di-di-dah dah-di-di-di-dit di-di-di-di-dah dah-dah-dah-di-dit dah-di-di-di-dit dah-di-di-dit dah-di-di-di-dit di-dah di-di-di-di-dah dah-dah-dah-dah-dit dah-dah-di-di-dit di-di-di-di-dah di-di-dah-dah-dah di-dah di-di-di-di-dit di-di-dah-dah-dah di-di-di-di-dit di-dah-dah-dah-dah di-di-dah-dah-dah dah-di-di-di-dit di-di-di-di-dah di-dah dah-dah-di-di-dit dah-dah-dah-dah-dah di-di-di-di-dit di-dah dah-dah-di-di-dit dah-di-di-di-dit dah-di-di-di-dit di-dah dah-di-di-di-dit dah-di-dit di-di-dah-dah-dah di-dah-dah-dah-dah di-di-dah-dah-dah di-di-di-di-dit di-di-dah-dah-dah di-di-di-di-dit di-di-di-di-dah dah-di-di-dit di-di-di-di-dah di-di-di-di-dah dah-di-di-di-dit dah-di-di-dit dah-di-di-di-dit dah-di-di-di-dit dah-dah-di-di-dit dah-dah-dah-dah-dah di-di-dah-dah-dah di-di-di-dah-dah di-di-di-di-dit dit di-di-di-di-dah dit di-di-di-dah-dah dah-dah-dah-dah-dit dah-di-di-di-dit dah-di-di-di-dit dah-di-di-di-dit dah-di-di-dit di-di-di-dah-dah di-di-di-di-dah dah-di-di-di-dit di-di-di-di-dah di-di-di-di-dit di-di-di-di-dit di-di-di-dah-dah di-di-di-di-dah dah-di-di-di-dit dah-di-dah-dit di-di-di-di-dah di-di-dah-dah-dah di-di-di-dah-dah di-di-di-dah-dah dah-dah-di-di-dit di-di-dah-dah-dah di-di-di-di-dit di-di-di-di-dah dah-di-di-di-dit di-di-dah-dit di-di-di-di-dit di-di-di-di-dah di-di-di-dah-dah dah-dah-dah-dah-dah di-di-di-di-dit dah-dah-dah-dah-dah di-di-di-di-dit di-dah di-di-di-di-dit di-dah-dah-dah-dah dah-di-di-di-dit dah-di-dit di-di-di-di-dah di-di-di-dah-dah di-di-di-di-dit di-dah-dah-dah-dah di-di-di-di-dah di-di-di-di-dit di-di-di-di-dah dah-di-di-dit di-di-di-di-dit dah-dah-dah-dah-dit di-di-di-di-dah di-di-dah-dah-dah di-di-di-dah-dah di-di-di-di-dah di-di-di-di-dit di-dah di-di-di-di-dah dah-di-dit dah-dah-di-di-dit dah-di-di-di-dit di-di-dah-dah-dah di-dah di-di-dah-dah-dah di-dah-dah-dah-dah di-di-di-di-dah dah-di-di-di-dit dah-di-di-di-dit dah-di-di-dit di-di-di-dah-dah dah-dah-dah-di-dit dah-di-di-di-dit dah-di-dah-dit di-di-dah-dah-dah di-di-di-di-dit dah-di-di-di-dit di-di-dah-dah-dah dah-di-di-di-dit di-dah dah-dah-di-di-dit di-dah-dah-dah-dah dah-di-di-di-dit dah-di-dah-dit di-di-di-di-dit dah-dah-dah-dah-dah di-di-di-di-dah dah-di-dit dah-di-di-di-dit dah-di-di-di-dit di-di-di-di-dah dah-dah-dah-dah-dit di-di-di-di-dah dah-dah-di-di-dit dah-di-di-di-dit dah-di-dit dah-di-di-di-dit di-dah-dah-dah-dah di-di-dah-dah-dah di-di-di-di-dit di-di-dah-dah-dah di-di-di-di-dit di-di-di-di-dah dah-di-di-di-dit dah-dah-di-di-dit di-dah di-di-di-di-dah dah-dah-di-di-dit di-di-dah-dah-dah dah-dah-dah-dah-dah dah-di-di-di-dit dah-dah-di-di-dit dah-di-di-di-dit dah-dah-dah-dah-dit dah-di-di-di-dit dah-dah-di-di-dit dah-di-di-di-dit di-di-di-di-dit dah-di-di-di-dit dah-di-dit dah-dah-di-di-dit dah-di-di-dit di-di-di-di-dah di-di-di-dah-dah di-di-di-dah-dah di-dah-dah-dah-dah dah-di-di-di-dit dah-dah-dah-dah-dit dah-di-di-di-dit di-di-di-dah-dah di-di-di-di-dah dah-di-di-dit di-di-di-di-dit di-di-dah-dit dah-di-di-di-dit di-di-di-dah-dah dah-di-di-di-dit dah-di-dah-dit di-di-di-dah-dah di-dah-dah-dah-dah di-di-di-di-dah di-di-di-dah-dah di-di-di-di-dah dah-di-di-dit di-di-dah-dah-dah dah-di-dit dah-dah-di-di-dit dah-dah-dah-dah-dit di-di-di-dah-dah dah-dah-dah-dah-dah dah-dah-di-di-dit di-di-di-di-dit di-di-di-di-dit di-di-dah-dit dah-di-di-di-dit dah-dah-dah-di-dit di-di-di-dah-dah di-di-di-di-dah dah-dah-di-di-dit dah-di-di-di-dit di-di-di-dah-dah di-di-di-dah-dah di-di-di-di-dit di-di-dah-dit dah-di-di-di-dit dah-di-dit di-di-di-dah-dah di-di-di-di-dah di-di-di-di-dah dah-dah-dah-dah-dit di-di-di-dah-dah di-dah-dah-dah-dah dah-dah-di-di-dit dah-di-dit di-di-dah-dah-dah dah-dah-dah-dah-dah dah-dah-di-di-dit di-di-di-di-dit dah-dah-di-di-dit dah-di-di-di-dit di-di-di-dah-dah di-di-di-di-dah dah-dah-di-di-dit dah-di-di-di-dit dah-dah-di-di-dit di-dah di-di-di-di-dah dah-di-di-dit di-di-di-di-dit di-dah dah-dah-di-di-dit di-di-di-di-dah di-di-di-dah-dah di-di-di-di-dah dah-dah-di-di-dit dah-dah-dah-dah-dit dah-di-di-di-dit di-di-dah-dit dah-di-di-di-dit dah-di-dit dah-di-di-di-dit dah-dah-dah-dah-dit di-di-di-di-dah di-di-di-di-dah di-di-di-di-dit di-di-di-dah-dah dah-di-di-di-dit dah-dah-dah-di-dit di-di-di-di-dah dah-di-dah-dit dah-di-di-di-dit dah-di-dit di-di-di-dah-dah dah-dah-dah-di-dit di-di-di-di-dit di-dah-dah-dah-dah di-di-di-di-dah di-di-di-di-dit di-di-di-di-dah dah-di-di-di-dit dah-di-di-di-dit dit di-di-di-di-dit di-di-di-di-dit dah-dah-di-di-dit di-di-di-di-dah dah-dah-di-di-dit dah-dah-di-di-dit di-di-di-di-dah di-dah di-di-di-di-dah dah-dah-dah-dah-dah di-di-di-di-dah dit dah-dah-di-di-dit di-di-di-di-dit di-di-di-di-dah di-di-dah-dit di-di-di-di-dit dah-dah-dah-dah-dit dah-di-di-di-dit dah-di-di-di-dit di-di-di-di-dit dah-dah-dah-di-dit di-di-dah-dah-dah dah-di-di-di-dit di-di-di-dah-dah dah-dah-dah-di-dit dah-dah-di-di-dit di-di-di-di-dit di-di-di-di-dah dah-dah-dah-dah-dah di-di-di-di-dah dah-dah-di-di-dit dah-di-di-di-dit dit di-di-dah-dah-dah di-dah-dah-dah-dah di-di-di-dah-dah di-dah-dah-dah-dah di-di-dah-dah-dah di-di-di-di-dit di-di-di-di-dit di-di-di-di-dah dah-dah-di-di-dit di-dah-dah-dah-dah dah-dah-di-di-dit dah-di-di-di-dit di-di-di-dah-dah dah-dah-dah-dah-dah di-di-di-di-dit dah-di-di-di-dit dah-di-di-di-dit di-di-di-dah-dah di-di-di-di-dit di-di-dah-dah-dah dah-dah-di-di-dit di-dah di-di-di-di-dit dah-di-di-di-dit di-di-dah-dah-dah di-dah-dah-dah-dah dah-di-di-di-dit di-dah di-di-dah-dah-dah di-dah-dah-dah-dah dah-dah-di-di-dit dah-di-di-di-dit dah-dah-di-di-dit di-di-di-di-dit dah-dah-di-di-dit di-di-di-di-dit dah-dah-di-di-dit dah-dah-dah-dah-dah di-di-di-dah-dah dah-dah-dah-di-dit di-di-di-di-dah di-di-dah-dah-dah dah-di-di-di-dit di-dah dah-di-di-di-dit di-di-di-di-dah di-di-di-di-dah dit di-di-di-di-dah dah-dah-dah-dah-dit dah-dah-di-di-dit di-dah-dah-dah-dah di-di-di-di-dah di-di-di-di-dit di-di-di-dah-dah di-di-di-di-dit dah-dah-di-di-dit dah-dah-di-di-dit di-di-dah-dah-dah di-di-di-dah-dah di-di-dah-dah-dah di-di-di-di-dah di-di-dah-dah-dah di-di-di-di-dit di-di-di-di-dit dah-di-di-di-dit di-di-di-dah-dah di-di-di-di-dah di-di-di-di-dit di-di-di-di-dit di-di-di-di-dit di-dah di-di-di-di-dah di-di-dah-dit di-di-di-di-dit dah-dah-dah-dah-dit di-di-di-di-dit di-dah di-di-di-dah-dah di-di-dah-dah-dah dah-dah-di-di-dit di-dah di-di-di-dah-dah dah-dah-di-di-dit di-di-di-di-dit di-di-di-di-dah di-di-di-dah-dah di-di-dah-dah-dah di-di-di-dah-dah di-di-di-di-dit dah-dah-di-di-dit di-di-di-di-dah di-di-di-dah-dah dah-dah-di-di-dit di-di-dah-dah-dah dah-di-di-di-dit dah-dah-di-di-dit dah-dah-dah-di-dit di-di-di-di-dah dah-di-dah-dit di-di-di-di-dah dah-dah-dah-dah-dah di-di-di-di-dit dah-dah-di-di-dit di-di-di-di-dah di-di-dah-dit di-di-di-dah-dah dah-dah-di-di-dit di-di-di-dah-dah di-di-di-di-dah di-di-di-dah-dah di-dah-dah-dah-dah di-di-di-dah-dah dah-dah-dah-dah-dah di-di-di-di-dit di-dah-dah-dah-dah di-di-di-di-dah dah-dah-dah-dah-dit"""

a = a.replace("-","")

a = a.replace("dit",".")

a = a.replace("di",".")

a = a.replace("dah","-")

print a


print "57702a6c58744751386538716e6d4d59552a737646486b6a49742a5251264a705a766a6d2125254b446b6670235e4e39666b346455346c423372546f5430505a516d4351454b5942345a4d762a21466b386c25626a716c504d6649476d612525467a4720676967656d7b433169634b5f636c31434b2d7930755f683476335f6d3449317d20757634767a4b5a7434796f6d694453684c6d385145466e5574774a404e754f59665826387540476e213125547176305663527a56216a217675757038426a644e49714535772324255634555a4f595a327a37543235743726784c40574f373431305149".decode("hex")


RSAaaay


문제는 다음과 같다.


(2531257, 43)

p = 509

q = 4973

My super secret message: 906851 991083 1780304 2380434 438490 356019 921472 822283 817856 556932 2102538 2501908 2211404 991083 1562919 38268


n 값이 엄청 작아서 그냥 소인수 분해가 된다. 주어진 암호문을 공백으로 split한 뒤 각각 복호화 해보면 아래와 같은 값이 나온다.


103

105103

101109

12383

97118

97103

10195

83105

12095

70108

121105

110103

9584

105103

101114

115125


그냥 hex디코딩해보면 첫번째 값만 디코딩이 된다. 뭐지 하다 유심히 복호화된 값을 보니 아스키 값을 2개씩 이어붙인 것 같았고 이를 토대로 복호화 해보니 제대로 값이 나왔다.


solve.py


from gmpy2 import *

  

p = 509

q = 4973


phi = (p-1)*(q-1)


n = p*q


e = 43


d = invert(e,phi)



c = "906851 991083 1780304 2380434 438490 356019 921472 822283 817856 556932 2102538 2501908 2211404 991083 1562919 38268".split(" ")

flag = ""


for i in c:

        result = str(pow(int(i),d,n))

        if len(result)>3:

                if result[0]=="1":

                        flag += chr(int(result[0:3]))

                        flag += chr(int(result[3:]))

                else:

                        flag += chr(int(result[0:2]))

                        flag += chr(int(result[2:]))

        else:

                flag += chr(int(result))


print flag


smile

문제에서 준 암호문은 다음과 같다.


XUBdTFdScw5XCVRGTglJXEpMSFpOQE5AVVxJBRpLT10aYBpIVwlbCVZATl1WTBpaTkBOQFVcSQdH


base64 디코딩 해보면 이상한 값이 나오는데, 디코딩된 각 문자들이 모두 아스키 범위였다. 그래서 아스키범위로 카이사르 돌려봤는데 아니었고, 플래그 포멧이 gigem이라 해당 값으로 카이사르 키 같은게 있나 찾아봤는데 이것도 아니었다. 그래서 혹시하고 gigem이랑 xor를 돌려봤더니 58 41이 계속 반복되는걸 볼 수 있었다. 이걸 key로 해서 base64 디코딩된 값을 xor해보니 플래그가 나왔다.


solve.py


a = "XUBdTFdScw5XCVRGTglJXEpMSFpOQE5AVVxJBRpLT10aYBpIVwlbCVZATl1WTBpaTkBOQFVcSQdH"

a =  a.decode("base64")

key = ":)"

flag = ""

for i in range(0,len(a)):

    flag += chr(ord(a[i])^ord(key[i%2]))

print flag




블로그 이미지

JeonYoungSin

메모 기록용 공간

,