好久没来这跟新了,打算从今年开始在这里除除草,我兄弟的公众号也开通了给大家推荐下 小菜鸡的技术之路 关注公众号推荐给大家,网盘免费的Linux学习课程 在内网渗透过程中有时需要将内网中的应用服务进行端口转发,可以使用很多工具进行实现,主要介绍ssh以及lcx(ew基于lcx实现),并结合源码分析他们的实现原理。 端口转发(Port forwarding),有时被叫做隧道,是安全壳(SSH) 为网络安全通信使用的一种方法。端口转发是转发一个网络端口从一个网络节点到另一个网络节点的行为。简单来讲就是访问一个转发端口可以将数据转发至该对应的服务端口。 如上图所示将PC2 8888端口的数据转发至PC1的80端口,实现在PC2上访问PC1的web服务 从图下面的socket通道来看,端口转发的实现依靠的是两个socket通信的数据转发来实现的。socket1 和socket2 在PC2 上的两个端口1234和2345 通过共享BUF数据缓冲区实现端口转发。具体实现参考第四节(lcx源码分析) 端口转发的工具也多种多样,其中最方便的是使用xshell的ssh端口转发功能,最灵活的是lcx的端口转发,earthworm是最全面的端口转发工具。依次介绍其使用方法并在第三节中介绍使用场景。 使用方法 使用方法 使用方法 正向SOCKS V5 反弹 SOCKS v5 服务器 多级级联 通过lcx以及ew工具可以实现多层内网的穿透,使用简单,并且灵活性较高。通过写shell得ssh隧道可以方便的进入深层网络使得操作步骤简单,提高使用效率。 利用ew工具穿透内网,将服务转发到公网ip 实验环境有以下几个 在公网服务器执行 两种实现途径 方法2 实验场景有下几个 利用xshell 配置三台主机的登录信息 192.168.43.140 172.17.0.13 登录 172.17.0.16 场景还是上图拓扑,要求是192.168.43.165的主机能够连接172.17.0.16的socks5服务 具体做法如下 设置socks5端口 为127.0.0.1 端口为1121即可 其隧道示意图如下 将172.17.0.16的socks5服务转发到本机1121端口 端口转发的核心函数transdata,bind2conn 、bind2bind、conn2conn都是基于该函数实现的 利用select函数实现io复用,同时侦听两个套接字可读可写操作,代码实现如下: 关键代码如下 上述代码可以用下图表示 在1111端口收到的数据立刻转发到2222端口,同时在1111端口收到的数据立刻转发到2222端口,从而完成端口转发操作 关键代码如下 lcx的指令为./lcx -m 1 -h1 127.0.0.1-p1 4444 -h2 127.0.0.1 -p2 1111
0x01 端口转发
0x1 概念
0x2 图解
0x02 工具使用分析
0x1 lcx
Usage:./lcx -m method [-h1 host1] -p1 port1 [-h2 host2] -p2 port2 [-v] [-log filename] -v: version -h1: host1 -h2: host2 -p1: port1 -p2: port2 -log: log the data -m: the action method for this tool 1: listen on PORT1 and connect to HOST2:PORT2 2: listen on PORT1 and PORT2 3: connect to HOST1:PORT1 and HOST2:PORT2
开启监听端口,同时连接PORT2
开启监听端口PORT1和PORT2
连接两个主机的端口,主机地址可以是本地0x2 ssh(xshell)
ssh -L 8888:45.78.29.252:80 root@server ssh -R 8888:127.0.0.1:80 root@server ssh -D 7777
开启本地转发,转发至远程端口
开启远程转发,转发至本地端口
开启动态转发,在远程开启socks5 动态转发来自本地的请求0x3 ew
./xxx ([-options] [values])* options : Eg: ./xxx -s ssocksd -h -s state setup the function.You can pick one from the following options: ssocksd , rcsocks , rssocks , lcx_listen , lcx_tran , lcx_slave -l listenport open a port for the service startup. -d refhost set the reflection host address. -e refport set the reflection port. -f connhost set the connect host address . -g connport set the connect port. -h help show the help text, By adding the -s parameter, you can also see the more detailed help. -a about show the about pages -v version show the version. -t usectime set the milliseconds for timeout. The default value is 1000 ......
./ew -s ssocksd -l 1080
先在一台具有公网 ip 的主机A上运行以下命令:
./ew -s rcsocks -l 1080 -e 8888
在目标主机B上启动 SOCKS v5 服务 并反弹到公网主机的 8888端口
./ew -s rssocks -d 1.1.1.1 -e 8888
./ew -s lcx_listen -l 1080 -e 8888
./ew -s lcx_tran -l 1080 -f 2.2.2.3 -g 9999
./ew -s lcx_slave -d 1.1.1.1 -e 8888 -f 2.2.2.3 -g 99990x03 使用场景
0x1 内网穿透
1 本机docker ssh服务转发到公网
./ew_for_Linux32 -s lcx_listen -l 1112 -e 8980
在本机执行
./ew_for_linux64 -s lcx_slave -d serverip -e 8980 -f 172.17.0.13 -g 22
2 在本机开启Socks 服务 转发到公网
方法1
在本机执行
./ew_for_linux64 -s ssocksd -l 9999
./ew_for_linux64 -s lcx_slave -d serverip -e 8981 -f 127.0.0.1 -g 9999
在公网服务器执行
./ew_for_Linux32 -s lcx_listen -l 1113 -e 8981
在本机执行
./ew_for_linux64 -s rssocks -d serverip -e 8981
在公网服务器执行
./ew_for_Linux32 -s lcx_listen -l 1113 -e 89810x2 多级代理
1 利用xshell代理登录主机
通过192.168.43.165 主机登录在另一台主机里docker环境里的172.17.0.16主机,需要做两个跳板
首先登录192.168.43.140开启本地动态转发,通过一层代理登录172.17.0.13 ,开启本地动态转发,设置代理后登录172.17.0.16
2 利用ew代理socks5
0x04 lcx实现原理及源码分析
0x1 函数列表
void usage(char *s); void transdata(int fd1,int fd2);//进行数据转发 ,是代码实现的核心函数 void closeallfd(); void makelog(char *buffer,int length); int testifisvalue(char *str); int bind2conn(int port1,char *host,int port2);//侦听&连接 int bind2bind(int port1,int port2);//侦听&侦听 int conn2conn(char *host1,int port1,char *host2,int port2);//连接&连接 int create_socket(); int create_serv(int sockfd,int port); int client_connect(int sockfd,char* server,int port);
0x2 transdata 函数
SOCKET fd1, fd2;//用于数据交换的套接字 fd_set readfd,writefd;//设置套接字集合 FD_ZERO(&readfd);//清空集合 FD_ZERO(&writefd); //清空集合 FD_SET((UINT)fd1, &readfd); FD_SET((UINT)fd1, &writefd); FD_SET((UINT)fd2, &writefd); FD_SET((UINT)fd2, &readfd); //将fd1和fd2分别放在检测可读可写的集合里 result=select(maxfd,&readfd,&writefd,NULL,×et); //如果检测到可读套接字则继续执行 if(FD_ISSET(fd1, &readfd)) { read1=recv(fd1, read_in1, MAXSIZE-totalread1, 0); memcpy(send_out1+totalread1,read_in1,read1); totalread1+=read1;//totalread1记录收到的数据长度 memset(read_in1,0,MAXSIZE);//置空读取缓冲区 } } if(FD_ISSET(fd2, &writefd)) { int err=0; sendcount1=0; while(totalread1>0) { send1=send(fd2, send_out1+sendcount1, totalread1, 0); sendcount1+=send1;//sedcount1记录发送的总数据长度 totalread1-=send1; //剩余数据的长度 } if((totalread1>0) && (sendcount1>0))//处理异常情况下buf中的数据 { /* move not sended data to start addr */ memcpy(send_out1,send_out1+sendcount1,totalread1); memset(send_out1+totalread1,0,MAXSIZE-totalread1); } else memset(send_out1,0,MAXSIZE); }
0x3 bind2bind 函数
void bind2bind(int port1, int port2) { SOCKET fd1,fd2, sockfd1, sockfd2; struct sockaddr_in client1,client2; int size1,size2; HANDLE hThread=NULL; transocket sock; DWORD dwThreadID; if((fd1=create_socket())==0) return; if((fd2=create_socket())==0) return; if(create_server(fd1, port1)==0) { closesocket(fd1); return; } if(create_server(fd2, port2)==0) { closesocket(fd2); return; } //创建两个监听套接字 printf("[+] Listen OK!rn"); size1=size2=sizeof(struct sockaddr); while(1) { if((sockfd1 = accept(fd1,(struct sockaddr *)&client1,&size1))<0) { printf("[-] Accept1 error.rn"); continue; } if((sockfd2 = accept(fd2, (struct sockaddr *)&client2, &size2))<0) { printf("[-] Accept2 error.rn"); closesocket(sockfd1); continue; } //开启监听 sock.fd1 = sockfd1; sock.fd2 = sockfd2; //等待端口建立 通信后 执行转发函数 hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)transmitdata, (LPVOID)&sock, 0, &dwThreadID); if(hThread == NULL) { TerminateThread(hThread, 0); return; } Sleep(1000); } }
lcx的指令为./lcx -m 2 -p1 1111 -p2 22220x3 bind2conn 函数
void bind2conn(int port1, char *host, int port2) { if((sockfd=create_socket()) == INVALID_SOCKET) return; if(create_server(sockfd, port1) == 0) { closesocket(sockfd); return; }//创建监听套接字 size=sizeof(struct sockaddr); while(1) { if((sockfd1=accept(sockfd,(struct sockaddr *)&remote,&size))<0) { printf("[-] Accept error.rn"); continue; } //开启监听,等待连接 inet_ntoa(remote.sin_addr), ntohs(remote.sin_port)); if((sockfd2=create_socket())==0) { closesocket(sockfd1); continue; } if(client_connect(sockfd2,host,port2)==0)//连接另一个监听端口 { } sock.fd1 = sockfd1; sock.fd2 = sockfd2; //创建新线程,开启数据转发 hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)transmitdata, (LPVOID)&sock, 0, &dwThreadID); if(hThread == NULL) { TerminateThread(hThread, 0); return; } Sleep(1000); } }
lcx的指令为./lcx -m 1 -p1 4444 -h2 127.0.0.1 -p2 11110x4 conn2conn 函数
int conn2conn(char *host1,int port1,char *host2,int port2) { int sockfd1,sockfd2; int pid; while(1) { if((sockfd1=create_socket())==0) exit(0); if((sockfd2=create_socket())==0) exit(0); printf("make a connection to %s:%d....",host1,port1); fflush(stdout); if(client_connect(sockfd1,host1,port1)==0) //连接一个端口 { close(sockfd1); close(sockfd2); break; } printf("okrn"); printf("make a connection to %s:%d....",host2,port2); fflush(stdout); if(client_connect(sockfd2,host2,port2)==0) //连接另一个端口 { close(sockfd1); close(sockfd2); break; } printf("okrn"); pid=fork(); if(pid==0) transdata(sockfd1,sockfd2);//端口数据转发 //sleep(2); close(sockfd1); close(sockfd2); } }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算