For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

SOCKSv4 protocol parsing and IP/Port/Hostname rewrites

Problem this snippet solves:

Hi Folks,

the provided iRule can be used to parse SOCKSv4 connection request and to rewrite the connection attemps to a given IP/Port/Hostname to a different IP/Port/Hostname.

Cheers, Kai

How to use this snippet:

  1. Tweak the RULE_INIT settings as required
  2. Attach the iRule to your Virtual Server which is serving your SOCKSv4 Proxy.
  3. Connect to the IP/Port/Hostname via SOCKSv4 as usual.
  4. Check if the connection was forwarded to the new host.

Code :

when RULE_INIT {

    set static::socks_debug 1

    # Set the original and new destination HOST

    set static::orig_host "1.1.1.1:22"
    set static::new_host "2.2.2.2:22"

    set static::orig_hostname "dummy1.domain.de"
    set static::new_hostname "dummy2.domain.de"

    # Formating static::orig_host value to socks compliant host string

    scan $static::orig_host %d.%d.%d.%d:%d ip1 ip2 ip3 ip4 port
    set static::orig_host_hex [format %4.4x $port]
    foreach octed "$ip1 $ip2 $ip3 $ip4" {
        append static::orig_host_hex [format %2.2x $octed]
    }

    # Formating static::new_host value to socks compliant host string

    scan $static::new_host %d.%d.%d.%d:%d ip1 ip2 ip3 ip4 port
    set static::new_host_hex [format %4.4x $port]
    foreach octed "$ip1 $ip2 $ip3 $ip4" {
        append static::new_host_hex [format %2.2x $octed]
    }

    binary scan $static::orig_hostname H* static::orig_hostname_hex
    binary scan $static::new_hostname H* static::new_hostname_hex

}
when CLIENT_ACCEPTED {
    TCP::collect
}
when CLIENT_DATA {

    catch {

        if { $static::socks_debug } then {
            binary scan [TCP::payload] H2H1H4H2H2H2H2H* socks_version socks_command socks_port socks_ip1 socks_ip2 socks_ip3 socks_ip4 socks_username
            log local0.debug "Socks Request received: Version=[expr { "0x$socks_version" }], Command=[expr { "0x$socks_command" }] , DST_Port=[expr { "0x$socks_port" }] , DST_IP=[expr { "0x$socks_ip1" }].[expr { "0x$socks_ip2" }].[expr { "0x$socks_ip3" }].[expr { "0x$socks_ip4" }] , Username = [binary format H* $socks_username]"
        }
        binary scan [TCP::payload] H* orig_socks_payload

        if { $orig_socks_payload contains $static::orig_hostname_hex } then {
            if { $static::socks_debug } then {
                log local0.debug "Socks Request requires HOSTNAME rewrite..."
            }
            set new_socks_payload [string map "$static::orig_hostname_hex $static::new_hostname_hex" $orig_socks_payload]
            TCP::payload replace 0 [TCP::payload length] [binary format H* $new_socks_payload]
        } elseif { $orig_socks_payload contains $static::orig_host_hex } then {
            if { $static::socks_debug } then {
                log local0.debug "Socks Request requires IP rewrite..."
            }
            set new_socks_payload [string map "$static::orig_host_hex $static::new_host_hex" $orig_socks_payload]
            TCP::payload replace 0 [TCP::payload length] [binary format H* $new_socks_payload]
        }
    }
    TCP::release
}

Tested this on version:

12.0
Published Sep 08, 2016
Version 1.0
No CommentsBe the first to comment