VYPR
Moderate severityNVD Advisory· Published Sep 20, 2023· Updated Sep 25, 2024

CVE-2023-43618

CVE-2023-43618

Description

An issue was discovered in Croc through 9.6.5. The protocol requires a sender to provide its local IP addresses in cleartext via an ips? message.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Croc file transfer tool up to version 9.6.5 sends the sender's local IP addresses in cleartext during the protocol handshake, enabling passive network attackers to learn the sender's network topology and potentially bypass trust models.

An information disclosure vulnerability exists in the Croc file transfer utility through version 9.6.5. During the protocol handshake, the sender is required to transmit its local IP addresses in cleartext via an ips? message [1]. This design means the IP information is sent before any encryption layer is established, contrary to the tool's goal of providing end-to-end security. The issue is part of a set of security findings reported by Matthias Gerstner in September 2023 [1].

A passive network attacker who can observe the traffic between the sender and the relay server can capture these IP addresses without any authentication or special privileges. The ips? message is exchanged in the clear, so an attacker on the same network segment or along the path can glean the sender's internal IP addresses. No user interaction beyond a standard file transfer is required to trigger the exposure.

The impact is the leakage of potentially sensitive network topology information. A sender's local IP addresses can reveal the structure of a private network, the presence of multiple interfaces, or the use of VPNs and Docker networks. While not directly compromising the file content, this knowledge can assist an attacker in later stages of reconnaissance or targeted attacks, and it violates the principle that metadata should be protected when end-to-end encryption is promised [1][3].

No official patch has been released as of the publication date, as the upstream author has indicated limited resources to address the issues [1]. A pull request (#700) was opened to migrate the IP information exchange to after the encryption layer is established, but it has not been merged [2]. Administrators and users should be aware that the tool's current security model does not protect this metadata and should consider network-level protections or alternative tools for sensitive transfers.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/schollz/croc/v9Go
< 9.6.169.6.16

Affected products

4

Patches

1
6f5f16aa1c16

Merge pull request #700 from schollz/issue597

https://github.com/schollz/crocZackMay 20, 2024via ghsa
1 file changed · +81 2
  • src/croc/croc.go+81 2 modified
    @@ -84,6 +84,11 @@ type Options struct {
     	GitIgnore      bool
     }
     
    +type SimpleMessage struct {
    +	Bytes []byte
    +	Kind  string
    +}
    +
     // Client holds the state of the croc transfer
     type Client struct {
     	Options                         Options
    @@ -697,12 +702,28 @@ func (c *Client) Send(filesInfo []FileInfo, emptyFoldersToTransfer []FileInfo, t
     			}
     			log.Debugf("banner: %s", banner)
     			log.Debugf("connection established: %+v", conn)
    +			var kB []byte
    +			var dataMessage SimpleMessage
    +			B, _ := pake.InitCurve([]byte(c.Options.SharedSecret[5:]), 1, c.Options.Curve)
     			for {
     				log.Debug("waiting for bytes")
     				data, errConn := conn.Receive()
     				if errConn != nil {
     					log.Debugf("[%+v] had error: %s", conn, errConn.Error())
     				}
    +				err = json.Unmarshal(data, &dataMessage)
    +				if err != nil {
    +					log.Debugf("dataMessage error unmarshalling: %v", err)
    +				} else {
    +					log.Debugf("dataMessage: %s", dataMessage)
    +				}
    +				// if kB not null, then use it to decrypt
    +				if kB != nil {
    +					data, err = crypt.Decrypt(data, kB)
    +					if err != nil {
    +						log.Debugf("error decrypting: %v", err)
    +					}
    +				}
     				if bytes.Equal(data, ipRequest) {
     					// recipient wants to try to connect to local ips
     					var ips []string
    @@ -717,9 +738,25 @@ func (c *Client) Send(filesInfo []FileInfo, emptyFoldersToTransfer []FileInfo, t
     						ips = append([]string{c.Options.RelayPorts[0]}, ips...)
     					}
     					bips, _ := json.Marshal(ips)
    +					bips, _ = crypt.Encrypt(bips, kB)
     					if err = conn.Send(bips); err != nil {
     						log.Errorf("error sending: %v", err)
     					}
    +				} else if dataMessage.Kind == "pake1" {
    +					err = B.Update(dataMessage.Bytes)
    +					if err == nil {
    +						kB, err = B.SessionKey()
    +						if err == nil {
    +							log.Debugf("dataMessage kB: %x", kB)
    +							dataMessage.Bytes = B.Bytes()
    +							dataMessage.Kind = "pake2"
    +							data, _ = json.Marshal(dataMessage)
    +							if err = conn.Send(data); err != nil {
    +								log.Errorf("dataMessage error sending: %v", err)
    +							}
    +						}
    +
    +					}
     				} else if bytes.Equal(data, handshakeRequest) {
     					break
     				} else if bytes.Equal(data, []byte{1}) {
    @@ -897,15 +934,57 @@ func (c *Client) Receive() (err error) {
     	if c.Options.TestFlag || (!usingLocal && !c.Options.DisableLocal && !isIPset) {
     		// ask the sender for their local ips and port
     		// and try to connect to them
    -		log.Debug("sending ips?")
    +		var A *pake.Pake
     		var data []byte
    -		if err = c.conn[0].Send(ipRequest); err != nil {
    +		A, err = pake.InitCurve([]byte(c.Options.SharedSecret[5:]), 0, c.Options.Curve)
    +		if err != nil {
    +			return err
    +		}
    +		dataMessage := SimpleMessage{
    +			Bytes: A.Bytes(),
    +			Kind:  "pake1",
    +		}
    +		data, _ = json.Marshal(dataMessage)
    +		if err = c.conn[0].Send(data); err != nil {
    +			log.Errorf("dataMessage send error: %v", err)
    +			return
    +		}
    +		data, err = c.conn[0].Receive()
    +		if err != nil {
    +			return
    +		}
    +		err = json.Unmarshal(data, &dataMessage)
    +		if err != nil || dataMessage.Kind != "pake2" {
    +			return fmt.Errorf("dataMessage %s pake failed", ipRequest)
    +		}
    +		err = A.Update(dataMessage.Bytes)
    +		if err != nil {
    +			return
    +		}
    +		var kA []byte
    +		kA, err = A.SessionKey()
    +		if err != nil {
    +			return
    +		}
    +		log.Debugf("dataMessage kA: %x", kA)
    +
    +		// secure ipRequest
    +		data, err = crypt.Encrypt([]byte(ipRequest), kA)
    +		if err != nil {
    +			return
    +		}
    +		log.Debug("sending ips?")
    +		if err = c.conn[0].Send(data); err != nil {
     			log.Errorf("ips send error: %v", err)
     		}
     		data, err = c.conn[0].Receive()
     		if err != nil {
     			return
     		}
    +		data, err = crypt.Decrypt(data, kA)
    +		if err != nil {
    +			return
    +		}
     		log.Debugf("ips data: %s", data)
     		var ips []string
     		if err = json.Unmarshal(data, &ips); err != nil {
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.