https://blog.alien177.ca/from-getaddrinfo-to-ip/ alien177 * Home * About Extracting IP from getaddrinfo call * Tupatac Tupatac Sep 4, 2023 * 4 min read Summary This short post documents tracking down the IP address location and value resolved by the getaddrinfo function call with the help of x64dbg. Tools To follow along you will need to build 32-bit WinSock server and client provided by Microsoft and x64dbg. Getaddrinfo The getaddrinfo function resolves the provided hostname to the IP address and its prototype is: INT WSAAPI getaddrinfo( [in, optional] PCSTR pNodeName, [in, optional] PCSTR pServiceName, [in, optional] const ADDRINFOA *pHints, [out] PADDRINFOA *ppResult ); The third parameter passed to getaddrinfo is the pointer to the addrinfo structure that contains data about the socket type the caller supports. And the fourth parameter is the pointer to where the address of the returned addrinfo structure will be stored after the getaddrinfo execution. The addrinfo structure is defined like so: typedef struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; char *ai_canonname; struct sockaddr *ai_addr; struct addrinfo *ai_next; } ADDRINFOA, *PADDRINFOA; The sockaddr structure for TCP/IP looks like this: struct sockaddr { ushort sa_family; char sa_data[14]; }; struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; Getaddrinfo and x64dbg Now let's start the server app provided by MSDN and open the client app in x64dbg. To provide the command line arguments to the client app in x64dbg I updated the main input parameters before the main started to execute. The argc value was changed from 0x1 to 0x2 and the command line stored in argv was updated to look like this path_to_client.exe localhost: [00]x64dbg: we need to update argc and argv passed to main[01]x64dbg: argv before the update[02]x64dbg: argv after the update Now we can step into main and follow along until we hit the call to getaddrinfo which is preceded by the call to ZeroMemory preparing the hints buffer: [04]x64dbg after ZeroMemory execution. Dump window shows the zeroed out hints buffer. Once ZeroMemory (or memset running behind the scene) is executed we have a hints buffer of type addrinfo that needs to be populated before we execute getaddrinfo: [05]x64dbg: ai_family, ai_socktype and ai_protocol of the hints buffer are now set Now the parameters for getaddrinfo are pushed on the stack. In the image below 0x009FFCF0 will store the address of the addrinfo res structure, 0x009FFCBC stores the hints buffer that was populated above, 0x00437B80 stores the port value and the last parameter pushed on the stack is 0x00000000 since we will be resolving the localhost hostname: [06]x64dbg: getaddringo parameters are pushed on the stack After the getaddrinfo execution the 0x009FFCF0 address stores the address of the returned res structure of type addrinfo (0x00EA1D28 ): [07]x64dbg: 0x00EA1D28 returned after getaddinfo execution Let's follow it in memory and break down the data returned: (4 bytes) int ai_flags; 00 00 00 00 int ai_family; 02 00 00 00 (AF_INET) int ai_socktype; 01 00 00 00 (SOCK_STREAM) int ai_protocol; 06 00 00 00 (TCP) size_t ai_addrlen; 10 00 00 00 (16 bytes) char *ai_canonname; 00 00 00 00 struct sockaddr *ai_addr; 58 7E EA 00 (0x00EA7E58) struct sockaddr *ai_next; 00 00 00 00 [08]x64dbg: addrinfo structure at 0x00EA1D28 memory address The returned IP address is stored in ai_addr member of the addrinfo structure at memory address 0x00EA7E58 so we need to follow it in memory to get the actual IP address value: [09]x64dbg: sockaddr structure at 0x00EA7E58 memory address Data stored at aforementioned 0x00EA7E58 memory address represent the sockaddr structure for TCP/IP. Let's break it down too: short sin_family; 02 00 u_short sin_port; 69 87 (hex value for our 27015 default port) struct in_addr sin_addr; 7F 00 00 01 (IP value in hex form) char sin_zero[8] So 0x7F000001 is the returned IP value but it is in hex form and we probably want to convert it: 0x7F000001 binary form is: 01111111 00000000 00000000 00000001 or if you convert each 8 bits into decimal 127 0 0 1 So here you go. The localhost hostname was resolved to 127.0.0.1 IP as expected by the call to getaddrinfo =) References * https://learn.microsoft.com/en-us/windows/win32/winsock/ finished-server-and-client-code * https://learn.microsoft.com/en-us/windows/win32/api/ws2tcpip/ nf-ws2tcpip-getaddrinfo PSScriptAnalyzer: Tokens and ASTs Introduction Bumped into the PSScriptAnalyzer the other day and a very interesting work on detecting PowerShell scripts obfuscation using ASTs by Daniel Bohannon. So figured it might be interesting to create a small write-up about ASTs, PSScriptAnalyzer, custom PSScriptAnalyzer rules, and put all the info that's out there in one Dec 15, 2022 5 min read Part I: Remcos .NET Loader Summary Quick RE of Remcos .NET loader (e0516fbf7582151fe90b672925f75734). Static Analysis I will skip the static analysis write up since it was not very exciting. We are working with a 32 bit .NET Windows PE and you can find a couple of interesting things statically by examining the file's metadata stream Dec 1, 2022 5 min read Registry: LsaSrv Introduction Grzegorz Tworek discovered that the LsaSrv registry key could be potentially used for persistence on the host since it contains the list of DLLs that LSASS.exe automatically loads. However, it requires a little bit of work to modify its value due to its original permissions. Therefore, I figured Aug 4, 2022 5 min read alien177 (c) 2023 * Home Powered by Ghost