change the return address to point to shellcode
change the return address to point to shellcode
Im using linux and I have c program, I would like to change the return
address to point to my shellcode, im unable to do it.
Can someone point to me how to do it with linux gdb debugger.
Here is my shellcode
"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc
2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80"
Here is my c program
int global_value = 0;
void bang(int val)
{
if (global_value == cookie) {
printf("Bang!: You set global_value to 0x%x\n", global_value);
validate(2);
} else
printf("Misfire: global_value = 0x%x\n", global_value);
exit(0);
}
address to point to my shellcode, im unable to do it.
Can someone point to me how to do it with linux gdb debugger.
Here is my shellcode
"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc
2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80"
Here is my c program
int global_value = 0;
void bang(int val)
{
if (global_value == cookie) {
printf("Bang!: You set global_value to 0x%x\n", global_value);
validate(2);
} else
printf("Misfire: global_value = 0x%x\n", global_value);
exit(0);
}
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
Re: change the return address to point to shellcode
This has nothing to do with operating system development, besides possessing an understanding of x86 instruction opcode encodings.
Re: change the return address to point to shellcode
thank you Brynet-Inc for your reply.
i understand that it has nothing to do with O/S.
but what i want to change the return address of the function to my shellcode.
can you please give me example how to do it.? with my source code.
i understand that it has nothing to do with O/S.
but what i want to change the return address of the function to my shellcode.
can you please give me example how to do it.? with my source code.
Re: change the return address to point to shellcode
Perhaps you could explain why you want to do this. What are you trying to achieve?
- iocoder
- Member
- Posts: 208
- Joined: Sun Oct 18, 2009 5:47 pm
- Libera.chat IRC: iocoder
- Location: Alexandria, Egypt | Ottawa, Canada
- Contact:
Re: change the return address to point to shellcode
If I get you correctly, you can change the return address of bang by modifying the pushed IP in the stack... in gcc (x86_64) it would be something like this:
Code: Select all
__asm__("movq $my_shell_code, 8(%rbp)");
Re: change the return address to point to shellcode
thank you iocoder for your reply.
but im using 32 bit O/S.
can you explain more in details. im new to this.
first of all how to get bang return address?
second shell i write assemble code to change bang return address to point to my shellcode ?
but im using 32 bit O/S.
can you explain more in details. im new to this.
first of all how to get bang return address?
second shell i write assemble code to change bang return address to point to my shellcode ?
Re: change the return address to point to shellcode
iansjack, im trying to exploit my c code by learning how to change the return address with out supplying buffer.
can you help here..
thank you.
can you help here..
thank you.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: change the return address to point to shellcode
1) learn to single step through assembly
2) learn to predict what instructions do
3) read the intel manual on "RET"
4) make that instruction do something else.
2) learn to predict what instructions do
3) read the intel manual on "RET"
4) make that instruction do something else.
Re: change the return address to point to shellcode
Combuster,
i understand what you saying about learning Assembly.
but what i need now little input about changing my return address to shellcode.
can you help here please....
i understand what you saying about learning Assembly.
but what i need now little input about changing my return address to shellcode.
can you help here please....
Re: change the return address to point to shellcode
That tells me nothing that you haven't already said. Why do you want to manipulate return addresses in this way? I can think of nefarious reasons and I wouldn't want to help a proto-hacker.hadi wrote:iansjack, im trying to exploit my c code by learning how to change the return address with out supplying buffer.
can you help here..
thank you.
Last edited by iansjack on Thu Oct 09, 2014 11:27 am, edited 2 times in total.
- iocoder
- Member
- Posts: 208
- Joined: Sun Oct 18, 2009 5:47 pm
- Libera.chat IRC: iocoder
- Location: Alexandria, Egypt | Ottawa, Canada
- Contact:
Re: change the return address to point to shellcode
I don't know about stuff like exploitation and security, but lemme help you with what I know.hadi wrote:thank you iocoder for your reply.
but im using 32 bit O/S.
can you explain more in details. im new to this.
first of all how to get bang return address?
second shell i write assemble code to change bang return address to point to my shellcode ?
Given this simple C program like this:
Code: Select all
#include <stdio.h>
#include <stdlib.h>
int global_value = 0;
void shellcode() {
__asm__(".byte 0x90,0x90,0x90,0x90"); /* you may put your shellcode here */
printf("hey guyz!\n");
exit(0);
}
void bang(int val) {
if (global_value == 5) {
printf("Bang!: You set global_value to 0x%x\n", global_value);
//validate(2);
} else
printf("Misfire: global_value = 0x%x\n", global_value);
//exit(0);
__asm__("movl $shellcode, 4(%ebp)");
}
int main() {
bang(0);
}
Code: Select all
.file "main.c"
.globl global_value
.bss
.align 4
.type global_value, @object
.size global_value, 4
global_value:
.zero 4
.section .rodata
.LC0:
.string "hey guyz!"
.text
.globl shellcode
.type shellcode, @function
shellcode:
.LFB2:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $8, %esp
#APP
# 7 "main.c" 1
.byte 0x90,0x90,0x90,0x90
# 0 "" 2
#NO_APP
subl $12, %esp
pushl $.LC0
call puts
addl $16, %esp
subl $12, %esp
pushl $0
call exit
.cfi_endproc
.LFE2:
.size shellcode, .-shellcode
.section .rodata
.align 4
.LC1:
.string "Bang!: You set global_value to 0x%x\n"
.LC2:
.string "Misfire: global_value = 0x%x\n"
.text
.globl bang
.type bang, @function
bang:
.LFB3:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $8, %esp
movl global_value, %eax
cmpl $5, %eax
jne .L3
movl global_value, %eax
subl $8, %esp
pushl %eax
pushl $.LC1
call printf
addl $16, %esp
jmp .L4
.L3:
movl global_value, %eax
subl $8, %esp
pushl %eax
pushl $.LC2
call printf
addl $16, %esp
.L4:
#APP
# 19 "main.c" 1
movl $shellcode, 4(%ebp)
# 0 "" 2
#NO_APP
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE3:
.size bang, .-bang
.globl main
.type main, @function
main:
.LFB4:
.cfi_startproc
leal 4(%esp), %ecx
.cfi_def_cfa 1, 0
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
.cfi_escape 0x10,0x5,0x2,0x75,0
movl %esp, %ebp
pushl %ecx
.cfi_escape 0xf,0x3,0x75,0x7c,0x6
subl $4, %esp
subl $12, %esp
pushl $0
call bang
addl $16, %esp
movl -4(%ebp), %ecx
.cfi_def_cfa 1, 0
leave
.cfi_restore 5
leal -4(%ecx), %esp
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE4:
.size main, .-main
.ident "GCC: (GNU) 4.9.1"
.section .note.GNU-stack,"",@progbits
The call instruction in x86 in protected mode pushes the EIP into stack (EIP here contains the return address, which points to the instruction directly after the call) then jumps to the destination code. Now at this point the stack has the return address of bang at its top (pointed to by ESP). bang() starts execution.
At first, bang() pushes EBP (the "pushl %ebp" in bang). This simply means that ESP decreases by four. So at this point, the return address becomes at ESP+4. Then comes the "movl %esp, %ebp" so the current value of ESP can be stored into EBP until the function leaves. Based on this information, we can use EBP+4 to get and modify the return address of bang().
The __asm__("movl $shellcode, 4(%ebp)"); in your C code does the trick. now when bang() returns (notice that I disabled exit(0)), it will actually return to the beginning shellcode(), not the "addl.." instruction in main().
Re: change the return address to point to shellcode
Why go through all that if the code is actually included in the program? Just place it after the function call.
I'm reading it that the OP wants to hook some external code into a program. Now why would you want to do that? Actually, modern OSs make this difficult to do - for obvious reasons.
I'm reading it that the OP wants to hook some external code into a program. Now why would you want to do that? Actually, modern OSs make this difficult to do - for obvious reasons.
Re: change the return address to point to shellcode
The IP register holds the current instruction address. (or EIP if you are in 32-bit mode)
When a function is called using the CALL instruction, the CPU pushes the current value of IP (which just happens to point to the "next" instruction after the CALL instruction) to the stack.
Then when the function is complete, it ends with a RET instruction, and the CPU pulls the "saved" value of IP from the stack and overwrites the IP register with the "saved" value, which causes the CPU to start executing code from the original location.
You can "trick" the CPU into "returning" to a different location by replacing the stored 32-bit address on the top of the stack with a new 32-bit address, and then calling RET.
However, if you are in 32-bit protected mode, the CPU will check and make sure that you have permission to execute code at the new address, and will throw a General Protection Fault if you do not.
Hopefully, this makes sense. If not, feel free to ask any specific questions you may have.
When a function is called using the CALL instruction, the CPU pushes the current value of IP (which just happens to point to the "next" instruction after the CALL instruction) to the stack.
Then when the function is complete, it ends with a RET instruction, and the CPU pulls the "saved" value of IP from the stack and overwrites the IP register with the "saved" value, which causes the CPU to start executing code from the original location.
You can "trick" the CPU into "returning" to a different location by replacing the stored 32-bit address on the top of the stack with a new 32-bit address, and then calling RET.
However, if you are in 32-bit protected mode, the CPU will check and make sure that you have permission to execute code at the new address, and will throw a General Protection Fault if you do not.
Hopefully, this makes sense. If not, feel free to ask any specific questions you may have.
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
- iocoder
- Member
- Posts: 208
- Joined: Sun Oct 18, 2009 5:47 pm
- Libera.chat IRC: iocoder
- Location: Alexandria, Egypt | Ottawa, Canada
- Contact:
Re: change the return address to point to shellcode
Yeah exactly. The text section in GNU/Linux is usually read-only, and I don't think that other data sections and the stack are executable. But maybe it is easy to do in some older versions of some poor operating system still used by many people....iansjack wrote:Why go through all that if the code is actually included in the program? Just place it after the function call.
I'm reading it that the OP wants to hook some external code into a program. Now why would you want to do that? Actually, modern OSs make this difficult to do - for obvious reasons.
Re: change the return address to point to shellcode
iocoder,
thank you for your help and support.
i can see eip pointing to shellcode (nope) with gdb.
my question here how i can compile shellcode separately with Assembly, and injected into my code with gdb linux debugger .
thank you for your help and support.
i can see eip pointing to shellcode (nope) with gdb.
my question here how i can compile shellcode separately with Assembly, and injected into my code with gdb linux debugger .