Skip to content

Commit

Permalink
fix: filter IPs resolved from hosts file according to hints like fake ip
Browse files Browse the repository at this point in the history
fix: allow resolution by custom hosts file even if proxy_dns is off
  • Loading branch information
shunf4 committed Jun 24, 2020
1 parent d4fd5d9 commit eb33964
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 30 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,11 @@ proxychains.exe is in no way compatible with terminals based on ConEmu

## To-do

- [ ] IPs resolved from hosts file should also be filtered like fake ip
- [ ] Properly handle "fork-and-exit" child process ? (In this case the
descendant processes' dns queries would never succeed)
- [ ] Remote DNS resolving based on UDP associate
- [ ] Hook `sendto()`, coping with applications which do TCP fast open
- [X] IPs resolved from hosts file should also be filtered like fake ip
- [X] Resolve encoding issue regarding Cygwin and Mintty (fixed in 0.6.7)
- [X] Fake IPs should be filtered according to types of resolved IPs
and hints in `GetAddrInfoW` and `gethostbyname`, otherwise crash may happen
Expand Down
2 changes: 1 addition & 1 deletion include/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@
#define PXCH_VERSION_MINOR 6
#endif
#ifndef PXCH_VERSION_PATCH
#define PXCH_VERSION_PATCH 7
#define PXCH_VERSION_PATCH 8
#endif
2 changes: 1 addition & 1 deletion proxychains.conf
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ localnet 127.0.0.0/255.0.0.0
IP-CIDR,10.0.0.0/8,DIRECT
IP-CIDR,172.16.0.0/12,DIRECT
IP-CIDR,192.168.0.0/255.255.0.0,DIRECT
IP-CIDR,fd00::/8,DIRECT
IP-CIDR,fe80::/8,DIRECT
# - PORT rule, matching requests to a target port.
# e.g. PORT,25,BLOCK
#
Expand Down
33 changes: 20 additions & 13 deletions src/dll/hook_connect_win32.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,21 @@ typedef union _PXCH_TEMP_DATA {
PXCH_WS2_32_TEMP_DATA Ws2_32_TempData;
} PXCH_TEMP_DATA;

static BOOL ResolveByHostsFile(PXCH_IP_ADDRESS* pIp, const PXCH_HOSTNAME* pHostname)
static BOOL ResolveByHostsFile(PXCH_IP_ADDRESS* pIp, const PXCH_HOSTNAME* pHostname, int iFamily)
{
PXCH_UINT32 i;

PXCH_IP_ADDRESS* pCurrentIp;

for (i = 0; i < g_pPxchConfig->dwHostsEntryNum; i++) {
if (StrCmpW(PXCH_CONFIG_HOSTS_ENTRY_ARR_G[i].Hostname.szValue, pHostname->szValue) == 0) {
if (pIp) *pIp = PXCH_CONFIG_HOSTS_ENTRY_ARR_G[i].Ip;
break;
pCurrentIp = &PXCH_CONFIG_HOSTS_ENTRY_ARR_G[i].Ip;
if (iFamily == AF_UNSPEC
|| (iFamily == AF_INET && pCurrentIp->CommonHeader.wTag == PXCH_HOST_TYPE_IPV4)
|| (iFamily == AF_INET6 && pCurrentIp->CommonHeader.wTag == PXCH_HOST_TYPE_IPV6)
) {
if (pIp) *pIp = *pCurrentIp;
break;
}
}
}
return i != g_pPxchConfig->dwHostsEntryNum;
Expand Down Expand Up @@ -1230,7 +1237,7 @@ PROXY_FUNC2(Ws2_32, gethostbyname)
StringCchPrintfW(OriginalHostname.szValue, _countof(OriginalHostname.szValue), L"%S", name);

// Decide if we should use hosts entry
if (g_pPxchConfig->dwWillResolveLocallyIfMatchHosts && ResolveByHostsFile((PXCH_IP_ADDRESS*)&IpPortResolvedByHosts, &OriginalHostname)) {
if (g_pPxchConfig->dwWillResolveLocallyIfMatchHosts && ResolveByHostsFile((PXCH_IP_ADDRESS*)&IpPortResolvedByHosts, &OriginalHostname, AF_INET)) {
bShouldReturnHostsResult = TRUE;
bShouldUseHostsResult = TRUE;
}
Expand Down Expand Up @@ -1276,7 +1283,7 @@ PROXY_FUNC2(Ws2_32, gethostbyname)
}

if (bShouldUseResolvedResult) {
if (!g_pPxchConfig->dwWillResolveLocallyIfMatchHosts && ResolveByHostsFile((PXCH_IP_ADDRESS*)&IpPortResolvedByHosts, &OriginalHostname)) {
if (!g_pPxchConfig->dwWillResolveLocallyIfMatchHosts && ResolveByHostsFile((PXCH_IP_ADDRESS*)&IpPortResolvedByHosts, &OriginalHostname, AF_INET)) {
bShouldUseHostsResult = TRUE;
}
}
Expand Down Expand Up @@ -1534,6 +1541,11 @@ PROXY_FUNC2(Ws2_32, GetAddrInfoW)
// Print DNS query
FUNCIPCLOGD(L"Ws2_32.dll GetAddrInfoW(%ls, %ls, AF%#010x, FL%#010x, ST%#010x, PT%#010x) called", pNodeName, pServiceName, pHintsCast->ai_family, pHintsCast->ai_flags, pHintsCast->ai_socktype, pHintsCast->ai_protocol);

DefaultHints.ai_family = AF_UNSPEC;
DefaultHints.ai_flags = 0;
DefaultHints.ai_socktype = SOCK_STREAM;
DefaultHints.ai_protocol = IPPROTO_TCP;

iReturn = orig_fpWs2_32_GetAddrInfoW(L"127.0.0.1", pServiceName, NULL, &pQueryPortAddrInfo);
iWSALastError = WSAGetLastError();
dwLastError = GetLastError();
Expand All @@ -1553,7 +1565,7 @@ PROXY_FUNC2(Ws2_32, GetAddrInfoW)
Hostname.wPort = 0;

// Decide if we should use hosts entry
if (g_pPxchConfig->dwWillResolveLocallyIfMatchHosts && ResolveByHostsFile((PXCH_IP_ADDRESS*)&IpPortResolvedByHosts, &Hostname)) {
if (g_pPxchConfig->dwWillResolveLocallyIfMatchHosts && ResolveByHostsFile((PXCH_IP_ADDRESS*)&IpPortResolvedByHosts, &Hostname, pHintsCast->ai_family)) {
bShouldReturnHostsResult = TRUE;
bShouldUseHostsResult = TRUE;
}
Expand All @@ -1563,11 +1575,6 @@ PROXY_FUNC2(Ws2_32, GetAddrInfoW)
bShouldReturnResolvedResult = TRUE;
bShouldUseResolvedResult = TRUE;
} else if (!bShouldReturnHostsResult) {
DefaultHints.ai_family = AF_UNSPEC;
DefaultHints.ai_flags = 0;
DefaultHints.ai_socktype = SOCK_STREAM;
DefaultHints.ai_protocol = IPPROTO_TCP;

ZeroMemory(&RequeryAddrInfoHints, sizeof(RequeryAddrInfoHints));
RequeryAddrInfoHints.ai_family = AF_UNSPEC;
RequeryAddrInfoHints.ai_protocol = pHintsCast->ai_protocol;
Expand Down Expand Up @@ -1617,7 +1624,7 @@ PROXY_FUNC2(Ws2_32, GetAddrInfoW)
}

if (bShouldUseResolvedResult) {
if (!g_pPxchConfig->dwWillResolveLocallyIfMatchHosts && ResolveByHostsFile((PXCH_IP_ADDRESS*)&IpPortResolvedByHosts, &Hostname)) {
if (!g_pPxchConfig->dwWillResolveLocallyIfMatchHosts && ResolveByHostsFile((PXCH_IP_ADDRESS*)&IpPortResolvedByHosts, &Hostname, pHintsCast->ai_family)) {
bShouldUseHostsResult = TRUE;
}
}
Expand Down
26 changes: 12 additions & 14 deletions src/dll/hook_installer.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,20 +71,18 @@ void Win32HookWs2_32(void)
orig_fpWs2_32_getnameinfo = (void*)GetProcAddress(hWs2_32, "getnameinfo");
orig_fpWs2_32_GetNameInfoW = (void*)GetProcAddress(hWs2_32, "GetNameInfoW");

if (g_pPxchConfig->dwWillUseFakeIpAsRemoteDns) {
pWs2_32_gethostbyname = orig_fpWs2_32_gethostbyname ;
pWs2_32_gethostbyaddr = orig_fpWs2_32_gethostbyaddr ;
pWs2_32_getaddrinfo = orig_fpWs2_32_getaddrinfo ;
pWs2_32_GetAddrInfoW = orig_fpWs2_32_GetAddrInfoW ;
pWs2_32_GetAddrInfoExA = orig_fpWs2_32_GetAddrInfoExA ;
pWs2_32_GetAddrInfoExW = orig_fpWs2_32_GetAddrInfoExW ;
pWs2_32_freeaddrinfo = orig_fpWs2_32_freeaddrinfo ;
pWs2_32_FreeAddrInfoW = orig_fpWs2_32_FreeAddrInfoW ;
pWs2_32_FreeAddrInfoExA_ = orig_fpWs2_32_FreeAddrInfoExA_;
pWs2_32_FreeAddrInfoExW = orig_fpWs2_32_FreeAddrInfoExW ;
pWs2_32_getnameinfo = orig_fpWs2_32_getnameinfo ;
pWs2_32_GetNameInfoW = orig_fpWs2_32_GetNameInfoW ;
}
pWs2_32_gethostbyname = orig_fpWs2_32_gethostbyname ;
pWs2_32_gethostbyaddr = orig_fpWs2_32_gethostbyaddr ;
pWs2_32_getaddrinfo = orig_fpWs2_32_getaddrinfo ;
pWs2_32_GetAddrInfoW = orig_fpWs2_32_GetAddrInfoW ;
pWs2_32_GetAddrInfoExA = orig_fpWs2_32_GetAddrInfoExA ;
pWs2_32_GetAddrInfoExW = orig_fpWs2_32_GetAddrInfoExW ;
pWs2_32_freeaddrinfo = orig_fpWs2_32_freeaddrinfo ;
pWs2_32_FreeAddrInfoW = orig_fpWs2_32_FreeAddrInfoW ;
pWs2_32_FreeAddrInfoExA_ = orig_fpWs2_32_FreeAddrInfoExA_;
pWs2_32_FreeAddrInfoExW = orig_fpWs2_32_FreeAddrInfoExW ;
pWs2_32_getnameinfo = orig_fpWs2_32_getnameinfo ;
pWs2_32_GetNameInfoW = orig_fpWs2_32_GetNameInfoW ;

// CREATE_HOOK3_IFNOTNULL(Ws2_32, WSAStartup, pWs2_32_WSAStartup);
CREATE_HOOK3_IFNOTNULL(Ws2_32, WSAConnect, pWs2_32_WSAConnect);
Expand Down

0 comments on commit eb33964

Please sign in to comment.