CTFlearn의 일흔여덟번째 문제
이번엔 포렌식 카테고리의 Medium 난이도 문제이다.
포렌식 문제지만 암호학이 살짝 섞여있는.. 그런 문제다.
문제 설명을 보면 플래그를 암호화 해놨는데,
누군가가 성공적으로 복호화 해갔다고 한다.
그때 당시의 heap dump 를 확보했는데
이걸로 플래그를 복구할 수 있냐고 물어본다.
문제에서 주어지는 것은 Decryptor.java 파일과 heapdump.hprof 파일 두개이다.
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Decryptor
{
public static final String FLAG = "S+kUZtaHEYpFpv2ixuTnqBdORNzsdVJrAxWznyOljEo=";
private static class Password
{
private byte[] passHash;
public Password(char[] pass) throws Exception
{
MessageDigest digest = MessageDigest.getInstance("SHA-256");
this.passHash = Arrays.copyOf(digest.digest(new String(pass).getBytes("UTF-8")), 16);
}
public byte[] encrypt(byte[] msg) throws Exception
{
SecretKeySpec spec = new SecretKeySpec(passHash, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, spec);
return cipher.doFinal(msg);
}
public byte[] decrypt(byte[] msg) throws Exception
{
SecretKeySpec spec = new SecretKeySpec(passHash, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, spec);
return cipher.doFinal(msg);
}
}
public static void main(String[] args) throws Exception
{
Password pass = new Password(System.console().readPassword("Enter password to decrypt flag: "));
System.out.println(new String(pass.decrypt(Base64.getDecoder().decode(FLAG.getBytes()))));
Thread.sleep(5000); //We did a heap dump right here.
}
}
우선 Decryptor.java 파일을 본다.
이건 플래그를 암호화할때 사용한 java 코드이다.
AES ECB 알고리즘을 사용해서 암호화했고,
암호화된 플래그 값은 S+kUZtaHEYpFpv2ixuTnqBdORNzsdVJrAxWznyOljEo= 이다.
이 값을 복호화 하려면
암호화할때 사용한 키값인 passHash 값을 알아내야 한다.
코드 맨 아래 main 함수를 보면
Thread.sleep(5000); 부분에서 heap dump 를 했다고 한다.
이 정보를 토대로 heapdump.hprof 파일을 분석해야 한다.
heapdump.hprof 파일은 말그대로 heap dump 파일이다.
java heap dump 파일을 분석하기 위해선
Eclipse Memory Analyzer 도구가 필요하다.
https://www.eclipse.org/mat/downloads.php
위 링크에서 다운로드 받을 수 있다.
도구를 실행시켜 주어진 heapdump.hprof 파일을 열어주면
이런 화면이 나온다.
화면 아래쪽에 있는 Dominator Tree 버튼을 눌러준다.
그럼 이런 화면이 나온다.
이 중에서 아까 봤던 main의 Thread 클래스를 찾아준다.
엔터를 눌러 세부내용을 보면
뭔가 암호화에 사용되었을것 같은 정보들이 보인다.
중간에 Password 라고 저장되어 있는 키값도 보인다.
하지만 저 값을 그대로 사용하면 안된다.
왼쪽에서 Attributes 를 보면
정확히 어떤 값이 들어있는지 보인다.
. 으로 표현되었던것은 인코딩이 안돼서 그런것이다.
양수도 있고 음수도 있고 섞여있는데
이 값들을 16진수로 표현해 줘야 한다.
계산기를 이용하면 쉽게 계산할 수 있다.
예를들어 byte[2] 에 들어있는 -34 의 경우
16진수로 표현하면 DE 가 된다.
그런식으로 password 의 16진수 값을 다 알아냈다면
CyberChef(https://gchq.github.io/CyberChef) 에서 복호화 해주면 된다.
먼저 암호문의 base64 인코딩을 풀어주고
AES Decrypt 레시피를 선택해서
key 값을 넣어주면
플래그를 확인할 수 있다.
'워게임 > CTFlearn' 카테고리의 다른 글
[CTFlearn] Adoni Assembler Chall - 프로그래밍 (62) | 2023.03.26 |
---|---|
[CTFlearn] XOR Is Friend Not Food - 암호학 (68) | 2023.03.10 |
[CTFlearn] My Friend John - MISC / John the Ripper (74) | 2023.03.06 |
[CTFlearn] RE_verseDIS - 리버싱 / IDA / Python (52) | 2023.03.03 |
[CTFlearn] Smiling ASCII - 포렌식 / HxD / PIL (58) | 2023.03.01 |