1、前言

假装大学生水一下CTF题目,常规思路。程序没有加壳,是VC写的MFC程序。

2、破题思路

  • 1、MessageBox 下断点
  • 2、找到提示错误字符串的函数B
  • 3、跟踪函数
  • 4、跟踪算法

3、实现过程

PEID查询无壳,进IDA查看字符串。

得到这个字符串的一个存放地址,向上跟踪到有这个字符串的地方,依稀可以看到加密后的Flag轮廓。

.data:00403254 aVSIKTQU        db '注册码要往这里填呀 ! ',0     ; DATA XREF: sub_401230+40o

当即想到有字符串就会有弹框的地方,查找所有模块后,在MessageBox断点。

运行-输入Flag的地方输入【ABCDEFG1234567】,然后通过堆栈窗口跟踪到调用弹窗的地方。

拿到弹窗地址00401759,到IDA里的窗口查看对比得到调用Flag输入错误提示信息的地址。

sub_401720 调用提示错误字符串的函数B

在sub_401720处断点,截获到存着flag的寄存器。说明计算离计算flag的距离已经不远了。

继续通过堆栈窗口跳到调用401720这个函数的地方,也就是00401621这个地址

00401621 调用提示字符串B - 错误

调用00401621地址也就是错误提示的地方来自以上的一个判断,这里应该有一个判断。但是IDA识别不出来,自己手动创建函数后程序结构判断一目了然。

int __thiscall sub_4015E0(CWnd *this)
{
CWnd *v1; // esi@1
int result; // eax@3
int v3; // [sp-4h] [bp-Ch]@2
int *v4; // [sp+4h] [bp-4h]@2 v1 = this;
CWnd::UpdateData(this, 1);
if ( *(_DWORD *)(*((_DWORD *)v1 + 165) - 8) == 33
&& (v3 = *((_DWORD *)v1 + 165), v4 = &v3, CString::CString(&v3, (char *)v1 + 660), (unsigned __int8)sub_401630(v3)) )
{
result = sub_4016E0(v1);
}
else
{
result = sub_401720(v1);
}
return result;
}

依赖IDA向上追溯已经没法子了,那么通过程序中可以看到会对比一个33的字符,那么这个判断里非常有可能就是计算flag的地方。计算要求必须要33个字符,那么我们就整个33字符输入进去即可!输入构造好的33个字符的字符串【ABCDEFG123456789qwertyuiopzxcvbnm】

反汇编的注释如下:


004015E0 push ecx ; 调用错误提示的函数
004015E1 push esi
004015E2 mov esi,ecx
004015E4 push 0x1
004015E6 call <jmp.&MFC42.#6334> ; MFC更新数据函数UpdateData()
004015EB mov ecx,dword ptr ds:[esi+0x294]; 将FLAG字符串存储到ECX寄存器中
004015F1 lea eax,dword ptr ds:[esi+0x294]
004015F7 cmp dword ptr ds:[ecx-0x8],0x21 ; 对比是否有33个字符
004015FB jnz short WHCTF201.0040161F
004015FD push ecx
004015FE mov ecx,esp
00401600 mov dword ptr ss:[esp+0x8],esp
00401604 push eax
00401605 call <jmp.&MFC42.#535> ; MFC_CString函数
0040160A mov ecx,esi
0040160C call WHCTF201.00401630 ; 这个函数出来之后就比较是否跳到提示错误弹窗函数
00401611 test al,al ; 再一次比较是否到调用提示错误的弹窗函数
00401613 je short WHCTF201.0040161F
00401615 mov ecx,esi
00401617 call WHCTF201.004016E0 ; 调用提示成功的弹窗函数
0040161C pop esi ; 0012FEB4
0040161D pop ecx ; 0012FEB4
0040161E retn
0040161F mov ecx,esi ; 调用提示错误的弹窗函数
00401621 call WHCTF201.00401720
00401626 pop esi ; 0012FEB4
00401627 pop ecx ; 0012FEB4
00401628 retn

反汇编代码中首先对比了一个输入的字符串是否有33个字符,如果没有就调用提示错误的弹窗函数。计算Flag通常会有两次判断,一次是判断字符串长度是否正确,然后判断输入的字符串是否正确。以上汇编中从00401630这个函数出来后会进行结果的判断然后根据结果是否跳转到调用提示错误弹窗函数的地方。

跟进00401630函数,OD反汇编代码如下:

00401630 push ecx                               ;  Flag计算函数
00401631 push ebx ; msvcrt.srand
00401632 mov ebx,dword ptr ds:[<&MSVCRT.srand>] ; msvcrt.srand
00401638 push ebp
00401639 push esi
0040163A push edi
0040163B xor edi,edi
0040163D mov ebp,ecx ; -CRACKME
0040163F mov byte ptr ss:[esp+0x13],0x1
00401644 mov edx,0xA
00401649 xor esi,esi
0040164B push edx
0040164C call ebx ; msvcrt.srand
0040164E add esp,0x4
00401651 call dword ptr ds:[<&MSVCRT.rand>] ; [rand
00401657 cdq
00401658 mov ecx,0xA
0040165D idiv ecx ; 有符号除法
0040165F mov ecx,dword ptr ss:[esp+0x18] ; flag的值存储到ecx中
00401663 mov cl,byte ptr ds:[edi+ecx]
00401666 lea eax,dword ptr ds:[esi+edx]
00401669 cmp cl,byte ptr ds:[eax+ebp+0x60] ; flag{出现的地方
0040166D je short WHCTF201.00401674
0040166F mov byte ptr ss:[esp+0x13],0x0
00401674 add esi,0xA ; esi+10
00401677 inc edi ; 目标操作数+1
00401678 cmp esi,0x14A ; 330
0040167E jl short WHCTF201.0040164B
00401680 lea ecx,dword ptr ss:[esp+0x18]
00401684 call <jmp.&MFC42.#800>
00401689 mov al,byte ptr ss:[esp+0x13]
0040168D pop edi
0040168E pop esi
0040168F pop ebp
00401690 pop ebx ; msvcrt.srand
00401691 pop ecx
00401692 retn 0x4

Flag出现的地方,就是0040165F这里。

ABCDEFG123456789qwertyuiopzxcvbnm
flag{The-Y3ll0w-turb4ns-Upri$ing}

思路小结:

  • 1、MessageBox 下断点
  • 2、找到提示错误字符串的函数B
  • 3、有个CMP对比字符串是不是等于0x21(33)个字符
  • 4、调用两个CALL,MFC自带的跳过
  • 5、跟进00401630 计算flag函数
  • 6、00401663 读取flag字符
  • 7、0040165F 转换为Key值

4、附件下载

https://github.com/zprogram/zprogram.github.io/blob/master/Blog_attachment/CTF/WHCTF2017-CRACKME.zip

【CTF REVERSE】WHCTF2017-CRACKME的更多相关文章

  1. 【CTF REVERSE】ctf02-查找字符串

    1.前言 公司大拿给写的一个CTF逆向程序,提升我们组内人员的水平. 基于对话框MFC框架开发,使用EDIT控制特性隐藏Flag,可借助spy4win之类窗体工具找出Flag. 程序加UPX壳,已对壳 ...

  2. 【CTF MISC】隐写术wireshark找出图片-“强网杯”网络安全挑战赛writeup

    这场CTF中有一道题是分析pcap包的.. 13.大黑阔: 从给的pcap包里把图片提取出来,是一张中国地图. 题目提示是黑阔在聊天,从数据里可以找出几段话. 思路:主要考察wireshark的过滤规 ...

  3. 【CTF杂项】常见文件文件头文件尾格式总结及各类文件头

    文件头文件尾总结 JPEG (jpg), 文件头:FFD8FF 文件尾:FF D9PNG (png), 文件头:89504E47 文件尾:AE 42 60 82GIF (gif), 文件头:47494 ...

  4. 【CTF WEB】ISCC 2016 web 2题记录

      偶然看到的比赛,我等渣渣跟风做两题,剩下的题目工作太忙没有时间继续做. 第1题 sql注入: 题目知识 考察sql注入知识,题目地址:http://101.200.145.44/web1//ind ...

  5. 【CTF WEB】XSS-https://alf.nu/alert1

    XSS练习平台 https://alf.nu/alert1 Warmup 1");alert(1)// Adobe 1");alert(1)// JSON </script& ...

  6. 【CTF WEB】反序列化

    反序列化 漏洞代码 <?php error_reporting(0); if(empty($_GET['code'])) die(show_source(__FILE__)); class ex ...

  7. 【CTF WEB】服务端请求伪造

    服务端请求伪造 如你所愿,这次可以读取所有的图片,但是域名必须是www开头 测试方法 POST /index.php HTTP/1.1 Host: 218.2.197.236:27375 Conten ...

  8. 【CTF WEB】命令执行

    命令执行 找到题目中的KEY KEY为八位随机字符数字,例如key:1234qwer.提交1234qwer 即可. 漏洞代码 <?php system("ping -c 2 " ...

  9. 【CTF WEB】函数绕过

    函数绕过 <?php show_source(__FILE__); $c = "<?php exit;?>"; @$c.=$_GET['c']; @$filena ...

随机推荐

  1. 20135220谈愈敏Linux Book_5

    第五章 系统调用 内核提供了用户进程与内核进行交互的一组接口. 应用程序发出请求->内核负责满足 目的:保证系统稳定可靠 5.1 与内核通信 系统调用在用户空间进程和硬件设备之间添加了一个中间层 ...

  2. 组件 -- Button

    .btn --------------------------------- button的背景色: .btn-primary .btn-success .btn-secondary .btn-dan ...

  3. git 生成秘钥

    Permission denied (publickey). fatal: The remote end hung up unexpectedly 应该是ssh key过期了吧 试着重新创建ssh k ...

  4. python的logging日志模块

    1. 简单的将日志打印到屏幕 import logging logging.debug('This is debug message') logging.info('This is info mess ...

  5. AOP 如果被代理对象的方法设置了参数 而代理对象的前置方法没有设置参数 则无法拦截到

    AOP 如果被代理对象的方法设置了参数 而代理对象的前置方法没有设置参数 则无法拦截到

  6. python updata与深拷贝

    当使用updata更新字典时候 被动更新和主动更新的效果是一样的 意思是说 里面会添加值 而不是保持不变 当将一个字典每次新增到列表时候 要用深拷贝 因为直接append的话 会修改将最新的变量的值同 ...

  7. ubuntu下java JDK环境配置

    ubuntu下配置JDK环境变量ubuntu下的JDK配置本质上和win一样的:1.去官网下载JDK,选择适合自己版本,我下载的版本是jdk-8u121-linunx-x64.tag.gz,官方网址h ...

  8. BZOJ2597 WC2007剪刀石头布(费用流)

    考虑使非剪刀石头布情况尽量少.设第i个人赢了xi场,那么以i作为赢家的非剪刀石头布情况就为xi(xi-1)/2种.那么使Σxi(xi-1)/2尽量小即可. 考虑网络流.将比赛建成一排点,人建成一排点, ...

  9. The Super Powers UVA - 11752(合数幂)

    题意: 求1~2^64-1之间所有的 至少是两个不同的正整数的幂的数  升序输出 一个数的合数次幂即为这样的数 找出1~2^64-1中所有数的合数次幂 用set存起来(既能防止重复 又能升序) 最后输 ...

  10. oracle 每个类别取几条的语法怎么写

    select *from (select t.*,row_number() over(partition by t.公司名 order by 1) rn  from t)where rn<=10