前言

少年侠气,交结五都雄。肝胆洞。毛发耸。立谈中。死生同。一诺千金重。推翘勇。矜豪纵。轻盖拥。联飞鞚。斗城东。轰饮酒垆,春色浮寒瓮。吸海垂虹。闲呼鹰嗾犬,白羽摘雕弓。狡穴俄空。乐匆匆。
似黄粱梦。辞丹凤。明月共。漾孤篷。官冗從。怀倥偬。落尘笼。簿书丛。鹖弁如云众。供粗用。忽奇功。笳鼓动。渔阳弄。思悲翁。不请长缨,系取天骄种。剑吼西风。恨登山临水,手寄七弦桐。目送归鸿。

男儿何不带吴钩,收取关山五十州。

作者有情怀,读者也会热血沸腾。

“漏洞分析与利用的过程是充满艺术感的。想象一下,剥掉Windows中那些经过层层封装的神秘的对话框‘外衣’,面对着浩如烟海的二进制机器码,跋涉于内存中不知所云的海量数据,在没有任何技术文档可以参考的情况下,进行反汇编并调试,把握函数调用和参数传递的细节,猜测程序的设计思路,设置巧妙的断点并精确定位到几行有逻辑缺陷的代码,分析研究怎么去触发这个逻辑漏洞,最后编写出天才的渗透代码,从而获取系统的控制权……这些分析过程的每一个环节无不散发着充满智慧的艺术美感!这种技术不同于其他计算机技术,它的入门门槛很高,需要拥有丰富的计算机底层知识、精湛的调试技术、非凡的逻辑分析能力,还要加上一点点创造性的思维和可遇而不可求的运气。”

“在计算机工业向模块化、封装化、架构化发展的过程中,人们更加倾向于把时间和精力用于那些敏捷开发的高级工具上。走进大学的计算机系你可以发现J2EE与.NET的书籍随处可见,但是却没有几个学生能在二进制级别把计算机体系结构讲清。甚至在某些网络安全学院里,能把蠕虫入侵的原理刨根问底彻底、弄清的也是凤毛麟角,非好奇心不盛也,乃道之不传也久矣。在信息安全这条道路上行走,需要‘男儿何不带吴钩,收取关山五十州’的豪情,需要‘臣心一片磁针石,不指南方不肯休’的毅力,需要‘壁立千仞,无欲则刚’的情怀……我等立书只为布道交友,最大的收益莫过于帮助还在彷徨如何入门的朋友迈过那条门槛,通过此书结交更多的同道中人。”

“这个行业属于有兴趣、够执著的人,属于为了梦想能够不懈努力的意志坚定者。”

启程

第一章主要讲了常见工具的基本使用。应该是为了帮助初学者搭建环境。之前在学习《恶意代码分析实战》时我已经搭好了一个很棒的环境:

作者推荐的工具如下:

  • Lord PE
  • OllyDbg
  • SoftICE
  • WinDbg
  • IDA Pro
  • UltraEdit/Hex Workshop/WinHex/010 Editor
  • VMware(此处作者还提到了黑客帝国)
  • Python

作者还推荐了那篇著名的缓冲区溢出文章:Smashing The Stack For Fun And Profit

PE文件与内存映射

首先是几个概念:

  • File Offset
  • Image Base
  • Virtual Address, VA
  • Relative Virtual Address, RVA
VA = Image Base + RVA

默认情况下,PE文件的0字节处被映射到0x00400000处,即Image Base

由于PE文件中数据按0x200字节组织,而内存中按0x1000字节组织(根据操作系统知识,这或许就是内存页?),故映射前后本该是同一概念的File OffestRVA有着不同的值。为了方便后面的计算,我们把节的这种差异称为节偏移,比如下面的例子:

Section RVA File Offset 节偏移
.text 0x00001000 0x0400 (0x00001000 - 0x0400)
.rdata 0x00007000 0x6200 (0x00007000 - 0x6200)
.data 0x00009000 0x7400 (0x00009000 - 0x7400)
.rsrc 0x0002D000 0x7800 (0x0002D000 - 0x7800)

于是我们得到了File OffsetVA的换算方法:

File Offset = VA - Image Base - 节偏移
            = RVA - 节偏移

小试牛刀

题目

编译代码,尝试使用工具逆向并修改二进制程序:

/*****************************************************************************
      To be the apostrophe which changed "Impossible" into "I'm possible"!

POC code of chapter 3.7 in book "Vulnerability Exploit and Analysis Technique"

file name	: crack_me.c
author		: failwest
date		: 2006.9.20
description	: used as a simple demo to show how to crack a PE file
Noticed		: should be complied with VC6.0 and build into release version
version		: 1.0
E-mail		: failwest@gmail.com

	Only for educational purposes    enjoy the fun from exploiting :)
******************************************************************************/

#include <stdio.h>
#define PASSWORD "1234567"
int verify_password (char *password)
{
	int authenticated;
	authenticated=strcmp(password,PASSWORD);
	return authenticated;
}

main()
{
	int valid_flag=0;
	char password[1024];
	while(1)
	{
		printf("please input password:       ");
		scanf("%s",password);
		valid_flag = verify_password(password);
		if(valid_flag)
		{
			printf("incorrect password!\n\n");
		}
		else
		{
			printf("Congratulation! You have passed the verification!\n");
			break;
		}
	}
}

尝试运行

发现在正确输入密码后会弹出成功提示,否则会无限循环输入。

IDA Pro

作者没有提到反编译,也许写书时还没这个技术?

载入程序,在某行汇编代码上按空格可以跳到流程图界面。可以看到逻辑还是比较清晰的。

定位到关键语句为

jz      short loc_40107F

如果我们把这条指令改成jne,就能够在输错密码情况下获得成功提示了。在这条指令上按空格,返回汇编界面查看其地址:

.text:0040106E                 jz      short loc_40107F

接下来试一下OllyDbg的动态调试。

OllyDbg

载入程序,Crtl+G转到0x0040106EF2在此处下断点:

F9执行到这里(由于有输入,所以会挂起,你需要到命令行中随便给一个输入,比如xxx),按空格修改这里的指令为jne

接着继续F8执行,发现成功改变了逻辑:

但是,这仅仅修改了内存副本,真正的文件并未被改变,下面我们使用LordPE对文件进行修改。

LordPE

选择“PE编辑器”并载入文件:

接着点击“位置计算器”,输入VA0040106E,它会帮你算好其他的数据:

此时我们可以根据文件偏移使用其他二进制编辑器去修改代码,也可以直接在这里点击“十六进制编辑”,将je对应的74改为jne对应的75并保存:

再次运行,发现输入错密码可以获得成功提示,相反输入正确密码会得到错误提示:

总结

本章讲的够基础,但帮我复习了基本技能,其更偏向于逆向的范畴,不过本来逆向就是exploit的基础。现如今,无论是搭环境的自信,还是学习时丰富的联想发散或者对同一问题有与作者截然不同的解法,都告诉我自己已经不是当初什么都不懂的小白了。但是依然梦在远方,路在脚下。

所以加油。