picoCTF 2021 -Easy Peasy 쓰기-

설명



일회성 패드는 깨지지 않지만 플래그를 복구할 수 있습니까? (picoCTF{}로 래핑) nc mercury.picoctf.net 36981 otp.py

해결책




$ nc mercury.picoctf.net 36981
******************Welcome to our OTP implementation!******************
This is the encrypted flag!
5b1e564b6e415c0e394e0401384b08553a4e5c597b6d4a5c5a684d50013d6e4b

What data would you like to encrypt? picoCTF{abcdefg}
Here ya go!
41085d333b367227195b540f5033302f

What data would you like to encrypt?


암호화된 32바이트 플래그를 사용하며 입력 시 모든 문자를 암호화할 수 있음을 보여줍니다. 다음으로 첨부된 otp.py를 읽으십시오.


#!/usr/bin/python3 -u
import os.path

KEY_FILE = "key"
KEY_LEN = 50000
FLAG_FILE = "flag"


def startup(key_location):
    flag = open(FLAG_FILE).read()
    kf = open(KEY_FILE, "rb").read()

    start = key_location
    stop = key_location + len(flag)

    key = kf[start:stop]
    key_location = stop

    result = list(map(lambda p, k: "{:02x}".format(ord(p) ^ k), flag, key))
    print("This is the encrypted flag!\n{}\n".format("".join(result)))

    return key_location

def encrypt(key_location):
    ui = input("What data would you like to encrypt? ").rstrip()
    if len(ui) == 0 or len(ui) > KEY_LEN:
        return -1

    start = key_location
    stop = key_location + len(ui)

    kf = open(KEY_FILE, "rb").read()

    if stop >= KEY_LEN:
        stop = stop % KEY_LEN
        key = kf[start:] + kf[:stop]
    else:
        key = kf[start:stop]
    key_location = stop

    result = list(map(lambda p, k: "{:02x}".format(ord(p) ^ k), ui, key))

    print("Here ya go!\n{}\n".format("".join(result)))

    return key_location


print("******************Welcome to our OTP implementation!******************")
c = startup(0)
while c >= 0:
    c = encrypt(c)


지금까지 암호화된 플래그는 5541103a246e415e036c4c5f0e3d415a513e4a560050644859536b4f57003d4c이고 플래그 길이는 32바이트이며 키 길이는 소스 코드에서 50000바이트라는 것을 알고 있습니다. 소스 코드에서 키의 길이가 50000바이트임을 알 수 있습니다. 소스 코드의 "stop >= KEY_LEN"에서 키의 시작 위치가 50000을 초과하면 처음으로 돌아가는 것을 알 수 있습니다. 그런 다음 두 번째 "암호화할 데이터는 무엇입니까?"에서\x00의 32바이트를 보내면 xor에서 키를 볼 수 있습니다.


$ python3 -c "print('\x00'*(50000-32)+'\n'+'\x00'*32)" | nc mercury.picoctf.net 36981
31613e5c7862345c7839376b355557525c7863305c7862315c7864345c7831
345c7865345c7865365c7864335c7866335a7733375c786566525b5c783165
245c786639325c7866362f5c7863655c7837665c7861315c7863665c786432
5d525c7831317d355c786465555c7865365c7839665c7865637d5c7866345c
78633334605c7864395c7864345c786638555c7838655c786662645c786633
5c7864335c7861635c7862385c7861375c783831795c786363665c7839615c
7864615c786466785c7831375c7838335c786134735c7866667e5c7839646b
52405c786338695c7865625c7839665c7839335c7831372e5c7831375b5c78
61305c7830315c7861653b5c786231685c7861615c786235535c7866355c78
65667a5c7
.
.
.
What data would you like to encrypt? Here ya go!
6227295e455c7838375c7866375c7862355c786430635c7838665c7863365c78


Now all that is left is to xor the flag 5541103a246e415e036c4c5f0e3d415a513e4a560050644859536b4f57003d4c to the key 6227295e455c7838375c7866375c7862355c786430635c 7838665c7863365c78, the decryption is completed.



결론



일부 암호화에서는 문제를 해결하기 위해 주어진 소스 코드를 읽을 수 있어야 합니다. 이것은 Python 기술과 키를 사용하는 방법에 대한 아이디어가 필요한 좋은 질문입니다.

좋은 웹페이지 즐겨찾기