2013년 10월 5일, 온라인으로 POC의 이벤트중 하나인 여성해킹방어대회 POWER OF XX가 진행되엇습니다.
그중 저는 간단한 리버싱 문제를 출제했었는데 일반 닷넷 크랙미 수준으로 출제 되었습니다.
닷넷 프로그램의 특징은 자바와 비슷하게 거의 완벽한 코드 복구가 가능하다는 것입니다.
일반 c / c 로 컴파일된 프로그램의 경우 IDA의 HexRay도 거의 완벽하게 복구해주지만, 일반적인 경우엔 어셈블리 코드를 보면서 직접 이해해야 합니다.
하지만 닷넷 문제의 경우 .net reflector 나 ilspy 라는 프로그램을 이용하여 거의 완벽하게 복구가 가능합니다. [이유는 검색~!]
이점을 이용하게 하기 위해 문제에 간단하게 Ilspy를 다운받을 수 있는 링크를 힌트로 줬고
너무 쉽게 풀리는것을 방지하기 위해 [이문제에선 거의 쓸모가 없엇죠..] 손수 난독화를 진행했습니다 [일반 툴은 잘 안먹히더군요]
하지만 이것도 소스 코드를 조금만 살펴본다면 금방 풀수 있습니다.
문제의 목적은 암호화 되어있는 문자열이 숨겨진 프로그램 안에서 키가 만들어지는 루틴을 찾아서 분석후, 키를 얻어 문자열을 복호화 시키는 문제입니다.
POX 본선 진출자 분들은 대부분 이 문제를 해결하셨던것 같습니다.
CDC8501BE6FEC4B2D1FCC7B80DD129FA
using System;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;
namespace POWEROFXX_easy_reversing
{
public class Form1 : Form
{
private int[] jkd9j349njw984nt0wner9g34j = new int[]
{
7,
6,
5,
8,
9,
4,
2,
3,
1,
0
};
public string odf03mfg03mn4__dsfij9834rosdf043 = "MXgLk4UD5zEOjTuYy5/7MaQzMNquAcJu6yEiLzi30Rb0lSlhr7orlyY4OtTWW7 TdAIPqsY oL/";
public int nnumbobeeerofowoooeneneee = 1;
private IContainer components;
private Button button1;
private Panel panel1;
private Label label2;
private TextBox textBox2;
private Panel panel2;
private Button button2;
private Button button3;
private Button button4;
private Button button5;
private Label label1;
public Form1()
{
this.InitializeComponent();
this.label1.BackColor = Color.Transparent;
this.jkd9j349njw984nt0wner9g34j[this.jkd9j349njw984nt0wner9g34j.Length - this.jkd9j349njw984nt0wner9g34j.Length] = 1;
this.odf03mfg03mn4__dsfij9834rosdf043 = "iVO7R3sopmA Z/CmoNdKAHIjwEJK wclV8ONGO83f0SlBfWwEYbaoVXru5zhBgy83HSPpNjb0IJOUhsUPmSC66ByUd";
this.odf03mfg03mn4__dsfij9834rosdf043 = "CJZMwRLg72IsofYYEV/I223lK2xqh11HFRzOqaZPp";
this.odf03mfg03mn4__dsfij9834rosdf043 = "C/FyWDhkRAXEccfn5v513iz Qs7WI=";
}
private void Form1_Load(object sender, EventArgs e)
{
this.panel2.BackColor = Color.Transparent;
this.jkd9j349njw984nt0wner9g34j[this.jkd9j349njw984nt0wner9g34j.Length - 2] = 7;
}
private void panel_doubleclick(object sender, MouseEventArgs e)
{
MessageBox.Show("aHR0cDovL2lsc3B5Lm5ldC8=", "__BASE64__");
}
private void button1_Click_1(object sender, EventArgs e)
{
string.Concat(new object[]
{
this.dfj4rfioksdfiop4ewjf9dsr34r()[0],
this.nnumbobeeerofowoooeneneee,
this.dfj4rfioksdfiop4ewjf9dsr34r()[4],
this.dfj4rfioksdfiop4ewjf9dsr34r()[this.dfj4rfioksdfiop4ewjf9dsr34r().Length - 1]
});
this.label1.Text = this.tpyrcde821SEA(this.odf03mfg03mn4__dsfij9834rosdf043, this.textBox2.Text);
}
public string[] dfj4rfioksdfiop4ewjf9dsr34r()
{
return new string[]
{
"3",
"E",
"I",
"G",
"A",
"4",
"B",
"E",
"P",
"0",
"6",
"G",
"a",
"7",
"o",
"5"
};
}
public string tpyrcde821SEA(string Input, string key)
{
string result;
try
{
RijndaelManaged rijndaelManaged = new RijndaelManaged();
byte[] array = Convert.FromBase64String(Input);
byte[] bytes = Encoding.ASCII.GetBytes(key.Length.ToString());
PasswordDeriveBytes passwordDeriveBytes = new PasswordDeriveBytes(key, bytes);
ICryptoTransform transform = rijndaelManaged.CreateDecryptor(passwordDeriveBytes.GetBytes(32), passwordDeriveBytes.GetBytes(16));
MemoryStream memoryStream = new MemoryStream(array);
CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Read);
byte[] array2 = new byte[array.Length];
int count = cryptoStream.Read(array2, 0, array2.Length);
memoryStream.Close();
cryptoStream.Close();
string @string = Encoding.Unicode.GetString(array2, 0, count);
result = @string;
}
catch
{
result = "Invalid k3y..";
}
return result;
}
public string tpyrcen821SEA(string Input, string key)
{
RijndaelManaged rijndaelManaged = new RijndaelManaged();
byte[] bytes = Encoding.Unicode.GetBytes(Input);
byte[] bytes2 = Encoding.ASCII.GetBytes(key.Length.ToString());
PasswordDeriveBytes passwordDeriveBytes = new PasswordDeriveBytes(key, bytes2);
ICryptoTransform transform = rijndaelManaged.CreateEncryptor(passwordDeriveBytes.GetBytes(32), passwordDeriveBytes.GetBytes(16));
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write);
cryptoStream.Write(bytes, 0, bytes.Length);
cryptoStream.FlushFinalBlock();
byte[] inArray = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
return Convert.ToBase64String(inArray);
}
private void button2_Click(object sender, EventArgs e)
{
}
public string jf9j39fjd9rjngsweetfub95f()
{
this.dfj4rfioksdfiop4ewjf9dsr34r();
int num = this.jkd9j349njw984nt0wner9g34j[2];
string arg = "-" this.dfj4rfioksdfiop4ewjf9dsr34r()[14];
string result = arg num;
for (int i = 0; i < this.jkd9j349njw984nt0wner9g34j.Length; i )
{
this.label2.ForeColor = Color.FromArgb(15, 15, 15);
num >>= this.jkd9j349njw984nt0wner9g34j[i];
num = this.jkd9j349njw984nt0wner9g34j[i];
num <<= this.jkd9j349njw984nt0wner9g34j[i];
}
return result;
}
private void button3_Click(object sender, EventArgs e)
{
byte b = 49;
string[] array = this.dfj4rfioksdfiop4ewjf9dsr34r();
int arg_1E_0 = 2;
string arg_1E_1 = array[14];
char c = (char)b;
string str = arg_1E_0 arg_1E_1 c.ToString();
str = this.dfj4rfioksdfiop4ewjf9dsr34r()[1];
byte b2 = 95;
char c2 = (char)b2;
string text = c2.ToString() "!" this.jkd9j349njw984nt0wner9g34j[this.jkd9j349njw984nt0wner9g34j.Length - 1];
text = this.jf9j39fjd9rjngsweetfub95f();
this.label2.Text = str text;
int arg_8C_0 = this.jkd9j349njw984nt0wner9g34j[6];
}
private void rm(object sender, MouseEventArgs e)
{
if (this.textBox2.Text == "Input Passw0rd!")
{
this.textBox2.Text = "";
}
}
protected override void Dispose(bool disposing)
{
if (disposing && this.components != null)
{
this.components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
ComponentResourceManager componentResourceManager = new ComponentResourceManager(typeof(Form1));
this.button1 = new Button();
this.panel1 = new Panel();
this.label2 = new Label();
this.textBox2 = new TextBox();
this.panel2 = new Panel();
this.button2 = new Button();
this.button3 = new Button();
this.button4 = new Button();
this.button5 = new Button();
this.label1 = new Label();
this.panel1.SuspendLayout();
base.SuspendLayout();
this.button1.BackColor = Color.CornflowerBlue;
this.button1.FlatStyle = FlatStyle.Popup;
this.button1.Font = new Font("맑은 고딕", 9f, FontStyle.Bold, GraphicsUnit.Point, 129);
this.button1.ForeColor = Color.Black;
this.button1.Location = new Point(509, 28);
this.button1.Name = "button1";
this.button1.Size = new Size(75, 23);
this.button1.TabIndex = 10;
this.button1.Text = "SUBM1T";
this.button1.UseVisualStyleBackColor = false;
this.button1.Click = new EventHandler(this.button1_Click_1);
this.panel1.BackColor = SystemColors.ActiveCaptionText;
this.panel1.Controls.Add(this.label2);
this.panel1.Controls.Add(this.textBox2);
this.panel1.Controls.Add(this.button1);
this.panel1.Location = new Point(0, 305);
this.panel1.Name = "panel1";
this.panel1.Size = new Size(597, 63);
this.panel1.TabIndex = 11;
this.label2.AutoSize = true;
this.label2.Font = new Font("맑은 고딕", 9.75f, FontStyle.Regular, GraphicsUnit.Point, 129);
this.label2.ForeColor = Color.FromArgb(192, 192, 255);
this.label2.Location = new Point(10, 8);
this.label2.Name = "label2";
this.label2.Size = new Size(76, 17);
this.label2.TabIndex = 14;
this.label2.Text = "SERIAL K3Y";
this.textBox2.BackColor = Color.Black;
this.textBox2.BorderStyle = BorderStyle.FixedSingle;
this.textBox2.Font = new Font("맑은 고딕", 9f, FontStyle.Bold, GraphicsUnit.Point, 129);
this.textBox2.ForeColor = SystemColors.GradientActiveCaption;
this.textBox2.Location = new Point(12, 28);
this.textBox2.Name = "textBox2";
this.textBox2.Size = new Size(491, 23);
this.textBox2.TabIndex = 13;
this.textBox2.Text = "Input Passw0rd!";
this.textBox2.MouseClick = new MouseEventHandler(this.rm);
this.panel2.Location = new Point(303, 12);
this.panel2.Name = "panel2";
this.panel2.Size = new Size(281, 140);
this.panel2.TabIndex = 15;
this.panel2.MouseDoubleClick = new MouseEventHandler(this.panel_doubleclick);
this.button2.BackColor = SystemColors.WindowText;
this.button2.FlatStyle = FlatStyle.Flat;
this.button2.Location = new Point(1126, 358);
this.button2.Name = "button2";
this.button2.Size = new Size(10, 10);
this.button2.TabIndex = 16;
this.button2.Text = "Z2V0a2V5";
this.button2.UseVisualStyleBackColor = false;
this.button2.Click = new EventHandler(this.button2_Click);
this.button3.BackColor = SystemColors.WindowText;
this.button3.FlatStyle = FlatStyle.Flat;
this.button3.Location = new Point(891, 186);
this.button3.Name = "button3";
this.button3.Size = new Size(10, 10);
this.button3.TabIndex = 17;
this.button3.Text = "y3kt3g";
this.button3.UseVisualStyleBackColor = false;
this.button3.Click = new EventHandler(this.button3_Click);
this.button4.BackColor = SystemColors.WindowText;
this.button4.FlatStyle = FlatStyle.Flat;
this.button4.Location = new Point(810, 177);
this.button4.Name = "button4";
this.button4.Size = new Size(10, 10);
this.button4.TabIndex = 18;
this.button4.Text = "Z2V0a2V5";
this.button4.UseVisualStyleBackColor = false;
this.button5.BackColor = SystemColors.WindowText;
this.button5.FlatStyle = FlatStyle.Flat;
this.button5.Location = new Point(891, 288);
this.button5.Name = "button5";
this.button5.Size = new Size(10, 10);
this.button5.TabIndex = 19;
this.button5.Text = "Z2V0a2V5";
this.button5.UseVisualStyleBackColor = false;
this.label1.AutoSize = true;
this.label1.ForeColor = SystemColors.ActiveCaption;
this.label1.Location = new Point(10, 9);
this.label1.Name = "label1";
this.label1.Size = new Size(158, 12);
this.label1.TabIndex = 15;
this.label1.Text = "Click 'HACK THE PALNET'";
base.AutoScaleDimensions = new SizeF(7f, 12f);
base.AutoScaleMode = AutoScaleMode.Font;
this.BackColor = SystemColors.Control;
this.BackgroundImage = (Image)componentResourceManager.GetObject("$this.BackgroundImage");
base.ClientSize = new Size(597, 368);
base.Controls.Add(this.label1);
base.Controls.Add(this.button5);
base.Controls.Add(this.button4);
base.Controls.Add(this.button3);
base.Controls.Add(this.button2);
base.Controls.Add(this.panel2);
base.Controls.Add(this.panel1);
this.ForeColor = SystemColors.ControlText;
base.FormBorderStyle = FormBorderStyle.FixedSingle;
base.Icon = (Icon)componentResourceManager.GetObject("$this.Icon");
base.MaximizeBox = false;
base.MinimizeBox = false;
base.Name = "Form1";
this.Text = "2013 POWER OF XX - Easy Reverse Engineering";
base.Load = new EventHandler(this.Form1_Load);
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
base.ResumeLayout(false);
base.PerformLayout();
}
}
}
위는 Ilspy로 디컴파일한 코드의 모습입니다.
이 곳에 한개의 힌트를 더 숨겨놨는데, button3 의 text를 보면 아래와 같이 되있습니다.
this.button3.Text = "y3kt3g";
그리고 button3의 이벤트 핸들러를 보면 button3_click 이란것을 알 수있는데, 핸들러를 따라가보면 키를 구하게 되는 루틴이 나와있습니다.
그 이벤트 핸들러의 부분을 object로 변수가 지정된 부분을 int와 string으로 각각 수정후 새로운 함수를 만듭니다.
public void func()
{
byte b = 49;
string[] array = this.dfj4rfioksdfiop4ewjf9dsr34r();
int arg_1E_0 = 2;
string arg_1E_1 = array[14];
char c = (char)b;
string str = arg_1E_0 arg_1E_1 c.ToString();
str = this.dfj4rfioksdfiop4ewjf9dsr34r()[1];
byte b2 = 95;
char c2 = (char)b2;
string text = c2.ToString() "!" this.jkd9j349njw984nt0wner9g34j[this.jkd9j349njw984nt0wner9g34j.Length - 1];
text = this.jf9j39fjd9rjngsweetfub95f();
this.label2.Text = str text;
int arg_8C_0 = this.jkd9j349njw984nt0wner9g34j[6];
MessageBox.Show(str text); // 2o1E_!0-o5 <-- Key
}
그리고 Form1_Load 이벤트 핸들러 맨 아래에 func(); 함수를 실행하도록 하면 키가 출력됩니다.
그리고 이 키를 입력하면 문구가 출력됩니다.
Flag : md5("chicken_and_peace")
많은 분들이 푸실수 있도록 간단하게 출제했던 문제였습니다 :D
2013 ETRI junior ctf level10 write up (0) | 2014.02.06 |
---|---|
2013 POC - POWER OF XX 여성 해킹방어대회 Easy2.Net Write-up (22) | 2013.11.09 |
2013 CSAW CTF Exploitation 300 [exploit] (0) | 2013.09.23 |
2013 CSAW CTF Exploitation 200 [exploit] (0) | 2013.09.23 |
2013 CSAW CTF Exploitation 100 [exploit] (0) | 2013.09.23 |