So it was a regular day on IRC and iTpHo3NiX asked me to write a tut a tut on something like shellcoding or CSRF or something else. I was going for CSRF but that needed to setup a web server and vuln shit so I decided to write on shellcoding
Without further ado, let's begin.
A Brief Look into Shellcoding
Requirements- An x86 linux based OS (for simplifying the process)
- Decent knowledge of Assembly language
- A brain( without it, you can't do, trust me)
Alright, we are ready to start.
What really is a shellcode? From wikipedia - a shellcode is a small piece of code used as the payload in the exploitation of a software vulnerability. It is called "shellcode" because it typically starts a command shell from which the attacker can control the compromised machine, but any piece of code that performs a similar task can be called shellcode.
Typically written in machine languageToo lazy to define myself :p
Let's get started
One thing to note : the shellcode is just like any other piece of code written in assembly language, it can be anything you want, from a hello world printing code to reverse connect shell code to adding users with root priv and anything, possiblities are just endless. We just need to take care of some stuff and I'll be explaining that to you, just keep going.
We'll start with a hello world code :
.data
Hello: .ascii "Hello\n"
.text
.globl _start
_start:
# Printing Hello to the screen
movl $4, %eax
movl $1, %ebx
leal Hello, %ecx
movl $6, %edx
int $0x80
# Exiting gracefully
movl $1, %eax
movl $0, %ebx
int $0x80
Now, it prints simply
Hello on the command line and exits but the question is can we use this as shellcode? Umm... no because it got a fundamental problem with it and that is the address of the string is statically-binded into the program and when it is injected into another program's memory( as payload ), it won't work as that address may contain something else in that program's memory.
In the screenshot, you can see the highlighted part is the address of the string and is statically binded.
To overcome this problem, we'll have to write a PIC( Position Independent Code) so as to calculate its (string's) location on the fly when it is injected in the memory of a vuln program to execute this
Techniques for writing shellcode There are bascailly (mostly used) 2 techniques for writing the shellcode :
Well, the original is JMP-CALL-POP but I do a CALL-POP as it saves 2 bytes
Reason I described here -
ShellcodeGodI'll be using CALL-POP here, will use stack technique when it is required.
Writing the PICTo get around this problem, we'll use the fact that when the
call instruction is executed, it pushes the address of next instruction on the stack as a return address and we'll make this return address point to the string
.text
.globl _start
execute:
# Printing Hello to the screen
xorl %eax, %eax
xorl %ebx, %ebx
xorl %edx, %edx
movb $4, %al
movb $1, %bl
popl %ecx # Poping the address of the string in the ECX register
movb $6, %dl
int $0x80
# Exiting gracefully
movb $1, %al
int $0x80
_start:
call execute
hello: .ascii "Hello\n"
Here, in the output you can see I assembled it simply and if you see the output of the both runs, both runs perfectly and in the disassembly of the PIC code, there is
NO HARDCODED ADDRESS so we overcame the fundamental problem and this is ready to be used in the shellcode (I also optimized the shellcode and removed the nulls).
Let's try this as shellcode.
You may be thinking that ok, we got it running, we made it PIC but how will we put this in the memory?Ans. To put this into a program's memory and run this, inject this as a char array of opcodes. What do I mean by that is disassemble the elf file (your shellcode) using objdump and extract the opcodes and then arrange them in order as an array and then make the return pointer to overwrite the return address with your shellcode's address so when the C program(given below) exits, it'll jump to your shellcode and therefore it'll execute this and we are done.
Use the bash script given below to automate this for you
Cool.. it worked perfectly
Note : I used this shell script from
Here (actually the first comment) to dump the opcodes from the objdump output.
for i in `objdump -d $1 | tr '\t' ' ' | tr ' ' '\n' | egrep '^[0-9a-f]{2}$' ` ; do echo -n "\x$i" ; done
The C code for testing the shellcode is
#include<stdio.h>
char shellcode[] = ""; // Your shellcode's opcodes in the double quotes
int main(void){
int *ret;
ret = (int *)&ret + 2;
(*ret) = (int)shellcode;
}
Well, this is the brief intro to shellcoding. What do I have in mind for the next post is to continue this and will teach you how to write some usable shellcode as payload like making directory with permission 777 and how to execute a shell
Stay tuned.
I don't know why the fuck the images are blurry, they were crystal clear when I checked them but whatever.
If you have any doubts, just ask and if suggestions, I welcome them