CTF

[Forensic] Baby_RSA writeup

name2965 2022. 5. 11. 18:39
728x90

 

 

이번 문제는 네트워크 포렌식 문제입니다.

 

문제파일을 보면 pcapng 파일과 txt파일이 주어집니다.

 

pcapng 파일은 패킷 파일일 것이고 txt파일은 열어보면

 

 

 

다음과 같이 RSA 암호화에 쓰인 n값과 e값이 있습니다.

이 값을 이용해서 포렌식을 통해 얻은 암호화된 데이터를 복호화할때 써야 할것입니다.

 

 

먼저 패킷을 열어보면

 

 

 

이렇게 되있습니다.

 

먼저 Conversations를 열어보면 

 

 

 

 

TCP, UDP 등이 보입니다. 먼저 TCP를 살펴보면

 

전부다 http 포트로 통신한것이므로, 그다지 수상한 패킷은 보이지 않습니다.

그다음으로 UDP를 살펴보면

 

 

 

이 부분에 수상한 패킷이 하나 보입니다. 이 패킷을 Follow Stream ... 해보면

 

 

 

 

다음과 같은 수상한 값이 나옵니다. 이 패킷 이외의 패킷에는 별다른 이상한점이 안보이므로 

이 패킷이 우리가 찾아야하는 암호화된 데이터라는것을 유추할수 있습니다.

 

이제 이 데이터를 복호화해야합니다.

 

그런데 이 Follow Stream 창을 조금더 키워보면

 

 

 

다음과 같이 데이터가 1줄씩 줄바꿈 되어있습니다. 그리고 데이터를 자세히보면

 

 

 

 

이렇게, 데이터가 중복되는 경우가 자주 보입니다. 이 말은, 한줄 한줄이 상대적으로 겹치기 쉬운 문자열이 암호화되어서 줄바꿈이 되어있다는 것으로 추측해볼수 있습니다. 그러므로 암호화된 데이터 한줄 한줄이 문자 인것입니다.

 

문자마다 줄바꿈이 되어있으므로 데이터를 구분하기 쉬워집니다. 이를 기반으로 복호화 코드를 짤수 있습니다.

 

 

주어진 데이터는 n, e, c 입니다. 이 데이터를 통해서 구현할수 있는 복호화 방법을 찾아보던중, 

n 값만을 이용해서 p,q값을 구할수 있는 사이트가 있어서 이 사이트를 이용해보면

factordb.com

 

factordb.com

 

factordb.com

 

 

 

 

다음과 같은 값을 얻을수 있습니다. 그러므로 이 값을 p와 q의 값으로 이용할것입니다.

 

 

 

 

위키백과를 참고해보면, 다음과 같은 방법으로 암호화된 메세지를 복호화 할수 있다고 나와있습니다.

 

그러므로 이 방법을 사용하려면 d 값을 알아야하는데, d 값은 파이썬의 gmpy2 모듈을 사용하면 쉽게 알아낼수 있습니다. 그러므로 파이썬으로 복호화 코드를 짜보겠습니다.

 

먼저, 암호화 데이터를 하나하나 가져와서 연산해야하는데, 양이 너무 많으므로

텍스트 파일에 데이터를 저장한뒤, 줄바꿈 문자로 데이터를 하나하나 구분해서 리스트에 저장하는 방식으로 데이터를 가져올 것입니다. 그렇게 하면 다음과 같이 코드가 구현됩니다.

 

 

import gmpy2

f = open("C:/.../enc.txt")

flag_list = f.read().split("\n")

 

 

먼저 gmpy2 모듈을 import 하고 만들어둔 enc.txt의 절대경로를 통해서 파일을 엽니다.

그리고 줄바꿈문자로 데이터를 구분해서 리스트에 저장합니다.

 

그다음으로는 지금까지 얻은 데이터로 복호화를 하는 코드를 작성할것입니다.

 

 

import gmpy2

f = open("C:/.../enc.txt")

flag_list = f.read().split("\n")

if __name__ == "__main__":
    n = 27606985387162255149739023449107931668458716142620601169954803000803329
    e = 65537
    p = 162259276829213363391578010288127
    q = 170141183460469231731687303715884105727
    phi = (p-1)*(q-1)
    d = gmpy2.invert(e , phi)
    for i in range(0, 42):
        c = flag_list[i]
        byte = bytearray.fromhex(c)
        print('%c' % pow(int(byte.decode()),d,n),end='')

 

 

최종 코드는 다음과 같습니다.

 

먼저 n,e,p,q 값을 입력한뒤, d의 값을 구하기 위한 n에대한 오일러 파이 함수를 구해야 합니다.

이 함수는

 

다음과같은 수식을 이용해서 정의 할수 있습니다. 그리고 d값은 gmpy2.invert 메서드를 이용해서 쉽게 구할수 있습니다.

 

그리고 마지막으로 리스트에 저장되있는 암호화 데이터를 하나하나 가져와서 먼저 문자열을 바이트 배열로 변환합니다.

변환한 바이트 배열은 byte.decode() 메서드를 사용해서 16진수를 ASCII 문자열로 변환시킵니다.

그다음에는 변환한 암호화 값을 int형으로 형변환한후, 위에서 설명했던 복호화 수식을 이용해서

데이터를 하나씩 복호화해서 출력시킵니다.

 

이렇게 하면, 다음과 같은 플래그값을 얻을수 있습니다.

 

 

728x90

'CTF' 카테고리의 다른 글

2023 TAMUctf write-up  (0) 2023.05.15
[2023 root access CTF] write-up  (3) 2023.05.02
[2023 FooBar CTF] Write-up  (0) 2023.03.14
2022 Hacking Land CTF write-up  (0) 2022.08.01
[Reversing] Baby_Keylogger  (0) 2022.07.09