本文讲的是
APT案例分析:一个基于Meterpreter和Windows代理的攻击事件,
前言
1. 靶机系统以及IP:Windows 8.1 x64商业版本 10.x.x.189 2. 进入内网途径:通过认证代理 3. 代理ip以及端口:10.x.x.20:8080 4. 通过代理的外部Ip:190.x.x.x 5. 攻击者机器:190.y.y.y 6. meterpreter选择模块:windows/meterpreter/reverse_https
攻击过程分析
import ctypes import ctypes.wintypes import sys class WINHTTP_CURRENT_USER_IE_PROXY_CONFIG(ctypes.Structure): _fields_ = [("fAutoDetect", ctypes.wintypes.BOOL), ("lpszAutoConfigUrl", ctypes.wintypes.LPWSTR), ("lpszProxy", ctypes.wintypes.LPWSTR), ("lpszProxyBypass", ctypes.wintypes.LPWSTR)] class WINHTTP_AUTOPROXY_OPTIONS(ctypes.Structure): _fields_ = [("dwFlags", ctypes.wintypes.DWORD), ("dwAutoDetectFlags", ctypes.wintypes.DWORD), ("lpszAutoConfigUrl", ctypes.wintypes.LPCWSTR), ("lpvReserved", ctypes.c_void_p), ("dwReserved", ctypes.wintypes.DWORD), ("fAutoLogonIfChallenged", ctypes.wintypes.BOOL)] class WINHTTP_PROXY_INFO(ctypes.Structure): _fields_ = [("dwAccessType", ctypes.wintypes.DWORD), ("lpszProxy", ctypes.wintypes.LPCWSTR), ("lpszProxyBypass", ctypes.wintypes.LPCWSTR)] # dwFlags values WINHTTP_AUTOPROXY_AUTO_DETECT = 0x00000001 WINHTTP_AUTOPROXY_CONFIG_URL = 0x00000002 # dwAutoDetectFlags values WINHTTP_AUTO_DETECT_TYPE_DHCP = 0x00000001 WINHTTP_AUTO_DETECT_TYPE_DNS_A = 0x00000002 # Parameters for WinHttpOpen WINHTTP_USER_AGENT = "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko" WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0 WINHTTP_NO_PROXY_NAME = 0 WINHTTP_NO_PROXY_BYPASS = 0 WINHTTP_FLAG_ASYNC = 0x10000000 test_url = "http://www.google.com" # Gets the current user IE proxy configuration ieConfig = WINHTTP_CURRENT_USER_IE_PROXY_CONFIG() result = ctypes.windll.winhttp.WinHttpGetIEProxyConfigForCurrentUser(ctypes.byref(ieConfig)) if not result: print "[-] Error on WinHttpGetIEProxyConfigForCurrentUser: %s" % ctypes.GetLastError() sys.exit() print "[+] Got IE configuration" print "tAutoDetect: %s" % ieConfig.fAutoDetect print "tAuto URL: %s" % ieConfig.lpszAutoConfigUrl print "tProxy: %s" % ieConfig.lpszProxy print "tProxy Bypass: %s" % ieConfig.lpszProxyBypass # We have three alternatives: # 1. The configuration is set to "auto detect" the proxy, that is, via DHCP or DNS (in that order) # 2. There is a URL for downloading the script with the configuration (proxy autoconfiguration, PAC) # 3. A manually configured proxy is being used if ieConfig.lpszAutoConfigUrl: autoProxyOpts = WINHTTP_AUTOPROXY_OPTIONS() proxyInfo = WINHTTP_PROXY_INFO() print "[+] IE config set to autodetect with URL %s" % ieConfig.lpszAutoConfigUrl autoProxyOpts.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL autoProxyOpts.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A autoProxyOpts.fAutoLogonIfChallenged = True autoProxyOpts.lpszAutoConfigUrl = ieConfig.lpszAutoConfigUrl hInternet = ctypes.windll.winhttp.WinHttpOpen(WINHTTP_USER_AGENT, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, WINHTTP_FLAG_ASYNC) if not hInternet: print "[-] Error on WinHttpOpen: %s" % ctypes.GetLastError() sys.exit() result = ctypes.windll.winhttp.WinHttpGetProxyForUrl(hInternet, unicode(test_url), ctypes.byref(autoProxyOpts), ctypes.byref(proxyInfo)) if not result: print "[-] Error on WinHttpGetProxyForUrl: %s" % ctypes.GetLastError() sys.exit() print "[+] Proxy Host: %s" % proxyInfo.lpszProxy elif ieConfig.lpszProxy: print "[+] IE config set to proxy %s with bypass %s" % (ieConfig.lpszProxy, ieConfig.lpszProxyBypass)
1. 自动选择配置:通过252选项(DHCP)获得URL。或者在允许的情况下,通过DNS,LLMNR或者NBNS协议请求WPAD主机名。 2. 使用自动配置脚本:从指定的url下载自动配置脚本,使用这个脚本进行代理选择。 3. 代理服务器: 为不同的协议手动配置代理服务器。
import ctypes import ctypes.wintypes import sys class WINHTTP_CURRENT_USER_IE_PROXY_CONFIG(ctypes.Structure): _fields_ = [("fAutoDetect", ctypes.wintypes.BOOL), ("lpszAutoConfigUrl", ctypes.wintypes.LPWSTR), ("lpszProxy", ctypes.wintypes.LPWSTR), ("lpszProxyBypass", ctypes.wintypes.LPWSTR)] class WINHTTP_AUTOPROXY_OPTIONS(ctypes.Structure): _fields_ = [("dwFlags", ctypes.wintypes.DWORD), ("dwAutoDetectFlags", ctypes.wintypes.DWORD), ("lpszAutoConfigUrl", ctypes.wintypes.LPCWSTR), ("lpvReserved", ctypes.c_void_p), ("dwReserved", ctypes.wintypes.DWORD), ("fAutoLogonIfChallenged", ctypes.wintypes.BOOL)] class WINHTTP_PROXY_INFO(ctypes.Structure): _fields_ = [("dwAccessType", ctypes.wintypes.DWORD), ("lpszProxy", ctypes.wintypes.LPCWSTR), ("lpszProxyBypass", ctypes.wintypes.LPCWSTR)] # dwFlags values WINHTTP_AUTOPROXY_AUTO_DETECT = 0x00000001 WINHTTP_AUTOPROXY_CONFIG_URL = 0x00000002 # dwAutoDetectFlags values WINHTTP_AUTO_DETECT_TYPE_DHCP = 0x00000001 WINHTTP_AUTO_DETECT_TYPE_DNS_A = 0x00000002 # Parameters for WinHttpOpen WINHTTP_USER_AGENT = "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko" WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0 WINHTTP_NO_PROXY_NAME = 0 WINHTTP_NO_PROXY_BYPASS = 0 WINHTTP_FLAG_ASYNC = 0x10000000 test_url = "http://www.google.com" # Gets the current user IE proxy configuration ieConfig = WINHTTP_CURRENT_USER_IE_PROXY_CONFIG() result = ctypes.windll.winhttp.WinHttpGetIEProxyConfigForCurrentUser(ctypes.byref(ieConfig)) if not result: print "[-] Error on WinHttpGetIEProxyConfigForCurrentUser: %s" % ctypes.GetLastError() sys.exit() print "[+] Got IE configuration" print "tAutoDetect: %s" % ieConfig.fAutoDetect print "tAuto URL: %s" % ieConfig.lpszAutoConfigUrl print "tProxy: %s" % ieConfig.lpszProxy print "tProxy Bypass: %s" % ieConfig.lpszProxyBypass # We have three alternatives: # 1. The configuration is to "auto detect" the proxy, that is, via DHCP or DNS # 2. There is a URL for the script with the configuratoin (proxy autoconfiguration, PAC) # 3. A manually configured proxy is being used if ieConfig.lpszAutoConfigUrl or ieConfig.fAutoDetect: autoProxyOpts = WINHTTP_AUTOPROXY_OPTIONS() proxyInfo = WINHTTP_PROXY_INFO() if ieConfig.lpszAutoConfigUrl: print "[+] IE config set to autodetect with URL %s" % ieConfig.lpszAutoConfigUrl autoProxyOpts.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL autoProxyOpts.dwAutoDetectFlags = 0 autoProxyOpts.lpszAutoConfigUrl = ieConfig.lpszAutoConfigUrl if ieConfig.fAutoDetect: print "[+] IE config set to autodetect via DHCP or DNS" autoProxyOpts.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT autoProxyOpts.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A autoProxyOpts.lpszAutoConfigUrl = 0 autoProxyOpts.fAutoLogonIfChallenged = True hInternet = ctypes.windll.winhttp.WinHttpOpen(WINHTTP_USER_AGENT, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, WINHTTP_FLAG_ASYNC) if not hInternet: print "[-] Error on WinHttpOpen: %s" % ctypes.GetLastError() sys.exit() result = ctypes.windll.winhttp.WinHttpGetProxyForUrl(hInternet, unicode(test_url), ctypes.byref(autoProxyOpts), ctypes.byref(proxyInfo)) if not result: print "[-] Error on WinHttpGetProxyForUrl: %s" % ctypes.GetLastError() sys.exit() print "[+] Proxy Host: %s" % proxyInfo.lpszProxy elif ieConfig.lpszProxy: print "[+] IE config set to proxy %s with bypass %s" % (ieConfig.lpszProxy, ieConfig.lpszProxyBypass)
... dprintf("[PROXY] Got IE configuration"); dprintf("[PROXY] AutoDetect: %s", ieConfig.fAutoDetect ? "yes" : "no"); dprintf("[PROXY] Auto URL: %S", ieConfig.lpszAutoConfigUrl); dprintf("[PROXY] Proxy: %S", ieConfig.lpszProxy); dprintf("[PROXY] Proxy Bypass: %S", ieConfig.lpszProxyBypass); if (ieConfig.lpszAutoConfigUrl || ieConfig.fAutoDetect) { WINHTTP_AUTOPROXY_OPTIONS autoProxyOpts = { 0 }; WINHTTP_PROXY_INFO proxyInfo = { 0 }; if (ieConfig.fAutoDetect) { dprintf("[PROXY] IE config set to autodetect via DHCP or DNS"); autoProxyOpts.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT; autoProxyOpts.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A; autoProxyOpts.lpszAutoConfigUrl = 0; } else if (ieConfig.lpszAutoConfigUrl) { dprintf("[PROXY] IE config set to autodetect with URL %S", ieConfig.lpszAutoConfigUrl); autoProxyOpts.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL; autoProxyOpts.dwAutoDetectFlags = 0; autoProxyOpts.lpszAutoConfigUrl = ieConfig.lpszAutoConfigUrl; } autoProxyOpts.fAutoLogonIfChallenged = TRUE; if (WinHttpGetProxyForUrl(ctx->internet, ctx->url, &autoProxyOpts, &proxyInfo)) ...
问题根源所在
* 为什么要首先到达攻击机。 * 在攻击的第一阶段以及第二阶段有什么不同。
1. 攻击机器(https服务器)具有提供的证书签名的能力,防止像L7网络防火墙这样的代理进行内容检查。 2. 获取当前用户代理设置的能力,以便能够通过网络到达攻击机器。
1. 是否使用代理。意味着如果当前用户的系统中使用了浏览器代理,那么接下来就会对WinInet支持的程序进行代理。 2. 不会对自定义的SSL/TLS证书进行代理。
1. 允许自定义的SSL证书进行代理。 2. 不使用当前系统中的代理。
1. reverse_https攻击载荷使用的是WinInet的Windows API,意味着不会通过证书验证,但是可以使用系统当前的代理配置。于是,如果用户可以通过IE进行网络访问,那么这个攻击载荷就可以进行工作。 2. reverse_winhttps攻击载荷使用的是Winhttp的Windows API,意味着他可以通过证书验证,不过系统当前的代理设置不会被使用。
代理识别方法
请使用如下的步骤使用进行代理设置: 1. 配置自动选择配置 2. 配置自动选择url 3. 配置静态代理设置
容错实现
实验设置
域名:lab.bransh.com 域控IP: 192.168.0.1 DHCP 服务器:192.168.0.100-150
tmg1.lab.bransh.com: 192.168.0.10 tmg2.lab.bransh.com: 192.168.0.11 tmg3.lab.bransh.com: 192.168.0.12
import ctypes import ctypes.wintypes import sys class WINHTTP_CURRENT_USER_IE_PROXY_CONFIG(ctypes.Structure): _fields_ = [("fAutoDetect", ctypes.wintypes.BOOL), ("lpszAutoConfigUrl", ctypes.wintypes.LPWSTR), ("lpszProxy", ctypes.wintypes.LPWSTR), ("lpszProxyBypass", ctypes.wintypes.LPWSTR)] class WINHTTP_AUTOPROXY_OPTIONS(ctypes.Structure): _fields_ = [("dwFlags", ctypes.wintypes.DWORD), ("dwAutoDetectFlags", ctypes.wintypes.DWORD), ("lpszAutoConfigUrl", ctypes.wintypes.LPCWSTR), ("lpvReserved", ctypes.c_void_p), ("dwReserved", ctypes.wintypes.DWORD), ("fAutoLogonIfChallenged", ctypes.wintypes.BOOL)] class WINHTTP_PROXY_INFO(ctypes.Structure): _fields_ = [("dwAccessType", ctypes.wintypes.DWORD), ("lpszProxy", ctypes.wintypes.LPCWSTR), ("lpszProxyBypass", ctypes.wintypes.LPCWSTR)] WINHTTP_USER_AGENT = ctypes.c_wchar_p('Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko') WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0 WINHTTP_ACCESS_TYPE_NO_PROXY = 1 WINHTTP_ACCESS_TYPE_NAMED_PROXY = 3 WINHTTP_NO_PROXY_NAME = 0 WINHTTP_NO_PROXY_BYPASS = 0 def ShowLastError(message, alignment = 0): error_id = ctypes.GetLastError() print ' ' * alignment + '[-] Error on %s: %s' % (message, error_id) if error_id == 12167: title = 'ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT' message = 'The PAC file cannot be downloaded. For example, the server referenced by the PAC URL may not have been reachable, or the server returned a 404 NOT FOUND response.' elif error_id == 12007: title = 'ERROR_WINHTTP_NAME_NOT_RESOLVED' message = 'The server name cannot be resolved.' elif error_id == 12029: title = 'ERROR_WINHTTP_CANNOT_CONNECT' message = 'Returned if connection to the server failed.' elif error_id == 12002: title = 'ERROR_WINHTTP_TIMEOUT' message = 'The request has timed out.' elif error_id == 12180: title = 'ERROR_WINHTTP_AUTODETECTION_FAILED' message = 'Returned by WinHttpDetectAutoProxyConfigUrl if WinHTTP was unable to discover the URL of the Proxy Auto-Configuration (PAC) file.' else: title = 'UNKNOWN' message = 'unknown' msg_max_len = 70 msg_list = [message[i:i+msg_max_len] for i in range(0, len(message), msg_max_len)] print ' ' * alignment + ' => %s' % title for msg in msg_list: print ' ' * alignment + ' %s' % msg def GetCurrentProxies(): pProxyConfig = WINHTTP_CURRENT_USER_IE_PROXY_CONFIG() result = ctypes.windll.winhttp.WinHttpGetIEProxyConfigForCurrentUser(ctypes.byref(pProxyConfig)) if result == False: ShowLastError('WinHttpGetIEProxyConfigForCurrentUser') return False, None return True, pProxyConfig def GetProxyInfoList(pProxyConfig, target_url): print 'n[*] Checking proxy configuration alternatives...' proxy_list = [] hSession = ctypes.windll.winhttp.WinHttpOpen(WINHTTP_USER_AGENT, WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0) if hSession is None: ShowLastError('WinHttpOpen') sys.exit() WINHTTP_AUTOPROXY_AUTO_DETECT = 0x00000001 WINHTTP_AUTO_DETECT_TYPE_DHCP = 0x00000001 WINHTTP_AUTO_DETECT_TYPE_DNS_A = 0x00000002 WINHTTP_AUTOPROXY_CONFIG_URL = 0x00000002 if pProxyConfig.fAutoDetect: print 'n (1) Automatically detect settings (enabled)' print ' [*] Trying to get the proxy using the conventional method...' pAutoProxyOptions = WINHTTP_AUTOPROXY_OPTIONS() pProxyInfo = WINHTTP_PROXY_INFO() pAutoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT pAutoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A pAutoProxyOptions.lpszAutoConfigUrl = 0 lpcwszUrl = ctypes.wintypes.LPCWSTR(target_url) result = ctypes.windll.winhttp.WinHttpGetProxyForUrl(hSession, lpcwszUrl, ctypes.byref(pAutoProxyOptions), ctypes.byref(pProxyInfo)) if result == False: ShowLastError('WinHttpGetProxyForUrl', 6) print 'n [*] Trying to get the proxy using the AutoConfigURL...' dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A ppwszAutoConfigUrl = ctypes.wintypes.LPWSTR() result = ctypes.windll.winhttp.WinHttpDetectAutoProxyConfigUrl(dwAutoDetectFlags, ctypes.byref(ppwszAutoConfigUrl)) if result == False: ShowLastError('WinHttpDetectAutoProxyConfigUrl', 10) else: print ' [+] Trying to get the proxy from the obtained URL (%s)' % ppwszAutoConfigUrl.value pAutoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL pAutoProxyOptions.dwAutoDetectFlags = 0 pAutoProxyOptions.fAutoLogonIfChallenged = True pAutoProxyOptions.lpszAutoConfigUrl = ppwszAutoConfigUrl result = ctypes.windll.winhttp.WinHttpGetProxyForUrl(hSession, lpcwszUrl, ctypes.byref(pAutoProxyOptions), ctypes.byref(pProxyInfo)) if result: print ' [+] Proxy: %s' % (pProxyInfo.lpszProxy) proxy_list.append(pProxyInfo) else: ShowLastError('WinHttpGetProxyForUrl', 10) else: print ' [+] Proxy: %s' % (pProxyInfo.lpszProxy) proxy_list.append(pProxyInfo) if pProxyConfig.lpszAutoConfigUrl: print 'n (2) Use automatic configuration script (%s)' % pProxyConfig.lpszAutoConfigUrl pAutoProxyOptions = WINHTTP_AUTOPROXY_OPTIONS() pProxyInfo = WINHTTP_PROXY_INFO() pAutoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL pAutoProxyOptions.dwAutoDetectFlags = 0 pAutoProxyOptions.fAutoLogonIfChallenged = True pAutoProxyOptions.lpszAutoConfigUrl = pProxyConfig.lpszAutoConfigUrl lpcwszUrl = ctypes.wintypes.LPCWSTR(target_url) result = ctypes.windll.winhttp.WinHttpGetProxyForUrl(hSession, lpcwszUrl, ctypes.byref(pAutoProxyOptions), ctypes.byref(pProxyInfo)) if result == False: ShowLastError('WinHttpGetProxyForUrl', 6) else: print ' [+] Proxy: %s' % (pProxyInfo.lpszProxy) proxy_list.append(pProxyInfo) if pProxyConfig.lpszProxy: print 'n (3) Use a proxy server for your LAN' pProxyInfo = WINHTTP_PROXY_INFO() WINHTTP_ACCESS_TYPE_NAMED_PROXY = 3 pProxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY pProxyInfo.lpszProxy = pProxyConfig.lpszProxy pProxyInfo.lpszProxyBypass = pProxyConfig.lpszProxyBypass print ' [+] Proxy: %s' % pProxyConfig.lpszProxy print ' [+] Proxy Bypass: %s' % pProxyConfig.lpszProxyBypass proxy_list.append(pProxyInfo) ctypes.windll.winhttp.WinHttpCloseHandle(hSession) return proxy_list def CheckProxyStatus(proxyInfo, target_server, target_port): hSession = ctypes.windll.winhttp.WinHttpOpen(WINHTTP_USER_AGENT, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0) if hSession is None: ShowLastError('WinHttpOpen') return server_name = ctypes.c_wchar_p(target_server) INTERNET_DEFAULT_HTTP_PORT = target_port hInternet = ctypes.windll.winhttp.WinHttpConnect(hSession, server_name, INTERNET_DEFAULT_HTTP_PORT, 0) if hInternet is None: ShowLastError('WinHttpConnect', 8) return False WINHTTP_FLAG_BYPASS_PROXY_CACHE = 0x00000100 WINHTTP_FLAG_SECURE = 0x00800000 dwFlags = WINHTTP_FLAG_BYPASS_PROXY_CACHE pwszVerb = ctypes.c_wchar_p('GET') pwszObjectName = ctypes.c_wchar_p('') hRequest = ctypes.windll.winhttp.WinHttpOpenRequest(hInternet, pwszVerb, pwszObjectName, 0, 0, 0, dwFlags) if hRequest is None: ShowLastError('WinHttpOpenRequest', 8) return False WINHTTP_OPTION_PROXY = 38 result = ctypes.windll.winhttp.WinHttpSetOption(hRequest, WINHTTP_OPTION_PROXY, ctypes.byref(proxyInfo), ctypes.sizeof(proxyInfo)) if result == False: ShowLastError('WinHttpSetOption', 8) return False WINHTTP_NO_ADDITIONAL_HEADERS = 0 WINHTTP_NO_REQUEST_DATA = 0 result = ctypes.windll.winhttp.WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0) if result == False: ShowLastError('WinHttpSendRequest', 8) return False else: WINHTTP_QUERY_STATUS_CODE = 19 WINHTTP_QUERY_STATUS_TEXT = 20 WINHTTP_QUERY_RAW_HEADERS_CRLF = 22 WINHTTP_HEADER_NAME_BY_INDEX = 0 WINHTTP_NO_HEADER_INDEX = 0 dwInfoLevel = WINHTTP_QUERY_RAW_HEADERS_CRLF lpdwBufferLength = ctypes.wintypes.DWORD() lpdwIndex = ctypes.wintypes.DWORD() result = ctypes.windll.winhttp.WinHttpReceiveResponse(hRequest, 0) if result: result = ctypes.windll.winhttp.WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, 0, ctypes.byref(lpdwBufferLength), WINHTTP_NO_HEADER_INDEX) ERROR_INSUFFICIENT_BUFFER = 122 if ctypes.GetLastError() == ERROR_INSUFFICIENT_BUFFER: lpBuffer = ctypes.create_string_buffer(lpdwBufferLength.value) result = ctypes.windll.winhttp.WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, ctypes.byref(lpBuffer), ctypes.byref(lpdwBufferLength), WINHTTP_NO_HEADER_INDEX) if result: line = lpBuffer.raw.replace('x00', '').split('n')[0] space_1 = line.find(' ') space_2 = line.find(' ', space_1+1) code = line[space_1:space_2].strip() text = line[space_2:].strip() print "t[*] HTTP Query Status Code / Text: nt %s / %s" % (code, text) if code != "200": return False else: return True ctypes.windll.winhttp.WinHttpCloseHandle(hRequest) ctypes.windll.winhttp.WinHttpCloseHandle(hInternet) ctypes.windll.winhttp.WinHttpCloseHandle(hSession) return True def main(): result, pProxyConfig = GetCurrentProxies() if result == False: sys.exit() print 'n[*] We got the proxy configuration.' if pProxyConfig is None: print '[*] No proxy setting found for the current user.' sys.exit() target_server = 'www.google.com' target_url = 'http://' + target_server target_port = 80 proxy_list = GetProxyInfoList(pProxyConfig, target_url) print 'n[*] Number of proxies: %s' % str(len(proxy_list)) print 'n[*] Testing if proxy servers actually work...' for proxy in proxy_list: print 'n [*] Proxy "%s" ... ' % proxy.lpszProxy result = CheckProxyStatus(proxy, target_server, target_port) if result: print ' [+] Works! :)' else: print ' [-] Does not work :(' if __name__ == '__main__': main()
* GetProxyInfoList(pProxyConfig, target_url):这个函数将对当前用户进行的代理设置进行获取,返回指定url代理设置的列表。一定要注意代理列表中包含的可能用于URL进行访问的代理地址。但是这并不意味着代理服务器正在起作用。比如现在正在通过"自动选择配置"选项读取WPAD.DAT文件获取代理地址,但是当访问目标URL时代理服务并不工作。 * CheckProxyStatus(proxy, target_server, target_port):这个函数会对后门的服务以及ip进行检查(通过访问网站根目录),进而验证代理服务是否工作。这个函数会帮助确定当代理服务器给出时,判断是否可用。
测试场景一
1."自动选择配置"选项已经开启,并且在网卡禁用前通过在后台下载WPAD.PAC文件获得到代理配置为:"192.168.0.10:8080"。但是由于tmg1被禁用,所以代理服务并没有起作用,到达不了目的网络,得到连接超时页面。 2. "使用自动配置脚本"选项开启,并且与1相同,从WPAD.PAC中获得了代理服务器地址"192.168.0.11:8080",但是tmg2代理服务器被禁用,所以同样获得连接超时页面。 3. 手动设置的代理服务器地址为:"tmg3.lab.bransh.com:8080",所以这种方式代理可以成功,并且可以到达目的网络
测试场景二
1."自动选择配置"开启,但是并没有获得代理服务器地址。因为tmg1代理服务器一开始就不可达,所以不会下载WPAD.PAC文件,不会获得代理设置文件。 2. "使用自动配置脚本"选项开启,并且脚本中提供了"tmg2.lab.bransh.com/wpad.dat"代理脚本地址,不过tmg2服务器不可达,同样获取不到代理服务器地址。 3. 手动设置的代理服务器地址为:"tmg3.lab.bransh.com:8080",所以这种方式代理可以成功,并且可以到达目的网络
测试环境三
1. "自动选择配置"开启,可以通过获得的代理配置(192.168.0.10:8080)访问网络. 2. "使用自动配置脚本"开启,不过tmg2服务器不可达,所以不能下载wpad.dat脚本。 3. 手动设置的代理服务器地址为:"tmg3.lab.bransh.com:8080",所以这种方式代理可以成功,并且可以到达目的网络
测试环境四
测试环境五
1."自动选择配置"开启,可以通过获得的代理配置(192.168.0.10:8080),但是响应返回502错误,所以不能访问网络。 2. "使用自动配置脚本"同样开启,可以访问到tmg2代理服务器。但是访问响应同样是502,也不能访问网络。 3. 手动设置的代理服务器地址为:"tmg3.lab.bransh.com:8080",所以这种方式代理可以成功,并且可以到达目的网络
原文发布时间为:2017年5月27日
本文作者:xnianq
本文来自云栖社区合作伙伴嘶吼,了解相关信息可以关注嘶吼网站。