Avoiding 0xFF bytes in shellcode using CALL to read RIP?
call rel32
is the only relative encoding (and indirect or far jmp are rarely useful), so yes of course the high byte(s) will always be 00 or FF unless you're jumping very far away, because that's how 2's complement works.
Self-modifying code would be one option (but then you have a chicken/egg problem of getting a pointer to your code). Depending on the exploit mechanism, you might have a pointer to (near) your code in RSP. So you could maybe just lea rax, [rsp+44]
/ push rax
/ jmp ...
But x86-64 has no need for the jmp/call/pop idiom. Normally you can just jmp
over your data and then use RIP-relative LEA with a negative rel32
, but that will of course also have 0xFF
bytes.
You can use RIP-relative LEA with a safe rel32 then correct it:
lea rsi, [rel anchor + 0x66666666] ; or [RIP + 0x66666666]
sub rsi, 0x66666666
;...
xor eax,eax
mov al,1 ; __NR_write = 1 x86-64 Linux
mov edi, eax
lea edx, [rax-1 + msglen]
syscall ; write(1, msg, msglen)
lea eax, [rdi-1 + 60] ; __NR_exit
syscall ; sys_exit(1)
anchor:
msg: db "Hello World", 0xa
msglen equ $-msg
machine code from assembling with NASM and disassembling with objdump -drwC -Mintel
:
$ asm-link -dn rel.asm # a helper script to assmble+link and disassemble
+ nasm -felf64 -Worphan-labels rel.asm
+ ld -o rel rel.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
rel: file format elf64-x86-64
Disassembly of section .text:
0000000000401000 <anchor-0x1e>:
401000: 48 8d 35 7d 66 66 66 lea rsi,[rip+0x6666667d] # 66a67684 <__bss_start+0x66665684>
401007: 48 81 ee 66 66 66 66 sub rsi,0x66666666
40100e: 31 c0 xor eax,eax
401010: b0 01 mov al,0x1
401012: 89 c7 mov edi,eax
401014: 8d 50 0b lea edx,[rax+0xb]
401017: 0f 05 syscall
401019: 8d 47 3b lea eax,[rdi+0x3b]
40101c: 0f 05 syscall
000000000040101e <anchor>:
40101e: 48 rex.W
... ASCII data that isn't real machine code
401029: 0a .byte 0xa
peter@volta:/tmp$ ./rel
Hello World
$ strace ./rel
execve("./rel", ["./rel"], 0x7ffd09467720 /* 55 vars */) = 0
write(1, "Hello World\n", 12Hello World
) = 12
exit(1) = ?
+++ exited with 1 +++
Amusingly, 0x66
is the ASCII code for the letter 'f'
. I didn't intentionally pick 'f'
when trying to avoid 0xFF
:P But anyway, choose whatever 4-byte string you like.
The low byte of the rel32
will be higher depending on how far it has to reach, so choose wisely.
Actually doing a call
to somewhere nearby:
You can use the above RIP-relative LEA + fixup trick to create self-modifying code, e.g. inc byte [rax]
to turn 0xFE
into 0xFF
. Or a dword sub
-immediate with 0x11111111
or something could be useful to fixup a rel32
call r/m64
and jmp r/m64
are both unusable directly, because the opcodes themselves are FF /2
and FF /4
If you want to return, it's probably easiest to fixup a call rel32
or call rax
. But it would be possible to also use RIP-relative LEA to calculate a return address in a register and push it, then jmp rel8
or jmp rax
or whatever.
execute shellcode not on the stack (buffer overflow)
Yes, it is possible, but there's a lot of things to say here.
First of all, code on the stack is usually not executable on many modern devices which use the NX-bit.
But more generally speaking, any part of memory can be made executable if you manage to get the required privilege. This can be the heap, the RAM, any area of the drive. It doesn't really matter.
The stack is just the most common default attack, but shellcodes can, for instance, also exploit heap overflows, (see this answer for an explanation).
One common attack structure would be:
- Exploit some vulnerability to get on the stack, heap, some other memory
- Use ROP to make that part of memory executable
- Have a shellcode, possibly egg-hunter if there is a memory restriction, which will find the main payload, or download something
- Execute the main payload
Hope this answers the question
Insert shell code
You could use as stdin a file with the desired content or use the echo command.
Suppose your shell code is AA BB CC DD (obviously this is not a valid shellcode):
echo -e "\xAA\xBB\xCC\xDD" | prog
Related Topics
Using Awk to Get a Specific String in Line
How to Build Kernel Debug Info as Separate File
Git Says Everything Up-To-Date
Run Hydra (Mpiexec) Locally Gives Strange Ssh Error
Why Does 'Change_Protection' Hog CPU While Loading a Large Amount of Data into Ram
How to Do an Initial Setup of Slapd Olc with Ldapmodify
Why Does Cat <<< $Var1 Lose Newlines
Finding All Directories That Are World Readable
Libnetfilter_Queue Programming, How to Know Which Program Send The Packet
_Ldg Causes Slower Execution Time in Certain Situation
How to Boot with My Latest Rpi-3.18.0 Kernel and Enabling The Device Tree
Gitlab: You Are Not Allowed to Access Master! After Moving Gitlab to Another Server
(Mac) Leave Core File Where The Executable Is Instead of /Cores
Removing First 3 Characters of File Names in Linux
Level Triggered Interrupt Handling and Nested Interrupts
Linux Shared Library Depends on Symbols in Another Shared Library Opened by Dlopen with Rtld_Local
Replace a String in a File with Contents Copied from Another File