内网代理流量:Socks5协议原理分析和编程

0x00 前情提要

日常渗透演练中,代理是必不可少的,我们用的一般也都是CS自带socks4和代理工具的socks5协议,我们此时还要考虑在这个过程中的流量免杀的问题,所以还是要对底层的协议详细的看一下,然后对流量中的特征分析和修改一下

0x01 简介和流程

以下摘自维基百科

SOCKS是一种网络传输协议,主要用于客户端与外网服务器之间通讯的中间传递。SOCKS是”SOCKetS”的缩写[注 1]。 当防火墙后的客户端要访问外部的服务器时,就跟SOCKS代理服务器连接。这个代理服务器控制客户端访问外网的资格,允许的话,就将客户端的请求发往外部的服务器。 这个协议最初由David Koblas开发,而后由NEC的Ying-Da Lee将其扩展到SOCKS4。最新协议是SOCKS5,与前一版本相比,增加支持UDP、验证,以及IPv6。 根据OSI模型,SOCKS是会话层的协议,位于表示层传输层之间。 SOCKS协议不提供加密

小知识点:SOCKS 5 扩展了第 4 版本,加入了 UDP 协议支持

SOCKS5协议主要分为分为三个阶段:

  • (1) 协议版本及认证方式
  • (2) 根据认证方式执行对应的认证
  • (3) 请求信息

下面就对这几个流程详细的分析一下,附带一点点 Go的伪代码看着方便

0x02 Socks5Auth 授权认证

客户端需要先发起请求来对协议的版本及其认证方式。

这里就是客户端请求服务器的请求格式

VER 本次请求的协议版本号,socks 5取固定值 0x05
NMETHODS 客户端支持的认证方式数量,可取值 1~255
METHODS 可用的认证方式列表

然后服务端得选择一种认证方式,告诉客户端:

VER VER这里指定的就是socks的版本,也就是0x05
METHOD 选定的认证方式;其中 0x00 表示不需要认证,0x02 是用户名/密码认证,……

METHOD目前支持的验证方式一般就用两种:

  • 0x00 (不需要验证)
  • 0x20 (用户名、密码认证)

,例如我们这里是socks5的话接受的肯定就是0x05,并且我们设定不需要验证。那么就是0x00不需要验证

1
2
//无需认证 直接返回 0x05 0x00 就好了
n, err = client.Write([]byte{0x05, 0x00})

0x03 socks5协议解析之建立连接

Socket5的客户端和服务端进行双方授权验证通过之后,就开始建立连接了。连接由客户端发起,告诉Sokcet服务端客户端需要访问哪个远程服务器,其中包含,远程服务器的地址和端口,地址可以是IP4,IP6,也可以是域名。

VER VER这里指定的就是socks的版本,也就是0x05
REP 状态码,0x00=成功,0x01=未知错误,……
RSV 依然是没卵用的 RESERVED
ATYP 地址类型
BND.ADDR 服务器和DST创建连接用的地址
BND.PORT 服务器和DST创建连接用的端口
  • VER代表Socket协议的版本,Soket5默认为0x05,其值长度为1个字节

  • CMD代表客户端请求的类型,值长度也是1个字节,有三种类型

    • CONNECT 0x01
    • BIND 0x02
    • UDP ASSOCIATE 0x03’
  • RSV保留字,值长度为1个字节

  • ATYP代表请求的远程服务器地址类型,值长度1个字节,常用的就三种类型

  • 1:表示是一个IPV4地址(IP V4 address);
    3:表示是一个域名(DOMAINNAME);
    4:表示是一个IPV6地址(IP V6 address);
    <!--1-->
    

这个也是一个比较有意思的地方,在做流量免杀

0x03 建立链接之后的数据转发

最后完成链接之后就是需要进行数据转发了,这个操作和写端口转发的一样的,通过io.Copy()把两个端口的的流量进行转发即可

由于 golang 有一个 io.Copy ,所以使用还是十分简单的

1
2
3
4
5
6
7
8
forward := func(src, dest net.Conn) {
defer src.Close()
defer dest.Close()
io.Copy(src, dest)
}

go forward(client, target)
go forward(target, client)

0x04 流量检测问题

这边只有天眼的测试,这种认证可以轻松被识别出来,因为匹配的规则在分析之后一下就明白了,这是服务端响应客户端连接成功的规则,所以天眼检测就是这个成功攻击的规则

1
{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

天眼的检测PAYLOAD:

0x05 流量免杀

既然知道规则,那么免杀那就好说多了,因为这是socks认证的过程,虽然可以改服务端,但是我们的工具都是正常协议的socks5协议,那么客户端也得改,所以改认证其实不是很方便。所以最简单的实现方法在中间加一条隧道就好了。

image-20211027203826936

实际是可以规避流量检测,但是我写的时候没注意,是正向的连接的额,实战用还是写成有客户端主动外链的,所以没啥大用处,再重新改一下得。。。