CTF/리버싱

[UMDCTF] Twilight Zone - 리버싱 / dnSpy

SecurityMan 2022. 5. 11. 11:00

 

리버싱 문제

 

생각보다 어려워서 시간을 많이 투자했다.

 

반응형

 

문제파일로 TwilightZone.exe 파일이 주어진다.

 

주어진 exe파일을 실행시키면 이렇게

 

느끼한 아저씨 사진과 함께 비밀번호를 입력하는 창이 뜬다.

 

 

비밀번호칸에 hello 라고 시험삼아 입력해봤는데

 

당연히 틀린 비밀번호기 때문에 Not happening! 이라는 알람창이 뜬다.

 

exe 파일이니 평소에 하던대로 

 

디스어셈블러인 IDA 프로그램으로 열어보았다.

 

그런데 평소와 다른 인터페이스가 나왔다.

 

.NET으로 개발하면 이런식으로 나온다고 한다.

 

 

Mystery라는 함수가 있어서 내용을 살펴보는데 뭔가 암호화시켜서 저장하고 있는듯 보였다.

 

아무래도 비밀번호를 내부에 암호화해서 저장하고 있는듯 하다.

 

IDA로 이리저리 보다 너무 가독성이 떨어져서 어떻게 해야하나 찾아보다가

 

dnSpy 라는 도구를 찾았다.

(https://github.com/dnSpy/dnSpy)

 

 

dnSpy 역시 IDA처럼 디버깅 도구이다.

 

처음 실행하면 이런 화면이 나온다.

 

 

File - Open 메뉴에서 주어진 TwilightZone.exe를 추가해준다.

 

그러면 왼쪽에 밑줄친 부분처럼 추가가 된다.

 

오른쪽에는 디버깅된 소스코드도 보인다.

 

 

이제 코드에서 암호화하는 부분을 찾아가본다.

 

TwilightZoneGUI - TwilightZoneGUI.exe - TwilightZoneGUI - Form1 - Button1_Cilck 으로 타고 들어가면 된다.

 

아무래도 사용자가 비밀번호를 입력하고, Verify 버튼을 누르면

 

입력한 내용을 암호화 하든, 저장된 암호문을 복호화 하든 해서 비교검증을 할 것이기 때문이다.

 

// TwilightZoneGUI.Form1
// Token: 0x06000015 RID: 21 RVA: 0x0000229C File Offset: 0x0000049C
private void Button1_Click(object sender, EventArgs e)
{
	string text = this.TextBox1.Text;
	string text2 = "mLxCKPYXjSMUcEKu";
	string wJgEefC1c0B0A6mx = "UxLYNz3PClbqZ1U6l18XlW7lhUB0HaZYt6gBp3hR6+xRNJsvlPA20lS6OeCaFCqN";
	DateTime t = new DateTime(621355968000000000L);
	DateTime t2 = new DateTime(637228512000000000L);
	DateTime now = DateTime.Now;
	if (DateTime.Compare(now, t) > 0 || DateTime.Compare(now, t2) < 0)
	{
		MessageBox.Show("Not happening!");
		base.Close();
		return;
	}
	string text3 = this.Mystery(wJgEefC1c0B0A6mx, text2);
	if (text.Equals(text2))
	{
		MessageBox.Show(text3);
		base.Close();
		return;
	}
	MessageBox.Show("Not happening!");
	base.Close();
}

 

전체 코드는 위와 같다.

 

조건문(if)이 두개 있는걸 볼 수 있는데

 

첫번째 조건문은 시간을 비교하고 있다.

 

 

먼저 Datetime t 부분에 브레이크포인트를 걸고 살펴본다.

 

해당 부분에 커서를 두고 f9를 누르면 저렇게 빨간 점이 생긴다.

 

그리고 나서 위에 있는 Start 버튼을 누르면 된다.

 

 

그럼 프로그램이 실행되고, 다시한번 비밀번호 입력창에 아무 값이나 입력한 뒤

 

verify 버튼을 누르면 브레이크 포인트가 걸린다.

 

우측 하단의 창에서는 각 변수들의 현재상태를 보여준다.

 

f10을 눌러 코드를 한칸 진행시켜 주면

 

아래쪽에 DateTime t 변수에 시간값이 들어가게 된다.

 

t 변수에 저장되는 값은 1970-01-01 오전 12시이다.

 

if (DateTime.Compare(now, t) > 0 || DateTime.Compare(now, t2) < 0)
	{
		MessageBox.Show("Not happening!");
		base.Close();
		return;
	}

 

아까 코드에서 이 부분을 살펴본다.

 

Compare 함수의 경우 t1이 t2보다 나중일 경우 양수를 반환한다.

 

현재시각이 당연히 1970(t) 보다 나중이기 때문에 양수가 반환되고,

 

양수가 반환되면 조건문 안으로 들어가 맨처음 봤던 Not happening! 이라는 메세지 박스를 띄우는 것이다.

 

일단 프로그램을 실행시키려면 저 부분부터 우회해야 된다.

 

 

코드에서 아무곳에나 마우스를 두고 우클릭 한뒤 Edit Method(C#) 을 선택해준다.

 

 

그러면 새로운 창이 하나 뜨는데

 

저 시간을 설정하고 비교하는 부분을 통채로 날려버리면 된다.

 

 

그리고 나서 우측 하단의 Compile 버튼을 눌러준다.

 

 

그리고 나서 변경사항을 저장해 줘야한다.

 

File - Save All 버튼으로 저장해주면 된다.

 

 

저장한 파일은 구분하기 쉽게 TwilightZone1.exe 라고 이름을 지정해줬다.

 

 

저장한 TwilightZone1.exe 를 다시 dnSpy로 열어서

 

TwilightZoneGUI - TwilightZoneGUI.exe - TwilightZoneGUI - Form1 - Button1_Cilck로 들어가준다.

 

Start 버튼을 누르기 전에

 

string text = this.TextBox1.Text;
string text2 = "mLxCKPYXjSMUcEKu";
string wJgEefC1c0B0A6mx = "UxLYNz3PClbqZ1U6l18XlW7lhUB0HaZYt6gBp3hR6+xRNJsvlPA20lS6OeCaFCqN";
string text3 = this.Mystery(wJgEefC1c0B0A6mx, text2);
if (text.Equals(text2))
	{
		MessageBox.Show(text3);
		base.Close();
        return;
	}

 

다시한번 코드를 살펴보면

 

사용자의 입력값을 text 변수에 넣고

 

text2와 wJgEeC1c0b0A6mx 변수에 인코딩된 문자열을 넣는다.

 

그리고 나서 Mystery 함수의 인자로 text2와 wJgEeC1c0b0A6mx를 주고,  그 결과를 text3에 담는다.

 

그다음 text와 text2가 같은지 조건문에서 비교하고,

 

맞으면 text3를 출력한다.

 

그럼 비밀번호 입력창에 text2에 저장된 mLxCKPYXjSMUcEKu를 입력해준다면?

 

 

Start 버튼을 누른 뒤에 실행된 프로그램의 Password 입력창에

 

mLxCKPYXjSMUcEKu라고 입력한뒤, Verify 버튼을 눌러준다.

 

 

그럼 플래그가 출력되는걸 볼 수 있다.

 

 

string text 부분에 f9를 눌러 브레이크 포인트를 걸고

 

f10으로 한줄씩 실행시키면서 text3에 저장된 플래그 값을 확인하는 방법도 있다.

반응형