欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

****实验Lab1

程序员文章站 2022-04-26 09:39:09
...

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

****前言

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]));

}

 运行结果:

****实验Lab1

输出内容:

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

小结与讨论:

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

 

2、elfpass

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

Step1:设置权限

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

****实验Lab1

Step2:反汇编main函数

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

****实验Lab1

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

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

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

****实验Lab1

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

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

****实验Lab1

Step5:验证

****实验Lab1

 

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

Step1:反编译pyc文件

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

****实验Lab1

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++;
	}
}

运行结果:

****实验Lab1

 

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。

输出结果如下:

****实验Lab1

Step2:修复crackme2文件

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

****实验Lab1

Step3:反编译pyc文件

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

****实验Lab1

Step4:攻击

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

运行结果:

****实验Lab1

 

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

Step1:反汇编crackme

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

****实验Lab1

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

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

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

****实验Lab1

这里具体指明了该数组中的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;
}

运行结果:

****实验Lab1

输出内容:

密码:SesameOpenYourself!

Step3:验证

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

****实验Lab1

相关标签: ****

上一篇: ****实验Pre3

下一篇: ****实验Pre1