赞赏码 & 联系方式 & 个人闲话

逆向工程前言

Lab1

1、This is a security check to prevent automated programs from creating accounts.

去下面这个论坛注册一个账号https://forum.tuts4you.com/

回答出security check问题就可以。This is a security check to prevent automated programs from creating accounts.(这是一个安全检查,以防止自动程序创建帐户。

代码:

#include<stdio.h>
#include<math.h>
#include<string>

//八进制转十进制
int OtoD(int oct) {   
	int i, dec = 0, remainder;
	for (i = 0;; i++) {
		remainder = oct % 10;
		dec = dec + remainder * pow(8, i);
		if (oct / 10 == 0) {
			return dec;
		}
		oct = oct / 10;
	}
}

int main() {
	int code[] = { 127,150,141,164,47,163,40,163,150,157,162,164,40,146,157,162,40,42,142,151,156,141,162,171,40,144,151,147,151,164,42,77 };
	int i, len;
	len = sizeof(code) / sizeof(code[0]);

	printf("Code:");  
	for (i = 0; i < len; i++)
		printf("%d ", code[i]);

	printf("\nQuestion: ");
	for (i = 0; i < len; i++) 
		printf("%c", OtoD(code[i]));

}

 运行结果:

输出内容:

What’s short for “binary digit”?(二进制的简写是什么?)

小结与讨论:

二维码扫出的数字文本,实际上是字符ASCII码的八进制形式。我们要做的是通过编程将其转为十进制,并把对应的字符串输出。

 

2、elfpass

把elfpass拷贝进seed虚拟机,设成root所有suid程序,用普通用户去攻击获得root权限。可以先静态分析,搞不定再用gdb动态调试。

Step1:设置权限

把elfpass拷贝进seed虚拟机,设置成root所有,赋予suid权限。

Step2:反汇编main函数

通过GDB调试elfpass,使用disas来反汇编main函数,可以看到如下的汇编代码:

注意到里面显示了printf、scanf、strcmp函数,不难推测出分别是用作输出提示语“password”,接收输入的密码以及将输入密码和正确密码的比较。那么在比较前esp和esp+4处放置的就为两个进行比较的字符串的地址。

Step3:设置断点,推测正确密码

我们在strcmp处添加断点,输入任意密码,运行程序。我们首先查看esp得到储存两个字符串的地址。再分别查看两个地址,发现其中一个地址中储存的是我们输入的密码AAAA,另一个地址中储存的应该就是真实的密码。

Step4:确定密码的字符串序列

把得到的ASCII码拷贝进十六进制编辑器中,我们可以把16进制数转换为对应的可显示字符。结合字符串在内存中的存储顺序,我们可以得到密码:unixvswindows。

Step5:验证

 

3、运行win.pyc,要求输出'You Win'代表成功。

Step1:反编译pyc文件

反编译win.pyc文件,得出以下源码:

Step2:分析py文件

分析源码可得加密公式为((ord(v) + seed ^ ord(key[seed])) % 255),flag有23位,诸位爆破即可。

Step3:攻击

攻击代码如下:

#include<stdio.h>
#include<string.h>


int main() {
	char key1[] = "Maybe you are good at decryptint Byte Code, have a try!";
	int key2[] = { 124, 48, 52, 59, 164, 50, 37, 62, 67, 52, 48, 6, 1, 122, 3, 22, 72, 1, 1, 14, 46, 27, 232 };

	char simple[] = "QWERTYUIOPASDFGHJKLZXCVBNM{}";
	char ch;
	int i, j;
	int seed = 5;
	int tmp;

	printf("Flag:");

	for (i = 0; i < 23; i++) {   //flag有23位
		for (j = 0; j < strlen(simple); j++) {  //穷举来试
			ch = simple[j];
			tmp = (ch + seed ^ (key1[seed])) % 255;  //原算法的加密方法
			if (tmp == key2[i])
				printf("%c", ch);
		}
		seed++;
	}
}

运行结果:

 

4、在windows操作系统下运行cmpy2.exe,要求输出'you are right!'

参考Solving a PyInstaller-compiled crackme

https://hshrzd.wordpress.com/2018/01/26/solving-a-pyinstaller-compiled-crackme/(上面链接的pyc版本较老,pyc头部缺少8个字节,而下面的cmpy2里面的pyc则缺12字节)在windows操作系统下运行cmpy2.exe,要求输出'you are right!'代表成功。

Step1:解析exe文件

使用工具pyinstxtractor,指令为:python pyinstxtractor.py cmpy2.exe。

输出结果如下:

Step2:修复crackme2文件

解析了cmpy2.exe这个文件后,会生成很多文件模块,这里就有一个名为crackme2的文件。这个文件头部缺了12字节。我们只需将正常的pyc文件的前12字节,复制到crackme2的头部,然后将其另存为pyc文件,即可实现修复。

Step3:反编译pyc文件

在线反汇编:http://tools.bugscaner.com/decompyle/

Step4:攻击

由反汇编的代码可以看出,只要我们第一次输入def,第二次输入1313,程序就能输出'you are right!'。

运行结果:

 

5、(选做)crackme文件拷贝进seed虚拟机运行,要求输出'Congratulations!'代表成功。

Step1:反汇编crackme

使用IDApro7反汇编crackme,很容易找到这个和明显同密码有关的函数,仔细观察其伪代码,我们可以做出如下分析:

以上分析中有三点需要注意:

①for ( i = 0; v10[i]; ++i ); v1 = i == 19;这两句话如何理解?这里其实是计算v10的长度,若为19则v1为true。主要指明密码长度为19位。

②v5 = byte_804869C[v3];中数组byte_804869C具体是多少?我们可以进一步查看该数组:

这里具体指明了该数组中的20个数据,要注意的是数据在内存中的储存方式,例如0E8D40F58h应为0x58,0x0F,0xD4,0xE8。

③若要输出Congratulations则要保持v1为true,那么就要保持等式v5=v6^v4始终成立。

Step2:求解密码

现在我们的目的是解密出密码,密码是v10,而v10唯一的利用之处就是被赋值给了v6,所以也就是说如果我们找到v6的所有解则找到了最终密码。而v6可以根据等式v5=v6^v4计算,即v6=v5^v4,而v5和v4都是可以通过反汇编出的伪代码知晓的。根据以上分析,编写代码如下:

#include<stdio.h>
#include<stdlib.h>
int main()
{
	int i;
	bool v1;
	signed int v2;
	int v3;
	int v4;
	char v5;
	char v6;
	int v7;
	int result;
	int v9;
	char v10[124];

	for (i = 0; v10[i]; ++i);
	v1 = i == 19;
	//数组byte_804869C
	int SS[20] = { 0x6A,0xFB,0x4C,0x8D,0x58,0x0F,0xD4,0xE8,0x94,0x98,0xEE,0x6B,0x18,0x30,0xE0,0x55,0xC5,0x28,0x0E,0x90 };

	printf("密码:");
	for (i = 0; i < 19; i++)
	{
		v3 = i;
		v4 = 0;
		v5 = SS[v3];

		v9 = v3 + 1;
		v7 = 0;
		while (v7 < v9)
		{
			++v7;
			v4 = 1828812941 * v4 + 12345;
		}
		//v6=v5^v4
		unsigned __int8 aaa = (unsigned __int8)v5;
		unsigned __int8 bbb = (unsigned __int8)v4;
		printf("%c", aaa ^ bbb);
	}
	printf("\n");
	return 0;
}

运行结果:

输出内容:

密码:SesameOpenYourself!

Step3:验证

在虚拟机中运行crackme,输入求得的密码,成功输出'Congratulations!'

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐