Petition
gdb动态调试
-
寻找真正的地址 gdb Petition pwndbg> i function pwndbg> b printf pwndbg> r 调试程序进入到printf函数内部。但是esp存放了call调用之后的下一步的地址是0x565560cb。 于是我们知道了start()函数起始地址是0x56556040 -
解决ida乱码问题。 由图可以知道esp这部分是乱码,看不太懂。进入gdb调试。 pwndbg> b *0x56556040 进入gdb调试以后并没有乱码,显示正常。 -
寻找到输入地址在哪儿 pwndbg> b *0x5655616b
以上,发现esi,ebi是输入。对应的栈地址为0xfffcf90,而ebp为0xffffd090。所以存在了ebp - 0x100 的地址上。
寻找核心代码
-
通过动态调试和静态分析,发现sub_2910非常重要。 但是ida反编译的看不懂。 a3是esp,于是直接看汇编代码。 动态调试之后,发现这个esp里面的值正好是传入函数的第三个参数,也就是如果不动的话,可以顺利进入下一个递归函数。
-
进入递归函数 int __usercall sub_119C@<eax>(int a1@<esi>)
{
int i; // eax
int v2; // ecx
int v3; // eax
int v4; // ebx
int retaddr; // [esp+4h] [ebp+0h] BYREF
for ( i = 1; ; i = 2 * v3 )
{
v2 = i;
v3 = a1 & i;
if ( !v3 )
break;
a1 ^= v3;
}
v4 = *(_BYTE *)(v2 ^ a1) ^ 0x6C;
*(_DWORD *)(v4 ^ (unsigned int)&retaddr) = 0;
sub_2910(retaddr, *(_DWORD *)(v4 ^ (unsigned int)&retaddr), (int)sub_122A);
retaddr = 0;
return 4634;
}
好像也没看不懂,看汇编发现两个重要的点,因为esi是存输入的地址,而通过汇编发现: ida还是有问题,看动态: 把esi最高位的一个byte取出来了,放到ebx(bl是ebx的低位),然后和0x883d6d6c异或。经过若干次计算,eax本来是esp存储的指针,和ebx异或之后,[eax]被放上了1.然后发现eax清零之后赋值esp与另外的两个数字异或: 于是我们可以猜测input[i] ^ 0x883d6d6c ^ esp == 0xca ^ 0xca ^ exp, esp可以消掉。 -
返回sub_2910,经过发现如果第二个参数(edx)为1.那么esp才不会变化。而edx为1,需要上述等式,因为xor byte ptr [eax], 1,这里赋值了1. -
ida汇编解释: .text:000011B1 xor esi, ecx
.text:000011B3 xor ebx, ebx
.text:000011B5 xor bl, [esi]
.text:000011B7 xor ebx, 883D6B6Ch ; ebx = buffer[i] ^ 0x883d6b6c
.text:000011BD xor ecx, ecx
.text:000011BF xor cl, bl
.text:000011C1 xor ebx, ebx
.text:000011C3 xor bl, cl ; bl = cl
.text:000011C5 xor eax, eax
.text:000011C7 xor eax, esp
.text:000011C9 xor eax, ebx ; eax = esp ^ buffer[i] ^ 0x883d6b6c
.text:000011CB xor edx, edx
.text:000011CD xor edx, eax ; edx = esp ^ buffer[i] ^ 0x883d6b6c
.text:000011CF xor ecx, ecx
.text:000011D1 xor ecx, [eax] ; ecx = [eax]
.text:000011D3 xor [eax], ecx
.text:000011D5 xor eax, eax
.text:000011D7 xor eax, esp ; eax = esp
.text:000011D9 xor eax, 0CAh
.text:000011DE xor eax, 0CAh ; eax = esp ^ 0xca ^ 0xca
.text:000011E3 xor ecx, ecx
.text:000011E5 xor ecx, [eax]
.text:000011E7 xor [eax], ecx ; ecx = [esp ^ 0xca ^ 0xca]
.text:000011E9 xor byte ptr [eax], 1
.text:000011EC xor eax, eax
.text:000011EE xor eax, edx ; eax = esp ^ buffer[i] ^ 0x883d6b6c
.text:000011F0 xor edx, edx
.text:000011F2 xor edx, [eax] ; edx = [eax] = 1; if esp ^ buffer[i] ^ 0x883d6b6c == esp ^ 0xca ^ 0xca
.text:000011F4 call $+5
.text:000011F9 xor eax, eax
.text:000011FB xor eax, [esp+4+var_4]
.text:000011FE xor [esp+4+var_4], eax
.text:00001201 xor [esp+4+var_4], offset sub_122A
学习idapython提取出汇编指令
思路:提取出函数地址(名称,名称就是地址),然后按照偏移计算出xor的地址。三个分别是+27,+61,+66. ida_python:
import idautils
import idc
fun_addrs = ['0x119c', '0x122a', '0x12b8', '0x1344', '0x13d0', '0x145c', '0x14e8', '0x1574', '0x1602', '0x168e', '0x171c', '0x17a6', '0x1834', '0x18c2', '0x194e', '0x19da', '0x1a64', '0x1aee', '0x1b7a', '0x1c06', '0x1c94', '0x1d20', '0x1daa', '0x1e34', '0x1ec2', '0x1f4e', '0x1fda', '0x2064', '0x20f0', '0x217a', '0x2208', '0x2292', '0x231e', '0x23ac', '0x243a', '0x24c4', '0x2552', '0x25de', '0x266c', '0x26fa', '0x2784', '0x2810', '0x289c']
first_xor = []
second_xor = []
third_xor = []
for i in fun_addrs:
first_xor.append(int(i,16) + 27)
second_xor.append(int(i,16) + 61)
third_xor.append(int(i,16) + 66)
first_disasm = []
second_disasm = []
third_disasm = []
for i in range(len(first_xor)):
first_disasm.append(idc.GetDisasm(first_xor[i]))
second_disasm.append(idc.GetDisasm(second_xor[i]))
third_disasm.append(idc.GetDisasm(third_xor[i]))
print(first_disasm)
print(second_disasm)
print(third_disasm)
'''
读取程序代码。
a = []
for func in idautils.Functions():
print(hex(func))
a.append(hex(func))
with open('test.txt','w') as wp:
for i in a:
wp.write(i + '\n')
fun_addrs = ['0x119c', '0x122a', '0x12b8', '0x1344', '0x13d0', '0x145c', '0x14e8', '0x1574', '0x1602', '0x168e', '0x171c', '0x17a6', '0x1834', '0x18c2', '0x194e', '0x19da', '0x1a64', '0x1aee', '0x1b7a', '0x1c06', '0x1c94', '0x1d20', '0x1daa', '0x1e34', '0x1ec2', '0x1f4e', '0x1fda', '0x2064', '0x20f0', '0x217a', '0x2208', '0x2292', '0x231e', '0x23ac', '0x243a', '0x24c4', '0x2552', '0x25de', '0x266c', '0x26fa', '0x2784', '0x2810', '0x289c']
'''
python_exp:
first_disasm = ['xor ebx, 883D6B6Ch', 'xor ebx, 0C257C607h', 'xor ebx, 713CCBCEh', 'xor ebx, 0E15E13F9h', 'xor ebx, 9183DC8Ch', 'xor ebx, 53C7A888h', 'xor ebx, 47BE5AA8h', 'xor ebx, 3EC91252h', 'xor ebx, 0CB762A99h', 'xor ebx, 76F2EF19h', 'xor ebx, 9E905A15h', 'xor ebx, 0FE60EA66h', 'xor ebx, 54B6A82Eh', 'xor ebx, 270F76AFh', 'xor ebx, 42FEEBF6h', 'xor ebx, 0CB33EE43h', 'xor ebx, 5594EC2Ch', 'xor ebx, 0D80068C9h', 'xor ebx, 3B4E4FCAh', 'xor ebx, 0EEDB8266h', 'xor ebx, 1248D6AAh', 'xor ebx, 0CF0CD84Ch', 'xor ebx, 56B34D2Dh', 'xor ebx, 92845225h', 'xor ebx, 0E73146D6h', 'xor ebx, 0D12681FFh', 'xor ebx, 0E017F544h', 'xor ebx, 0C70EC7BDh', 'xor ebx, 0A415A472h', 'xor ebx, 0BE6D8165h', 'xor ebx, 4EA32808h', 'xor ebx, 0C5AF2385h', 'xor ebx, 3F052312h', 'xor ebx, 0A3D8BA7Fh', 'xor ebx, 9C0EDA13h', 'xor ebx, 2D126124h', 'xor ebx, 9B4784FCh', 'xor ebx, 0E50E3B24h', 'xor ebx, 0BB29CF33h', 'xor ebx, 0B9F87523h', 'xor ebx, 0C7F10097h', 'xor ebx, 0B785DBB2h']
second_disasm = ['xor eax, 0CAh', 'xor eax, 0DFh', 'xor eax, 0C8h', 'xor eax, 23h', 'xor eax, 2Dh', 'xor eax, 9Ch', 'xor eax, 0F5h', 'xor eax, 0F1h', 'xor eax, 2Ch', 'xor eax, 96h', 'xor eax, 5Bh', 'xor eax, 0A0h', 'xor eax, 9Bh', 'xor eax, 14h', 'xor eax, 0A9h', 'xor eax, 48h', 'xor eax, 58h', 'xor eax, 1Ah', 'xor eax, 0EFh', 'xor eax, 9Dh', 'xor eax, 43h', 'xor eax, 66h', 'xor eax, 62h', 'xor eax, 0C2h', 'xor eax, 0D3h', 'xor eax, 35h', 'xor eax, 16h', 'xor eax, 0EEh', 'xor eax, 77h', 'xor eax, 80h', 'xor eax, 1Fh', 'xor eax, 0F4h', 'xor eax, 8Ah', 'xor eax, 0DFh', 'xor eax, 66h', 'xor eax, 0B5h', 'xor eax, 0EFh', 'xor eax, 0EDh', 'xor eax, 0EEh', 'xor eax, 4Bh', 'xor eax, 0CDh', 'xor eax, 3Eh']
third_disasm =['xor eax, 0CAh', 'xor eax, 0B9h', 'xor eax, 61h', 'xor eax, 0A1h', 'xor eax, 98h', 'xor eax, 22h', 'xor eax, 3Eh', 'xor eax, 95h', 'xor eax, 8Ch', 'xor eax, 0B9h', 'xor eax, 7Ah', 'xor eax, 0F0h', 'xor eax, 98h', 'xor eax, 83h', 'xor eax, 6Eh', 'xor eax, 33h', 'xor eax, 40h', 'xor eax, 0FEh', 'xor eax, 11h', 'xor eax, 0C8h', 'xor eax, 0DFh', 'xor eax, 19h', 'xor eax, 62h', 'xor eax, 0DFh', 'xor eax, 61h', 'xor eax, 0AFh', 'xor eax, 6Bh', 'xor eax, 7Eh', 'xor eax, 32h', 'xor eax, 0D6h', 'xor eax, 71h', 'xor eax, 46h', 'xor eax, 0ABh', 'xor eax, 99h', 'xor eax, 4Dh', 'xor eax, 0A1h', 'xor eax, 25h', 'xor eax, 0FFh', 'xor eax, 0BEh', 'xor eax, 59h', 'xor eax, 27h', 'xor eax, 8Ch']
first_xor = []
second_xor = []
third_xor = []
for i in range(len(first_disasm)):
first_xor.append(int(first_disasm[i].split(' ')[-1][:-1],16))
second_xor.append(int(second_disasm[i].split(' ')[-1][:-1],16))
third_xor.append(int(third_disasm[i].split(' ')[-1][:-1],16))
flag = b''
for i in range(len(first_disasm)):
flag += ((first_xor[i] ^ second_xor[i] ^ third_xor[i]) & 0xFF).to_bytes(1,'little')
print(flag)
#b'lag{96c69646-8184-4363-8de9-73f7398066c1}\x00'
#缺一个f,在start函数里
#flag{96c69646-8184-4363-8de9-73f7398066c1}
|