Recently been doing some stuffs on Shellcode. After a while wandering in the net, I found the doc “The Basics of Shellcoding” by Angelo Rosiello may be the very concise introduction to start with shellcoding, especially for the newbie like myself – baby step. However, though with brief and clear description in this doc, I feel frustrated when I was trying to do it myself. Stack manipulation with string and system call is expected in the doc (part C below); while assembly code my here is C lib call and string in .rodata (part B below). Detailed workaround to get the opcode in part C is listed below. On the other hand, to implement shellcode, we really need to put everything we need in the stack and use system call directly, as address of .rodata and C lib function call would be dynamically changed per each binary.
/* A: Original C source code in the doc */
/home/daveti/shellcode: cat rosiello.c
#include <stdio.h>
int main()
{
write( 0, “WWW.ROSIELLO.ORG”, 16);
exit(0);
}
/* B: Objdump for the binary of the code above */
080481d0 <main>:
#include <stdio.h>
int main()
{
80481d0: 55 push %ebp
80481d1: 89 e5 mov %esp,%ebp
80481d3: 83 ec 08 sub $0x8,%esp
80481d6: 83 e4 f0 and $0xfffffff0,%esp
80481d9: b8 00 00 00 00 mov $0x0,%eax
80481de: 29 c4 sub %eax,%esp
write( 0, “WWW.ROSIELLO.ORG”, 16);
80481e0: 83 ec 04 sub $0x4,%esp
80481e3: 6a 10 push $0x10
80481e5: 68 68 f7 08 08 push $0x808f768
80481ea: 6a 00 push $0x0
80481ec: e8 8f 5a 00 00 call 804dc80 <__libc_write>
80481f1: 83 c4 10 add $0x10,%esp
exit(0);
80481f4: 83 ec 0c sub $0xc,%esp
80481f7: 6a 00 push $0x0
80481f9: e8 16 04 00 00 call 8048614 <exit>
80481fe: 90 nop
80481ff: 90 nop
/* C: Assembly code for shellcode expected in the doc */
xor %eax,%eax
xor %ebx,%ebx
xor %edx,%edx
push %eax
push $0x47524f2e
push $0x4f4c4c45
push $0x49534f52
push $0x2e575757
mov %esp,%ecx
mov $0x10,%dl
mov $0x4,%al
int $0x80
xor %eax,%eax
xor %ebx,%ebx
mov $0x1,%al
int $0x80
/* D: Shellcode in the doc */
/home/daveti/shellcode: cat rosiello_shellcode.c
#include <stdio.h>
char shellcode[]=
“x31xc0x31xdbx31xd2x50x68x2ex4f”
“x52x47x68x45x4cx4cx4fx68x52x4f”
“x53x49x68x57x57x57x2ex89xe1xb2”
“x10xb0x04xcdx80x31xc0x31xdbxb0”
“x01xcdx80”;
int main()
{
void (*routine)();
/* daveti: gcc 4.X would report error! */
(long) routine = &shellcode;
printf(“Size: %d bytesn”, sizeof(shellcode));
routine();
return 0;
}
/* E: Run the shellcode in the doc */
/home/daveti/shellcode: ./rosiello_shellcode
Size: 44 bytes
WWW.ROSIELLO.ORG/home/daveti/shellcode: gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs
Configured with: ../configure –prefix=/usr –mandir=/usr/share/man –infodir=/usr/share/info –enable-shared –enable-threads=posix –disable-checking –with-system-zlib –enable-__cxa_atexit –host=i386-redhat-linux
Thread model: posix
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
/home/daveti/shellcode: uname -a
Linux lssxlinux1.ih.lucent.com 2.6.32-042stab044.11 #1 SMP Wed Dec 14 16:02:00 MSK 2011 i686
/* F: gcc -S rosiello.c */
/home/daveti/shellcode: cat rosiello.s
.file “rosiello.c”
.section .rodata
.LC0:
.string “WWW.ROSIELLO.ORG”
.text
.globl main
.type main,@function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
subl %eax, %esp
subl $4, %esp
pushl $16
pushl $.LC0
pushl $0
call write
addl $16, %esp
subl $12, %esp
pushl $0
call exit
.Lfe1:
.size main,.Lfe1-main
.ident “GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)”
/* G: Modify rosiello.s to rosiello_daveti.c with desired assembly in C */
/home/daveti/shellcode: cat rosiello_daveti.s
.file “rosiello_daveti.c”
.section .rodata
.text
.globl main
.type main,@function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
subl %eax, %esp
xor %eax, %eax
xor %ebx, %ebx
xor %edx, %edx
push %eax
push $0x47524f2e
push $0x4f4c4c45
push $0x49534f52
push $0x2e575757
mov %esp, %ecx
mov $0x10, %dl
mov $0x4, %al
int $0x80
xor %eax, %eax
xor %ebx, %ebx
mov $0x1, %al
int $0x80
.Lfe1:
.size main,.Lfe1-main
.ident “GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)”
/* H: gcc -o rosiello_daveti rosiello_daveti.s – make sure our change work */
/home/daveti/shellcode: ./rosiello_daveti
WWW.ROSIELLO.ORG/home/daveti/shellcode:
/* I: Objdump to get the opcode instead of gdb */
080482f4 <main>:
80482f4: 55 push %ebp
80482f5: 89 e5 mov %esp,%ebp
80482f7: 83 ec 08 sub $0x8,%esp
80482fa: 83 e4 f0 and $0xfffffff0,%esp
80482fd: b8 00 00 00 00 mov $0x0,%eax
8048302: 29 c4 sub %eax,%esp
8048304: 31 c0 xor %eax,%eax
8048306: 31 db xor %ebx,%ebx
8048308: 31 d2 xor %edx,%edx
804830a: 50 push %eax
804830b: 68 2e 4f 52 47 push $0x47524f2e
8048310: 68 45 4c 4c 4f push $0x4f4c4c45
8048315: 68 52 4f 53 49 push $0x49534f52
804831a: 68 57 57 57 2e push $0x2e575757
804831f: 89 e1 mov %esp,%ecx
8048321: b2 10 mov $0x10,%dl
8048323: b0 04 mov $0x4,%al
8048325: cd 80 int $0x80
8048327: 31 c0 xor %eax,%eax
8048329: 31 db xor %ebx,%ebx
804832b: b0 01 mov $0x1,%al
804832d: cd 80 int $0x80
804832f: 90 nop
/* J: Finally we have got the workable opcode in the doc:) */