sweetchip's blog


2013년 11월 8일 오전 10시 @분 ~ 오후 4시 5분까지 POC 이벤트 홀에서 여성 해킹방어대회 본선이 진행 되었습니다.


저는 학교에 수능성적을 적으려 잠시 다녀오고 11시에 양재동으로 가는데 차가 막혀서 거의 12시약간 안되서부터 운영에 참가했었습니다.


그리고 제 문제는 대략 2시 이후에 공개되었엇는데, 공개가 되고 난 뒤 돌아다녀보니 많은 팀들이 닷넷 리버싱을 풀고 계셨습니다.


예선때 문제를 생각보다 잘 푸셧기 때문에[한번에 풀 수 있는 트릭을 잘 사용하신 팀이 상당히 많았음] 본선엔 약간 난이도를 올려 크랙미에서 키젠미로 내려고 하게 되었고,


예선때와 마찬가지로 손수 난독화를 진행해서 최종적으로 출제했었습니다.



F2EE31BCB5BD7DE78280E949877018AAF7F1C610




문제는 위와 같이 평문 메세지를 입력하면 암호화된 문자열을 출력시키는 방식입니다.


그리고 문제 원본은 압축파일이었고 문제 바이너리와 텍스트 메세지가 함께 들어있었습니다.


decrypt_message.txt


Sweet Secret Memo _ logger 0.1

Date : 10.26_23:44 [UTC 09:00]

Chicken's Message : 144 207 93 170 111 25 130 144 21 152 172 -3 113 164 -24 94 117 -25 173 106 77 169 119 15 135 127 9 111 123 -12 109 218 61 155 98 50 199 131 -2 168 205 75 169 164 24 139 116 95 127 113 71 102 141 -18 152 153 28 111 131 74 207 201 -21 174 155 74 138 164 -7 179 215 94 187 142 55 147 99 64 176 117 25 193 177 47 135 111 -5 108 137 -8 132 120

Egg's Message : 210 209 22 126 188 29 212 101 24 125 145 -22 180 134 -30 162 107 18 142 210 8 185 95 -23 221 123 54 183 180 39 103 145 57 141 181 56 141 138 -25 124 133


End of Log


문제의 주 목적은 위에 있는 정보를 활용하여 데이터를 복호화 시키는 것이었고, 두가지는 공통 조건이므로 한번 복호화 루틴을 만들면 똑같이 수행할 수 있습니다.


이 문제 역시도 예선때와 같이 문제속에 닷넷 디컴파일러를 다운받을 수 있는 링크가 주어졌습니다. [디자인은 재탕 ㅎㅎ]


디컴파일러로 디컴파일을 해보면 다음과 같습니다.


using System;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
namespace POWEROFXX_easy_reversing
{
public class Form1 : Form
{
public string d8jergu394r0nnsjd94jfs = "9pMaVs5DxiOPGe8JETXYmg3lbudro6Qk1WLKwyhfnS4Iv0ABtjUCc7RZz2NFHq";
public int njgcgcxdxxx6r = DateTime.Today.DayOfYear;
public int zfgvjnkji8y6ug9u9i = DateTime.Now.Hour;
public int cljbyt798ygdre5 = DateTime.Now.Minute;
public int zsawsrf6g0i98t6vllp = DateTime.Today.Month;
public int qexyg8j9u8thuhg = DateTime.Today.Day;
private IContainer components;
private Button button1;
private Panel panel1;
private Panel panel2;
private Label label3;
private TextBox textBox1;
private TextBox textBox2;
private Label label1;
private void textbox1_mouseclick(object sender, MouseEventArgs e)
{
}
public Form1()
{
this.InitializeComponent();
this.d8jergu394r0nnsjd94jfs = "KfeROdEILJs5W6D1m4XFtH7YbwgrUConPuqQBcSxT092zljv8yMAGhpZN3akVi";
this.d8jergu394r0nnsjd94jfs = "8vxekVPpYlsXDAujWoJEingTGf3mCh59LROt6cdUNMb41zH7Kr0yS2BIFZqawQ";
}
public string ldfogndkfvisgi490rjgdijgw434ref(string a)
{
StringBuilder stringBuilder = new StringBuilder();
int num = this.zsawsrf6g0i98t6vllp;
char[] array = a.ToCharArray();
for (int i = 0; i < a.Length; i )
{
stringBuilder.Append((int)(this.d8jergu394r0nnsjd94jfs[i num] ^ array[i]) " ");
}
return stringBuilder.ToString();
}
public int kfig9jepoingndkfvndjroger(string chr, int range)
{
int num = int.Parse(chr);
int num2 = range % 3;
int num3 = 2;
if (num2 == 0)
{
num = this.qexyg8j9u8thuhg * num3 this.cljbyt798ygdre5 * num3 - this.zfgvjnkji8y6ug9u9i * 2;
}
else
{
if (num2 == 1)
{
num = this.zsawsrf6g0i98t6vllp * 3 this.cljbyt798ygdre5 * 2 - this.zfgvjnkji8y6ug9u9i * num2;
}
else
{
if (num2 == 2)
{
num = this.njgcgcxdxxx6r - this.zsawsrf6g0i98t6vllp * (num2 * 5) - this.cljbyt798ygdre5 * num2 - this.zfgvjnkji8y6ug9u9i * (num3 4) - num2 * num3;
}
}
}
return num;
}
public void lfkfidngigiwhiu3yr89igorg(string str)
{
string text = "Sweet Secret Memo _ lfkfidngigiwhiu3yr89igorg 0.1\r\n";
object obj = text;
text = string.Concat(new object[]
{
obj,
"Date : ",
this.zsawsrf6g0i98t6vllp,
".",
this.qexyg8j9u8thuhg,
"_",
this.zfgvjnkji8y6ug9u9i,
":",
this.cljbyt798ygdre5,
" [UTC 09:00]\r\n"
});
text = text "Your Message : " str "\r\n\r\n";
text = "End of Log";
StreamWriter streamWriter = new StreamWriter("savelog.txt");
streamWriter.Write(text);
streamWriter.Close();
}
public void gettime()
{
this.njgcgcxdxxx6r = DateTime.Today.DayOfYear;
this.cljbyt798ygdre5 = DateTime.Now.Minute;
this.zsawsrf6g0i98t6vllp = DateTime.Today.Month;
this.qexyg8j9u8thuhg = DateTime.Today.Day;
this.zfgvjnkji8y6ug9u9i = DateTime.Now.Hour;
}
public static string ncfjgirerg430t34trdgdfs(string input)
{
int length = input.Length;
char[] array = new char[length];
for (int i = 0; i < input.Length; i )
{
array[i] = input[length - i - 1];
}
return new string(array);
}
private void Form1_Load(object sender, EventArgs e)
{
this.panel2.BackColor = Color.Transparent;
this.d8jergu394r0nnsjd94jfs = "Hv8VzYa5b1FMGNODW4kwX9L3hK6SqsTtyxoE0Z7fPJIgrCAQiljBuenRcp2dUm";
this.d8jergu394r0nnsjd94jfs = "fgnCw4HPJRdXKIq31YNDZMS82OjA7eUxpozasVmykiQrTFLW6htGb9B0lEcvu5";
this.d8jergu394r0nnsjd94jfs = "jxLaZdWYngAfKGNhzTcXQU7Jy9sFbp0eRI1ECrv23PSw846oH5MBVtlDiOqumk";
this.d8jergu394r0nnsjd94jfs = "U0tnl9bVK4iB2LzZXy7PaCHcAI5pOsSfjgqkr1vuRTFEo8Dxmhw3QGdeJM6WYN";
this.d8jergu394r0nnsjd94jfs = "gWYN9w4LuPjxJl1MhOkniQy8CBUXr6THaKDctEdb0Imp32VfFZGvAS5ezqsR7o";
this.d8jergu394r0nnsjd94jfs = "wj3J9fL8QY2kArXKgOEzmSdqHpcMsn1ahGWxCe7yPIlTuDRb6F40oZtiUBvV5N";
}
private void panel_doubleclick(object sender, MouseEventArgs e)
{
MessageBox.Show("aHR0cDovL2lsc3B5Lm5ldC8=", "__BASE64__");
}
public string h8r9gu4inheiprhgnncvjousdfgiuweg(string str)
{
StringBuilder stringBuilder = new StringBuilder();
string text = this.ldfogndkfvisgi490rjgdijgw434ref(Form1.ncfjgirerg430t34trdgdfs(str));
string[] array = text.Split(new char[]
{
' '
});
for (int i = 0; i < array.Length - 1; i )
{
stringBuilder.Append(this.kfig9jepoingndkfvndjroger(array[i], i) " ");
}
return stringBuilder.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
if (this.textBox2.Text.Length > this.d8jergu394r0nnsjd94jfs.Length - this.zsawsrf6g0i98t6vllp)
{
MessageBox.Show("Length Error", "ERROR_bb");
return;
}
this.gettime();
string text = this.h8r9gu4inheiprhgnncvjousdfgiuweg(this.textBox2.Text);
this.textBox1.Text = text;
this.lfkfidngigiwhiu3yr89igorg(text);
}
private void textBox2_MouseClick(object sender, MouseEventArgs e)
{
if (this.textBox2.Text == "Input Your Plain Text")
{
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.textBox2 = new TextBox();
this.label3 = new Label();
this.textBox1 = new TextBox();
this.panel2 = new Panel();
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(508, 69);
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);
this.panel1.BackColor = SystemColors.ActiveCaptionText;
this.panel1.Controls.Add(this.label1);
this.panel1.Controls.Add(this.textBox2);
this.panel1.Controls.Add(this.label3);
this.panel1.Controls.Add(this.textBox1);
this.panel1.Controls.Add(this.button1);
this.panel1.Location = new Point(0, 269);
this.panel1.Name = "panel1";
this.panel1.Size = new Size(597, 99);
this.panel1.TabIndex = 11;
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, 25);
this.textBox2.Name = "textBox2";
this.textBox2.Size = new Size(491, 23);
this.textBox2.TabIndex = 17;
this.textBox2.Text = "Input Your Plain Text";
this.textBox2.MouseClick = new MouseEventHandler(this.textBox2_MouseClick);
this.label3.AutoSize = true;
this.label3.Font = new Font("맑은 고딕", 9.75f, FontStyle.Regular, GraphicsUnit.Point, 129);
this.label3.ForeColor = Color.FromArgb(192, 192, 255);
this.label3.Location = new Point(9, 51);
this.label3.Name = "label3";
this.label3.Size = new Size(112, 17);
this.label3.TabIndex = 16;
this.label3.Text = "Crypted Message";
this.textBox1.BackColor = Color.Black;
this.textBox1.BorderStyle = BorderStyle.FixedSingle;
this.textBox1.Font = new Font("맑은 고딕", 9f, FontStyle.Bold, GraphicsUnit.Point, 129);
this.textBox1.ForeColor = SystemColors.GradientActiveCaption;
this.textBox1.Location = new Point(12, 69);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new Size(491, 23);
this.textBox1.TabIndex = 15;
this.textBox1.MouseClick = new MouseEventHandler(this.textbox1_mouseclick);
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.label1.AutoSize = true;
this.label1.Font = new Font("맑은 고딕", 9.75f, FontStyle.Regular, GraphicsUnit.Point, 129);
this.label1.ForeColor = Color.FromArgb(192, 192, 255);
this.label1.Location = new Point(9, 7);
this.label1.Name = "label1";
this.label1.Size = new Size(94, 17);
this.label1.TabIndex = 18;
this.label1.Text = "Plain Message";
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(596, 368);
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 2";
base.Load = new EventHandler(this.Form1_Load);
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
base.ResumeLayout(false);
}
}

}


상당히 스크롤 압박의 코드들인데, 이상한 함수명과 변수명을 보고 많은 분들이 멘붕을 느끼셨을걸로 예상되는데,


이를 다시 함수를 분석하고 변수의 초기값까지 추적하면서 함수명을 변경한다면 쉬운 코드로 변환이 가능합니다.


분석을 해보시면 알겠지만, 이 프로그램은 시간에 영향을 받습니다. 그래서 시간이 지날때마다 암호화 결과가 바뀌게 됩니다.


그것도 참고하면서 분석하면 되겠습니다.


우선 간단하게


public void gettime()
{
this.njgcgcxdxxx6r = DateTime.Today.DayOfYear; // day of year
this.cljbyt798ygdre5 = DateTime.Now.Minute; // minute
this.zsawsrf6g0i98t6vllp = DateTime.Today.Month; // month
this.qexyg8j9u8thuhg = DateTime.Today.Day; // day
this.zfgvjnkji8y6ug9u9i = DateTime.Now.Hour; // hour

}


위 코드는 이번 문제중 한부분입니다.


위와 같이 변수가 하는 일을 추적하면서 변수와 함수명을 바꿔갑니다.


public static string ncfjgirerg430t34trdgdfs(string input)
{
int length = input.Length;
char[] array = new char[length];
for (int i = 0; i < input.Length; i )
{
array[i] = input[length - i - 1];
}
return new string(array);

}


위 함수의 경우는 그대로 복사후에 붙여 넣고(약간 수정이 필요할수도 있겟으나.) 컴파일 해보면 문자열을 뒤집는 역할을 합니다.


public string ldfogndkfvisgi490rjgdijgw434ref(string a) // 첫번째 암호화 시작
{

StringBuilder stringBuilder = new StringBuilder();
int num = this.zsawsrf6g0i98t6vllp;
char[] array = a.ToCharArray();
for (int i = 0; i < a.Length; i )
{
stringBuilder.Append((int)(this.d8jergu394r0nnsjd94jfs[i num] ^ array[i]) " ");
}
return stringBuilder.ToString();
}


위는 문자열을 암호화 시키는 함수 2개중 1개입니다.


num에는 month의 값이 저장되고, 프로그램 초기화시 생성된 인코딩 테이블에서 값을 하나씩 가져오고 사용자가 입력한 문자열 한글자씩 xor연산을 합니다.


private void button1_Click(object sender, EventArgs e) // 인코딩 버튼 클릭시 루틴
{
if (this.textBox2.Text.Length > this.d8jergu394r0nnsjd94jfs.Length - this.zsawsrf6g0i98t6vllp) // 글자수 검사 [에러 방지]
{
MessageBox.Show("Length Error", "ERROR_bb");
return;
}
this.gettime(); // 시간정보 얻어옴
string text = this.h8r9gu4inheiprhgnncvjousdfgiuweg(this.textBox2.Text); // 암호화 시작
this.textBox1.Text = text;
this.lfkfidngigiwhiu3yr89igorg(text); // 암호화된 값들을 저장
}
public string h8r9gu4inheiprhgnncvjousdfgiuweg(string str) // 암호화 시작
{
StringBuilder stringBuilder = new StringBuilder();
string text = this.ldfogndkfvisgi490rjgdijgw434ref(Form1.ncfjgirerg430t34trdgdfs(str)); // 첫번째 암호화 시작 [윗 부분에 있음]
string[] array = text.Split(new char[] // 첫번쨰 암호화로 나온 결과물을 가공시킴
{
' '
});
for (int i = 0; i < array.Length - 1; i )
{
stringBuilder.Append(this.kfig9jepoingndkfvndjroger(array[i], i) " "); // 두번째 암호화 시작
}
return stringBuilder.ToString(); // 암호화된 결과를 리턴함.
}

public int kfig9jepoingndkfvndjroger(string chr, int range) // 두번째 암호화 시작
{
int num = int.Parse(chr);
int num2 = range % 3;
int num3 = 2;
if (num2 == 0)
{
num = this.qexyg8j9u8thuhg * num3 this.cljbyt798ygdre5 * num3 - this.zfgvjnkji8y6ug9u9i * 2;

}
else
{
if (num2 == 1)
{
num = this.zsawsrf6g0i98t6vllp * 3 this.cljbyt798ygdre5 * 2 - this.zfgvjnkji8y6ug9u9i * num2;
}
else
{
if (num2 == 2)
{
num = this.njgcgcxdxxx6r - this.zsawsrf6g0i98t6vllp * (num2 * 5) - this.cljbyt798ygdre5 * num2 - this.zfgvjnkji8y6ug9u9i * (num3 4) - num2 * num3;
}
}
}
return num;

}


분석은 대략 이런 순서로 진행되게 되는데, 총 2번 암호화가 진행됩니다.


첫번째 암호화는 바로 위에서 썻으니 이번엔 두번째 암호화를 분석할 차례입니다.


num2는 현재 암호화되는 글자인덱스의 경우마다 다른 암호화를 진행합니다.

0의 경우는 변수를 간단하게 만들면 num = ((day * i) (minute * i) - (hour * 2)) 와 같습니다.


이런식으로 분석을 하게 됩니다.


그러면 이제 복호화를 해야 하는데


Plain -> enc1 -> enc2 -> Crypted Message 로 암호화가 진행된다는것을 알게되었으니 다시


Crypted Message -> enc2_decrypt -> enc1_decrypt -> Plain 순서로 복호화 할 것입니다.


일단은 위에서 언급한대로 프로그램은 시간을 사용하기때문에 시간마다 암호화결과가 바뀌게 됩니다.


그러므로 문제에 주어진 시간을 활용하도록 합니다.


minute = 44

month = 10

day = 26

dayofyear = 299

hour = 23


그리고 두번째 암호화 함수를 복호화 시킬수 있는 함수를 제작합니다. [이 풀이에선 python script로 제작합니다]


def solve1(str, range):

test = int(str)


j = range % 3

i = 2


if(j==0):

test -= ((day * i) (minute * i) - (hour * 2))

elif(j==1):

test -= ((month * 3) (minute * 2 ) - (hour * j))

elif(j == 2):

test -= ((dayofyear - (month * (j * 5)) - (minute * j) - (hour * (i 4)) - (j* i)))

return test


그리고 첫번째 암호화 함수를 복호화 시킬 수 있는 함수를 제작합니다.


def solve2(input):

encoding_table = "9pMaVs5DxiOPGe8JETXYmg3lbudro6Qk1WLKwyhfnS4Iv0ABtjUCc7RZz2NFHq"

encoding_table = "KfeROdEILJs5W6D1m4XFtH7YbwgrUConPuqQBcSxT092zljv8yMAGhpZN3akVi"

encoding_table = "8vxekVPpYlsXDAujWoJEingTGf3mCh59LROt6cdUNMb41zH7Kr0yS2BIFZqawQ"

encoding_table = "Hv8VzYa5b1FMGNODW4kwX9L3hK6SqsTtyxoE0Z7fPJIgrCAQiljBuenRcp2dUm"

encoding_table = "fgnCw4HPJRdXKIq31YNDZMS82OjA7eUxpozasVmykiQrTFLW6htGb9B0lEcvu5"

encoding_table = "jxLaZdWYngAfKGNhzTcXQU7Jy9sFbp0eRI1ECrv23PSw846oH5MBVtlDiOqumk"

encoding_table = "U0tnl9bVK4iB2LzZXy7PaCHcAI5pOsSfjgqkr1vuRTFEo8Dxmhw3QGdeJM6WYN"

encoding_table = "gWYN9w4LuPjxJl1MhOkniQy8CBUXr6THaKDctEdb0Imp32VfFZGvAS5ezqsR7o"

encoding_table = "wj3J9fL8QY2kArXKgOEzmSdqHpcMsn1ahGWxCe7yPIlTuDRb6F40oZtiUBvV5="

d = 0

array = input.split(' ')

result = ""

for i in array:

if i == "":

break;

test = int(i)

result = str(test ^ ord(encoding_table[d 10]))

result = " "

d = 1

#str1 = (test ^ )

return result


그리고 나머지 필요한 구문을 삽입한뒤, 스크립트를 완성시킵니다.



# /usr/bin/python

# power of xx _ solver

# 2013 POC - Power Of XX - Binary Easy2.net Solver

# by sweetchip.


minute = 44

month = 10

day = 26

dayofyear = 299

hour = 23


def solve1(str, range):

test = int(str)


j = range % 3

i = 2


if(j==0):

test -= ((day * i) (minute * i) - (hour * 2))

elif(j==1):

test -= ((month * 3) (minute * 2 ) - (hour * j))

elif(j == 2):

test -= ((dayofyear - (month * (j * 5)) - (minute * j) - (hour * (i 4)) - (j* i)))

return test


def solve2(input):

encoding_table = "9pMaVs5DxiOPGe8JETXYmg3lbudro6Qk1WLKwyhfnS4Iv0ABtjUCc7RZz2NFHq"

encoding_table = "KfeROdEILJs5W6D1m4XFtH7YbwgrUConPuqQBcSxT092zljv8yMAGhpZN3akVi"

encoding_table = "8vxekVPpYlsXDAujWoJEingTGf3mCh59LROt6cdUNMb41zH7Kr0yS2BIFZqawQ"

encoding_table = "Hv8VzYa5b1FMGNODW4kwX9L3hK6SqsTtyxoE0Z7fPJIgrCAQiljBuenRcp2dUm"

encoding_table = "fgnCw4HPJRdXKIq31YNDZMS82OjA7eUxpozasVmykiQrTFLW6htGb9B0lEcvu5"

encoding_table = "jxLaZdWYngAfKGNhzTcXQU7Jy9sFbp0eRI1ECrv23PSw846oH5MBVtlDiOqumk"

encoding_table = "U0tnl9bVK4iB2LzZXy7PaCHcAI5pOsSfjgqkr1vuRTFEo8Dxmhw3QGdeJM6WYN"

encoding_table = "gWYN9w4LuPjxJl1MhOkniQy8CBUXr6THaKDctEdb0Imp32VfFZGvAS5ezqsR7o"

encoding_table = "wj3J9fL8QY2kArXKgOEzmSdqHpcMsn1ahGWxCe7yPIlTuDRb6F40oZtiUBvV5="

d = 0

array = input.split(' ')

result = ""

for i in array:

if i == "":

break;

test = int(i)

result = str(test ^ ord(encoding_table[d 10]))

result = " "

d = 1

#str1 = (test ^ )

return result


chicken = "144 207 93 170 111 25 130 144 21 152 172 -3 113 164 -24 94 117 -25 173 106 77 169 119 15 135 127 9 111 123 -12 109 218 61 155 98 50 199 131 -2 168 205 75 169 164 24 139 116 95 127 113 71 102 141 -18 152 153 28 111 131 74 207 201 -21 174 155 74 138 164 -7 179 215 94 187 142 55 147 99 64 176 117 25 193 177 47 135 111 -5 108 137 -8 132 120 "

# Chicken

chicken = "210 209 22 126 188 29 212 101 24 125 145 -22 180 134 -30 162 107 18 142 210 8 185 95 -23 221 123 54 183 180 39 103 145 57 141 181 56 141 138 -25 124 133 "

# Egg

chickenarr = chicken.split(' ')


solve1_result = ""

for i in range(0, len(chickenarr)-1):

solve1_result = str(solve1(chickenarr[i], i)) " "


print solve1_result


solve2_result = solve2(solve1_result)

l_result = ""

result = solve2_result.split(" ")

for i in result:

if i == '':

break

print int(i)

l_result = chr(int(i))


print l_result[::-1]


원본 python 스크립트 : http://pastebin.com/TWHRpbKP

C# 코드 버전 : http://pastebin.com/PDNjLn7f




Flag : md5(W3_10vE_Ch1cKen_FoR3veEr)



이번 POX가 생애 처음으로 해킹대회에 문제를 출제해보는 기회가 되었습니다.


그래서 문제에 조금 서툰 부분도 있엇고, 키젠미 문제엿으므로 조금더 일찍 공개했엇어야 햇는데 늦게 공개한것이 아쉬웠습니다


특히 거의 풀뻔한 팀이 나왓지만 끝에 아쉽게도 시간이 모자라서 못푼 팀도 있었습니다.


그리고 고심끝에 결정해서 이 문제의 힌트를 받기로 하신것 같은데 힌트도 제대로 주지 못해서 죄송했던 팀도 있엇고;;


아무튼 여러모로 배울점이 많았던 대회 운영이었습니다.


POX에 참가하신 팀들과 운영진분들 그리고 POC 운영진 분들 모두 고생많으셨습니다!

신고

Comment 22

  • 2013.11.10 22:04 수정 답글

    비밀댓글입니다

    • 2013.11.11 20:48 신고 수정

      요즘은 여성분들도 해킹대회등 활동을 하시는 분들이 점점 늘어나고 있는 추세입니다.
      아마 모두 인터넷과 책을 같이 겸해서 공부하신게 아닐까 하네요 ㅎㅎ..

  • 2013.11.11 18:45 수정 답글

    비밀댓글입니다

    • 2013.11.11 20:49 신고 수정

      안녕하세요.
      해당 프로그램은 더이상 개발을 진행하지 않을 것 입니다.
      프로그램의 원본 소스코드도 더이상 가지고 있지 않으며, 시간도 없기때문에 불가능 할것같습니다.
      감사합니다.

  • 아하
    2013.11.11 22:03 신고 수정 답글

    저도 공부를 해보려고 지식인 카페 이곳저곳 찾아봤는데
    마땅히 뭘 배울수 있는 사이트가없는거같은데 ..
    혹시 시스템해킹 리버싱 등 공부하기 괜찮은 카페 알고계신곳 있으신가요??

    • 2013.11.12 00:15 신고 수정

      카페보다는 사이트와 여러 블로그에 올려진 글들을 보면서 공부하시는 것을 추천합니다.
      워게임이나 그런것을 풀어보시면서 흥미를 돋우며 공부하시는 것도 좋은 방법 중 하나입니다.

  • 2013.11.12 00:48 수정 답글

    비밀댓글입니다

    • 2013.11.21 01:12 신고 수정

      원하는 자료를 검색하면 나오는 블로그들을 통해서 공부했습니다.

      각각 블로그마다 담겨잇는게 달라서.. 그냥 여러가지 봣네요

  • 2013.11.20 21:15 수정 답글

    비밀댓글입니다

    • 2013.11.21 01:12 신고 수정

      전 네이트온을 하지 않습니다. ㅠ-ㅠ

      궁금하신 것은 방명록으로 남겨주시길 바라겠습니다.

  • 2013.11.21 17:38 수정 답글

    비밀댓글입니다

    • 2013.11.21 17:44 신고 수정

      안녕하세요.

      원래 시험과목의 문제에 대해서는 비공개가 원칙이므로 자세하게는 알려드릴 수 없는점 양해 부탁드립니다.

      우선 정확하게는 네트워크, 운영체제, 프로그래밍입니다.

      어셈블리 관련하여 문제도 등장하기도 했구요. 여기까지만 알려드릴 수 있을것 같네요.

      프로젝트 발표는 지원자의 특기를 최대한 뽐내볼 수 있는 기회라고 하셨었습니다. 필수는 아니나 권장 사항이었습니다.

      리버싱, 포렌식을 잘하면 좋겟지만 못한다고 떨어지지는 않습니다.

      해킹대회도 마찬가지로 있으면 가산점일 뿐이지, 경력이 없다고 해서 떨어지는 것은 아닙니다.

      감사합니다.

  • 2013.11.24 03:26 수정 답글

    비밀댓글입니다

    • 2013.11.24 15:23 신고 수정

      언어는 c언어는 꼭 알아두고 가셔야 합니다. 다른 언어도 알아두면 좋구요.
      리눅스도 한개만 다룰줄 알아도 충분합니다.

  • 2013.11.26 16:49 수정 답글

    비밀댓글입니다

  • 2013.12.01 14:09 수정 답글

    비밀댓글입니다

    • 2013.12.01 20:33 신고 수정

      그 문제들은 시스템 해킹 관련 문제들입니다.
      한번쯤은 쉘코드를 직접 짜보는 것도 좋긴 하지만 주로 사람들은 이미 있는것을 사용하거나 메타스플로잇에서 만들어서 사용합니다.
      가끔씩은 ctf에 따라서 쉘코드가 적절하게 필요할때 만들어서 사용하기도 합니다.
      exploit 작성 방법 같은 경우에는 직접 문제를 풀어보면서 작성법을 배우셔야 합니다. 시스템 해킹이 처음에 진입 장벽이 높으니
      문제들을 많이 풀어보시기도 하셔야 하고 삽질도 많이 필요할겁니다.

  • 2013.12.03 13:24 수정 답글

    비밀댓글입니다

    • 2013.12.03 15:40 신고 수정

      문제에 대해선 자세히 말해드릴 수는 없으나 올해 필기 시험의 경우 그렇게 어렵지는 않았습니다. BOB도 역시 배우는 입장으로 들어가는 것이기 때문에 문제들 수준은 기본 지식을 확인하는 정도라고 생각하시면 되겠습니다. [내년은 모르겟네요 ^^;]
      그리고 계속 공부하시다가 내년에 지원하시면 좋은 결과가 있을것이라고 봅니다.
      또한 학력부분에서는 제가 평가하는 입장이 아니라서 어떻게 말을 해드릴수가 없을것 같네요. 다만, 제 '개인적인'의견으로는 학력 보다는 실력이 훨씬 중요시 된다는 것은 느끼고 있습니다. 또한 bob활동은 학교 성적과 전혀 관련이 없습니다.

      위는 현재 2기 생활을 하면서 느낀것들이니 참고만 해주시기 바랍니다. 내년엔 어떻게 바뀔지 몰라서 이거다 라고 말씀드리기 어렵네요.
      감사합니다.

  • 2014.01.07 15:32 수정 답글

    비밀댓글입니다

    • 2014.01.08 03:28 신고 수정

      전 이미 연구 팀이 있고 다른 팀도 이미 고려중이라 더 이상 팀에 속하기에는 어려울것 같습니다. :D 감사합니다.