0x00 Summary
In daily penetration drills, proxy is essential. We generally use the socks5 protocol that comes with socks4 and proxy tools in CS. At this time, we still need to consider the problem of traffic avoidance during this process, so we still need Take a detailed look at the underlying protocol, and then analyze and modify the characteristics of the traffic
0x01 Introduction and process
The following is taken from Wikipedia
SOCKS is a network transmission protocol , which is mainly used for the intermediate transmission of communication between the client and the external network server. SOCKS is the abbreviation of "SOCKetS" [ Note 1] . When the client behind the firewall wants to access the external server, it connects with the SOCKS proxy server . This proxy server controls the client's qualifications to access the external network, and if allowed, sends the client's request to an external server. This protocol was originally developed by David Koblas and later extended to SOCKS4 by Ying-Da Lee of NEC. The latest protocol is SOCKS5. Compared with the previous version, it supports UDP , authentication, and IPv6 . According to the OSI model , SOCKS is a protocol at the session layer , located between the presentation layer and the transport layer . The SOCKS protocol does not provide encryption .
Little knowledge point: SOCKS 5 extends version 4 and adds UDP protocol support
The SOCKS5 protocol is mainly divided into three stages:
- (1) Protocol version and authentication method
- (2) Execute corresponding authentication according to the authentication method
- (3) Request information
The following is a detailed analysis of these processes, with a little bit of Go pseudo-code for convenience
0x02 Socks5Auth authorization authentication
The client needs to initiate a request to verify the version of the protocol and its authentication method.
Here is the request format of the client request server
VER | The protocol version number of this request, socks 5 takes a fixed value of 0x05 |
---|---|
NMETHODS | The number of authentication methods supported by the client, the possible value is 1~255 |
METHODS | List of available authentication methods |
Then the server has to choose an authentication method and tell the client:
VER | VER specifies the version of socks here, which is 0x05 |
---|---|
METHOD | The selected authentication method; where 0x00 means no authentication is required, 0x02 is username/password authentication, ... |
There are generally two authentication methods currently supported by METHOD:
- 0x00 (authentication not required)
- 0x20 (username, password authentication)
, for example, if we are socks5 here, we must accept 0x05, and we set that no verification is required. Then 0x00 does not need verification
//无需认证 直接返回 0x05 0x00 就好了
n, err = client.Write([]byte{
0x05, 0x00})
0x03 socks5 protocol analysis to establish a connection
After the client and server of Socket5 pass the authorization verification of both parties, they start to establish a connection. The connection is initiated by the client, which tells the Sokcet server which remote server the client needs to access, including the address and port of the remote server. The address can be IP4, IP6, or a domain name.
VER | VER specifies the version of socks here, which is 0x05 |
---|---|
REP | Status code, 0x00=success, 0x01=unknown error,... |
RSV | Still useless RESERVED |
TYPE | address type |
BND.ADDR | The address used by the server and DST to create a connection |
BND.PORT | The port used by the server and DST to create connections |
-
VER represents the version of the Socket protocol, the default value of Socket5 is 0x05, and its value length is 1 byte
-
CMD represents the type of client request, the value length is also 1 byte, there are three types
- CONNECT 0x01
- BIND 0x02
- UDP ASSOCIATE 0x03’
-
RSV reserved word, the value length is 1 byte
-
ATYP represents the requested remote server address type, the value length is 1 byte, and there are three commonly used types
-
1:表示是一个IPV4地址(IP V4 address); 3:表示是一个域名(DOMAINNAME); 4:表示是一个IPV6地址(IP V6 address);
-
DST.ADDR represents the address of the remote server, which is parsed according to ATYP, and the length of the value is variable.
-
DST.PORT represents the port of the remote server, which port to visit, the value length is 2 bytes
The server will return the following data to the client in response to the successful connection of the client.
resp := []byte{
0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
This is also a more interesting place, doing traffic avoid killing
0x03 Data forwarding after link establishment
After the connection is finally completed, data forwarding is required. This operation is the same as writing port forwarding, and the traffic of the two ports can be forwarded through io.Copy()
Since golang has an io.Copy, it is very simple to use
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 Traffic detection problem
Here is only the SkyEye test. This kind of authentication can be easily identified, because the matching rules can be understood immediately after analysis. This is the rule for the server to respond to the successful connection of the client, so the SkyEye detection is the rule for this successful attack .
{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
Skyeye's detection PAYLOAD:
0x05 Traffic avoidance
Now that we know the rules, it is much easier to avoid killing, because this is the process of socks authentication, although the server can be changed, but our tools are the socks5 protocol of the normal protocol, so the client must also be changed, so changing the authentication is actually not convenient. So the easiest way to implement it is to add a tunnel in the middle.
In fact, it can avoid traffic detection, but I didn’t pay attention when I wrote it. It is a forward connection. For actual combat, it is still written as a client-side active external link, so it is not very useful, so I will change it again. . .