WARGAME/made by me!

[ecs ctf] [리버싱 자체제작] WpfApp - writeup

lucykorea414 2024. 1. 24. 20:22
728x90

 

[문제 설명]

admin 계정을 탈취해서 플래그값을 찾기

 

[문제의 의도]

코드/어셈블리 패치를 통한 admin 계정 탈취

 

 


문제 풀이

실행시 다음과 같은 화면이 나타납니다.

 

 

 

 

여기서 어드민을 체크해볼까요?

 

 

어드민이 아니라면서 체크도 해제되고 아예 체크박스가 막혀버렸네요.

그럼 이 상태에서 Get Flag 버튼을 한번 눌러봅시다

 

 

 

 

어드민이 아니라면서 막네요.

그럼 다시 실행시키고 이번에는 아무것도 안 누른 상태로 플래그 버튼을 눌러보겠습니다.

 

 

 

 

동일하게 경고문이 뜨는군요 :)

 

 

그러면 이제 분석을 해봅시다.

 

분석에 앞서, 이 문제의 이름을 보면 WpfApp이라고 되어있습니다.

구글에 wpf 이라고 치면 다음과 같이 나옵니다

그럼 C#으로 만든 앱인걸 알 수 있습니다!

 

C# 같은 경우에는 분석을 할때 대중적으로 많이 쓰는 xdbg나 ida 를 써도 잘 안보입니다! C#의 특성 때문입니다.

따라서 C# 분석에 아주 특화가 되어있는 DotPeek를 사용하거나 ILSpy를 사용하면 정말~~~~~ 편리합니다.

저는 코드를 패치할 수 있는 ILSpy를 사용하도록 하겠습니다.

 

 

 

WpfApp.exe 를 화면으로 끌고 오면 위와 같이 코드를 다 볼 수 있습니다.

 

 

 

여기서 WpfApp의 구성은 위와 같고, 여기서 우리가 핵심으로 공략해야할 부분은 MainWindow 라는 코드 부분입니다!

더블클릭으로 열어줍니다.

 

 

 

이제 C# 코드가 정상적으로 보이네요 :)

저는 따로 난독화를 진행하지 않았기 때문에 아주 깔끔하게 보입니다.

 

전체 코드는 다음과 같습니다.

// WpfApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// WpfApp.MainWindow
using System;
using System.CodeDom.Compiler;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using WpfApp;

public class MainWindow : Window, IComponentConnector
{
	public enum State
	{
		admin,
		user
	}

	private State state = State.user;

	internal Button getFlagButton;

	internal CheckBox adminCheckBox;

	internal TextBox logTextBox;

	internal Image flagimage;

	private bool _contentLoaded;

	public MainWindow()
	{
		InitializeComponent();
	}

	private void adminCheckBox_Checked(object sender, RoutedEventArgs e)
	{
		if (state == State.admin)
		{
			TextBox textBox = logTextBox;
			textBox.Text = textBox.Text + Environment.NewLine + "you are admin :)";
			adminCheckBox.IsChecked = true;
			adminCheckBox.IsEnabled = false;
		}
		else
		{
			TextBox textBox2 = logTextBox;
			textBox2.Text = textBox2.Text + Environment.NewLine + "you are not admin!! only admin is allowed.";
			adminCheckBox.IsChecked = false;
			adminCheckBox.IsEnabled = false;
		}
	}

	private void getFlagButton_Click(object sender, RoutedEventArgs e)
	{
		if (state == State.admin && adminCheckBox.IsChecked == true)
		{
			TextBox textBox = logTextBox;
			textBox.Text = textBox.Text + Environment.NewLine + "Success!";
			flagimage.Visibility = Visibility.Visible;
		}
		else
		{
			TextBox textBox2 = logTextBox;
			textBox2.Text = textBox2.Text + Environment.NewLine + "only admin is allowed :p";
		}
	}

	[DebuggerNonUserCode]
	[GeneratedCode("PresentationBuildTasks", "7.0.10.0")]
	public void InitializeComponent()
	{
		if (!_contentLoaded)
		{
			_contentLoaded = true;
			Uri resourceLocator = new Uri("/WpfApp;component/mainwindow.xaml", UriKind.Relative);
			Application.LoadComponent(this, resourceLocator);
		}
	}

	[DebuggerNonUserCode]
	[GeneratedCode("PresentationBuildTasks", "7.0.10.0")]
	[EditorBrowsable(EditorBrowsableState.Never)]
	void IComponentConnector.Connect(int connectionId, object target)
	{
		switch (connectionId)
		{
		case 1:
			getFlagButton = (Button)target;
			getFlagButton.Click += getFlagButton_Click;
			break;
		case 2:
			adminCheckBox = (CheckBox)target;
			adminCheckBox.Checked += adminCheckBox_Checked;
			break;
		case 3:
			logTextBox = (TextBox)target;
			break;
		case 4:
			flagimage = (Image)target;
			break;
		default:
			_contentLoaded = true;
			break;
		}
	}
}

여기서 중요하게 봐야할것은 맨 위에 정의되어 있는 enum (열거형)인데요,

enum의 개념은 아래에서 다루었으니 한번 참고해보세요

2023.05.30 - [study/코딩] - [c# 개념] enum(열거형)

 

[c# 개념] enum(열거형)

1. enum 이란? 마이크로소프트 C# 가이드에 enum을 쳐보면 이런 정의가 나온다. enum(열거형)은 기본 정수 숫자 형식의 명명된 상수 집합에 의해 정의되는 값 형식이다. Microsoft .NET C# 가이드 응? 전혀

lucykorea414.tistory.com

어쨌든 이 enum에서 실행파일을 실행시 유저의 상태를 정의하는 부분인것 같습니다.

private State state = State.user;

state 라는 전역변수가 상태를 user의 상태로 저장하고 있네요.

이 부분에서 state를 admin으로 패치하면 어드민 권한을 탈취할 수 있을것으로 보입니다.

 

private State state = State.admin;

 

 

체크박스가 체크되었을 때 실행되는 이벤트:

private void adminCheckBox_Checked(object sender, RoutedEventArgs e)
	{
		if (state == State.admin)
		{
			TextBox textBox = logTextBox;
			textBox.Text = textBox.Text + Environment.NewLine + "you are admin :)";
			adminCheckBox.IsChecked = true;
			adminCheckBox.IsEnabled = false;
		}
		else
		{
			TextBox textBox2 = logTextBox;
			textBox2.Text = textBox2.Text + Environment.NewLine + "you are not admin!! only admin is allowed.";
			adminCheckBox.IsChecked = false;
			adminCheckBox.IsEnabled = false;
		}
	}

 

먼저 체크박스가 체크되었을 때 실행되는 이벤트입니다.

만약 state 가 admin 이라면 "you are admin :)" 이라는 문구가 나오고 체크박스가 체크됩니다.

만약 state 가 admin이 아니라면(즉, user) 우리가 봤던 "넌 어드민이 아니야!" 라는 경고문이 출력되고 체크박스가 해제되네요!

 

 

 

플래그 버튼을 눌렀을때의 이벤트:

private void getFlagButton_Click(object sender, RoutedEventArgs e)
	{
		if (state == State.admin && adminCheckBox.IsChecked == true)
		{
			TextBox textBox = logTextBox;
			textBox.Text = textBox.Text + Environment.NewLine + "Success!";
			flagimage.Visibility = Visibility.Visible;
		}
		else
		{
			TextBox textBox2 = logTextBox;
			textBox2.Text = textBox2.Text + Environment.NewLine + "only admin is allowed :p";
		}
	}

 

만약, state 가 admin이고 체크박스가 체크되어있다면 우리가 원했던 flagimage가 visible 하게 바뀌네요.

만약 그렇지 않다면 (즉, user이거나 체크박스가 체크되어있지 않다면) 우리가 봤던 경고문이 출력됩니다 :)

 

 

 

 

그러면 State를 admin으로 수정하고 패치해봅시다

 

 

맨 상위 폴더인 WpfApp을 우클릭 후 Save Code를 하여 원하는 위치에 프로젝트를 저장합니다.

 

 

ILSpy는 프로젝트 자체를 c# 솔루션으로 저장하는 것을 지원해주기 때문에 직접 코드를 수정하기에 용이합니다 ^^

 

그럼 저장된 코드를 열어 (Visual Code 2022 사용) 패치 후 실행해봅시다

 

 

 

 

이제 숨겨져있던 플래그이미지가 보이네요

 

굳 ~^^

728x90