TSCTF2015 Reverse Alice_and_Easense

前两天是第一届TSCTF初赛,很成功撒花~虽然出了几道题但是被秒不是那么开心/(ㄒoㄒ)/~~,拿专家学长和曹老师出的几道逆向学习一下,这题确实很有意思,所以写成writeup贴上来,专家学长和曹老师受我一拜~

首先来看一下简洁明快的界面~

拖到ida和Ollydbg里面,动态分析一下,在关键处下一些断点,找到程序的主逻辑,把地址放到ida里面查看代码。

大概的逻辑是,不停读取输入的字符,转换成小人的行走方向,然后让小人在迷宫里穿梭,最后找到"E"得到答案,答案是把所有的方向bit异或之后的值。当然不是那么简单就出来的啊,看了几个小时%>_<%还是太弱。

这个就是迷宫了~

下面是小人在走迷宫。

走出来界面是这样的~

把源码贴上来和反编译的代码比较下~为了提高速度,还是要多读读二进制啊,加密与解密之类的,加快速度把sqli和reverse搞定,渗透和pwn等着我呢~~

?


char __thiscall sub_401700(void *this, char *a2)

{

void *v2; // [email protected]

int file; // [email protected]

char *sum; // [email protected]

char *addroftext; // [email protected]

unsigned int v6; // [email protected]

signed int count; // [email protected]

int *addrlow2b; // [email protected]

int valow2b; // [email protected]

char sumv; // [email protected]

char result; // [email protected]

signed int v12; // [email protected]

struct AFX_MODULE_STATE *v13; // [email protected]

HBITMAP v14; // [email protected]

const CHAR *v15; // [sp-Ch] [bp-53Ch]@2

const CHAR *v16; // [sp-8h] [bp-538h]@2

char v17; // [sp+10h] [bp-520h]@1

char v18; // [sp+11h] [bp-51Fh]@1

……

char v33; // [sp+20h] [bp-510h]@1

char v34; // [sp+21h] [bp-50Fh]@22

unsigned int low; // [sp+24h] [bp-50Ch]@5

int v36; // [sp+28h] [bp-508h]@5

……

int v98; // [sp+120h] [bp-410h]@1

char Text[1024]; // [sp+124h] [bp-40Ch]@3

int v100; // [sp+52Ch] [bp-4h]@1

?

v2 = this;

v43 = dword_42D324;

v44 = dword_42D328;

……

v62 = dword_42D2E0;

v63 = dword_42D2C4;

v100 = 0;

v64 = dword_42D2C8;

v65 = dword_42D2CC;

v66 = dword_42D2D0;

v17 = 25;

v18 = ‘;

v19 = ‘;

v20 = ‘\x03‘;

v21 = -108;

v22 = -99;

v23 = 10;

v24 = 12;

v25 = 32;

v26 = 115;

v27 = 117;

v28 = 112;

v29 = -40;

v30 = -91;

v31 = -92;

v32 = -115;

v33 = -106;

v39 = dword_42D314;

v40 = dword_42D318;

……

v97 = dword_42D31C;

v98 = dword_42D320;

file = openfile(a2, (int)aRb);

if ( file )

{

bufinit((int)&v39);

Text[0] = getchar((FILE *)file);

sum = (char *)&v43 + 1;

if ( !(*(_BYTE *)(file + 0xC) & 0x10) )

{

addroftext = Text;

while ( 2 )

{

v6 = (unsigned __int8)*addroftext;

low = v6 >> 6; // 模4?

v36 = (signed int)(v6 >> 4) % 4; // 先模16再模4的余数

v6 = (signed int)v6 % 16; // 模16的余数

v37 = (signed int)v6 / 4; // 除4的整数

v38 = (signed int)v6 % 4; // 模4的余数

count = 0;

addrlow2b = (int *)&low;

do

{

valow2b = *addrlow2b;

*sum = ‘ ‘;

switch ( valow2b ) // 判断a0 a1

{

case 0: // 注意,这里是前进后退,别搞错了!

sum -= 16;

break;

case 1:

++sum;

break;

case 2:

sum += 16;

break;

case 3:

--sum;

break;

default:

break;

}

sumv = *sum;

if ( *sum == ‘W‘ )

{

v16 = aGiveMyAliceBac;

v15 = aEasenseAliceCa;

goto LABEL_19;

}

if ( sumv == ‘ ‘ )

{

v16 = Caption;

v15 = ::Text;

goto LABEL_19;

}

if ( sumv == ‘E‘ ) // v10需要等于69,构造第一个字符

{

v12 = 0;

do

{

*(&v17 + v12) ^= Text[v12];

++v12;

}

while ( v12 <= 16 );

v34 = 0;

v13 = AfxGetModuleState();

v14 = LoadBitmapA(*((HINSTANCE *)v13 + 2), (LPCSTR)0x87);

SendMessageA(*((HWND *)v2 + 45), 0xF7u, 0, (LPARAM)v14);

strcpy(Text, aEasenseIFinall);

strcat(Text, &v17);

strcat(Text, aAliceBnbnbnbnw);

sub_41A2CD(Text, aTryAnotherAlic, 0x41u);// 就是这!为什么还给一个another alicebob,混淆?

goto LABEL_23;

}

++count;

++addrlow2b; // 应该是连一起的,这里应该是下2个bit了

*sum = ‘A‘; // 这个地方用65有用吗,上面不是有改成32了?

}

while ( count <= 3 );

++addroftext;

*addroftext = getchar((FILE *)file);

if ( !(*(_BYTE *)(file + 12) & 16) )

continue;

break;

}

}

LABEL_23:

fclose((FILE *)file);

v100 = -1;

sub_41B968(&a2);

result = 1;

}

else

{

v16 = aCanNotFindAnyA;

v15 = aEasenseWhereIs;

LABEL_19:

sub_41A2CD(v15, v16, 0x11u);

v100 = -1;

sub_41B968(&a2);

result = 0;

}

return result;

}


bool CAliceAndBobDlg::Check_Serial(CString file_name)

{

????//1122 3322 2111 1222 3322 3322 1111 1001 1001 0000 0001 0111 2222 3322 2112 2332 2211

????//5a fa 95 6a fa fa 55 41 41 00 01 15 aa fa 96 be a5

????char flag[] = {0x19, 0x95, 0xF1, 0x03, 0x94, 0x9D, 0x0A, 0x0C, 0x20, 0x73, 0x75, 0x70, 0xD8, 0xA5, 0xA4, 0x8D, 0x96};

????

????char misc[15][16]={"WWWWWWWWWWWWWWW",

???????????????????? "WA WWWWWW W",

???????????????????? "WWW WWWWW WW W",

???????????????????? "W WWWWW WWW W",

???????????????????? "W WWWWWWW WWW W",

???????????????????? "W WWWWWWW W W",

???????????????????? "W WWW W WWW",

???????????????????? "WWWWW WWW W WWW",

???????????????????? "WWWWW WWW W W",

???????????????????? "WWW WW WWW W",

???????????????????? "WWW WWWW WW W",

???????????????????? "W WW WW WWW",

???????????????????? "W WWWW WWWW WWW",

???????????????????? "W WWWW EW",

???????????????????? "WWWWWWWWWWWWWWW"};

?

????FILE *file = fopen(file_name, "rb");

?

????if (file == NULL)

????{

????????MessageBox("Easense: Where is my dear \"Alice\"? o.O", "Can not find any \"Alice\" here...", MB_OKCANCEL | MB_ICONERROR);

????????return false;

????}

?

????change_to_love(misc);

?

????int ii=0;

????unsigned char a[1024];

????a[ii] = getc(file);

?

????char *p_check = &misc[1][1];

?

????int code[4];

????while (!feof(file))

????{

????????code[0] = (a[ii]/16) / 4;

????????code[1] = (a[ii]/16) % 4;

????????code[2] = (a[ii]%16) / 4;

????????code[3] = (a[ii]%16) % 4;

?

????????for (int k=0; k<=3; k++)

????????{

????????????*p_check = ‘ ‘;

????????????switch (code[k])

????????????{

????????????//0 for up

????????????//1 for right

????????????//2 for down

????????????//3 for left

????????????case 0:

????????????????p_check -= 16;

????????????????break;

?

????????????case 1:

????????????????p_check += 1;

????????????????break;

?

????????????case 2:

????????????????p_check += 16;

????????????????break;

?

????????????case 3:

????????????????p_check -= 1;

????????????????break;

?

????????????default:

????????????????break;

????????????}

????????????

????????????if (*p_check == ‘W‘)

????????????{

????????????????MessageBox("Easense: Alice can not pass the wall! O.o", "Give my Alice back...", MB_OKCANCEL | MB_ICONERROR);

????????????????return false;

????????????}

????????????else if (*p_check == ‘ ‘)

????????????{

????????????????MessageBox("Easense: Alice can not go back! O.O", "I want my Alice...", MB_OKCANCEL | MB_ICONERROR);

????????????????return false;

????????????}

????????????else if (*p_check == ‘E‘)

????????????{

????????????????for (int jj=0; jj<=16; jj++)

????????????????{

????????????????????flag[jj] ^= (char)a[jj];

????????????????}

????????????????flag[17] = ‘\0‘;

????????????????HBITMAP bmp;

????????????????bmp = LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(SUCCESS));

????????????????this->m_btn_easense.SetBitmap(bmp);

?

????????????????char buf[1024];

????????????????strcpy(buf, "Easense:\r\nI finally meet you! Alice! o(∩_∩)o \r\nI want to tell you that——TSCTF{");

????????????????strcat(buf, flag);

????????????????strcat(buf, "}\r\n\r\nAlice:\r\n…………WTF?\r\nI just want my Bob! QAQ");

?

????????????????MessageBox(buf, "Try another Alice and Bob!", MB_OKCANCEL | MB_ICONINFORMATION);

????????????????fclose(file);

????????????????return true;

????????????}

????????????else//心

????????????{

????????????????*p_check = ‘A‘;

????????????}

????????}

?

????????ii++;

????????a[ii] = getc(file);

????}

?

????fclose(file);

?

????return true;

}

?

bool CAliceAndBobDlg::change_to_love(char misc[15][16])

{

????for (int i=0; i<=14; i++)

????{

????????for (int j=0; j<=15; j++)

????????{

????????????if (misc[i][j] == ‘ ‘)

????????????{

????????????????misc[i][j] = (char)36;

????????????}

????????}

????}

?

????return true;

}

时间: 2024-10-26 18:16:47

TSCTF2015 Reverse Alice_and_Easense的相关文章

Django url 标签和reverse()函数的使用(转)

原文:http://www.yihaomen.com/article/python/355.htm 使用url标签和reverse()函数,可以避免在模板和view中对url进行硬编码,这样即使url改变了,对模板和view也没有影响 起初用django 开发应用的时候,完全是在urls.py 中硬编码配置地址,在views.py中HttpResponseRedirect()也是硬编码转向地址,当然在template 中也是一样了,这样带来一个问题,如果在urls.py 中修改了某个页面的地址,

186. Reverse Words in a String II

https://leetcode.com/problems/reverse-words-in-a-string-ii/#/description Given an input string, reverse the string word by word. A word is defined as a sequence of non-space characters. The input string does not contain leading or trailing spaces and

codeforces 414C C. Mashmokh and Reverse Operation(归并排序求逆序对)

题目链接: C. Mashmokh and Reverse Operation time limit per test 4 seconds memory limit per test 512 megabytes input standard input output standard output Mashmokh's boss, Bimokh, didn't like Mashmokh. So he fired him. Mashmokh decided to go to university

Forward Proxy &amp; Reverse Proxy | 正向代理 和 反向代理

对请求和响应内容不做修改的转发的服务器,被称为代理服务器.代理服务器分为两种类型:正向代理 和 反向代理. 正向代理:面向互联网,从更广范围获取信息的代理. 反向代理:面向内部,一般用于某企业的网站的前端的代理.反向代理能承担负载均衡,身份认证,内容缓存的任务.这些功能在反向代理上面实现会显得很自然. 正向代理: 如果使用过 vpn 或者 shadowsocks 等FQ工具访问 Google,那么就是在使用正向代理服务器. 下面的图例解释了正向代理的使用.正向代理服务器在互联网中扮演用户的角色,

Reverse Linked List

题目: Reverse a singly linked list. cpp: class Solution { public: ListNode* reverseList(ListNode* head) { if(!head || !head->next) return head; ListNode *p1 = head; ListNode *p2 = head->next; ListNode *p3 = head->next->next; p1->next = nullpt

Reverse Integer - 反转一个int,溢出时返回0

Reverse Integer Reverse digits of an integer. Example1: x = 123, return 321Example2: x = -123, return -321 若反转的数溢出,直接返回0 可以用计算结果来判断溢出,也可以用因数来判断 Java代码实现: 1 public class ReverseInteger { 2 public static int reverseInt(int x){ 3 if (x == 0) { 4 return

Reverse Integer

Reverse digits of an integer. Example1: x = 123, return 321Example2: x = -123, return -321 click to show spoilers. Have you thought about this? Here are some good questions to ask before coding. Bonus points for you if you have already thought throug

leetcode 25: Reverse Nodes in k-Group

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is. You may not alter the values in the nodes, only nod

Leetcode: Reverse Words in a String

Given an input string, reverse the string word by word. For example, Given s = "the sky is blue", return "blue is sky the". Clarification: What constitutes a word? A sequence of non-space characters constitutes a word. Could the input