胖哈勃的期末公开赛---prob

附件解压后得到一个elf文件,查看文件信息

胖哈勃的期末公开赛---prob_第1张图片

运行程序发现只输出flag是否正确

用ida打开,发现是静态编译而且删除了符号表.

根据start函数找到main函数,发现无论如何都会出输出wrong,所以check肯定不在main函数

所以很有可能在main函数之前或之后,查看init_array找到了真正的check部分

胖哈勃的期末公开赛---prob_第2张图片

先检查flag的前5个,然后读入16字节到.233段

对输入查看交叉引用又发现了其他的2个check函数,将它们分别命名为check1,2,3

查看check1的汇编代码发现输入16字节后通过ROP链对输入进行了加密,然后在check2与硬编码比较

胖哈勃的期末公开赛---prob_第3张图片

使用动态调试,并且Trace instruction后得到ROP链

胖哈勃的期末公开赛---prob_第4张图片

简单处理后得到汇编代码,然后将代码汇编,再使用ida将二进制代码patch到程序空白部分查看伪代码

胖哈勃的期末公开赛---prob_第5张图片

看起来像某种加密算法的展开形式,但是算法水平太低看不出是什么算法

直接从后向前枚举每个变量的值

胖哈勃的期末公开赛---prob_第6张图片

最后得到输入的16个字符

check2和check1过程相同

用于枚举的代码:

#include
#include

using namespace std;

unsigned int ROR(unsigned int val,int bits)
{
	return ((val >> bits) | (val << (32 - bits)));
}


unsigned int ROL(unsigned int val,int bits)
{
	return ((val << bits) | (val >> (32 - bits)));
}


int main()
{
	unsigned int v34 = 0xde6ec7aa;

	//printf("%x\n",0x778EF56B^0xCF7199C3);
	for(unsigned int i=0;i<0xffffffff;i++)
	{
		if(i%0x10000000==0)printf("1\n");
		if( 0x1660ac1== (  ROR(v34 ^ ROR(v34 ^ ROR(v34 ^ ROR(v34 ^ ROR(v34 ^ ROR(v34 ^ ROR(v34 ^ ROR(v34 ^ ROR(v34 ^ ROR(v34 ^ ROR(i, 9), 2),3),4),5),6),7),8),9),10),11) ^ v34 ))
		{
			printf("%x\n",i);
		} 
	}
	
	system("pause");
	return 0;
}

部分python代码:

def ROR(a,b):
    a1=(a>>b)&0xffffffff
    b1=(a<<(32-b))&0xffffffff
    return (a1|b1)


def ROL(a,b):
    a1=(a<<b)&0xffffffff
    b1=(a>>(32-b))&0xffffffff
    return (a1|b1)

def BYTE1(a):
    return (a&0xff00)>>8

def BYTE2(a):
    return (a&0xff0000)>>16

email:[email protected]

你可能感兴趣的:(WP)