-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Fix command injection on PDB download #16966
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
Conversation
Seems to fail more often:
|
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.
Do you have some reproducer steps to test the various things you fixed?
933f615
to
2184566
Compare
@ret2libc updated pr description with test steps. Also, newshell is failing this: |
588ce77
to
1bb5d69
Compare
1bb5d69
to
930b445
Compare
8840369
to
c4e2872
Compare
* Also follow redirects
* Fix socket being created without a protocol
* Use select() in r_socket_ready() * Fix read failing if received only protocol answer * Fix double-free
c4e2872
to
cf7bf20
Compare
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.
Added some more comments, but I think it's almost ready!
@@ -191,6 +151,19 @@ void deinit_pdb_downloader(SPDBDownloader *pd) { | |||
pd->download = 0; | |||
} | |||
|
|||
static bool is_valid_guid(const char *guid) { |
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.
GUID are 32 chars long, aren't they? I'm not sure this function works correctly.
e.g.:
is_valid_guid('12345678901234567890123456789012') should be true
is_valid_guid('123456789012345678901234567890123') should be false
I think that currently this function does not return the right values.
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.
tested it, function works correctly
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.
Mmm, for me it doesn't. I'm using this test, where is_valid_guid
is copied-pasted from your PR.
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
static bool is_valid_guid(const char *guid) {
if (!guid) {
return false;
}
size_t i;
for (i = 0; guid[i] && i <= 33 ; i++) {
if (!isxdigit (guid[i])) {
return false;
}
}
return i == 33;
}
static void test_s(const char *s) {
if (is_valid_guid (s)) {
printf("'%s' is valid guid\n", s);
} else {
printf("'%s' is NOT valid guid\n", s);
}
}
int main(int argc, char **argv) {
test_s("12345678901234567890123456789012");
test_s("123456789012345678901234567890123");
return 0;
}
If I run this program, it says:
'12345678901234567890123456789012' is NOT valid guid
'123456789012345678901234567890123' is valid guid
but the expected output is:
'12345678901234567890123456789012' is valid guid
'123456789012345678901234567890123' is NOT valid guid
Please let me know if I'm missing something.
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.
turns out guid string has appended to it the "age", so assuming it even has a fixed length was wrong, fixed it now
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.
mh, that looks weird, but it seems it is something a bit more deeper in the existing code. Guid are 32 chars AFAIK. Nevermind.
* Use r_socket_http_get() on UNIXs * Use WinINet API on Windows for r_socket_http_get() * Fix command injection
* Remove 'r_' and '__' from static function names
01f3c5a
to
a6221f8
Compare
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.
Added some last minor stuff + doubts about is_valid_guid
. Once is_valid_guid
is fixed (or you prove me I'm doing something wrong :D) I think we can merge this. Thanks a lot for all the changes you have done!
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.
Good work! nice to see new escaping APIs, we probably need to have the unescape_sh() one too, and have more tests for them
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.
Looks good, thanks again!
* Fix r_sys_mkdirp with absolute path on Windows * Fix build with --with-openssl * Use RBuffer in r_socket_http_answer() * r_socket_http_answer: Fix read for big responses * Implement r_str_escape_sh() * Cleanup r_socket_connect() on Windows * Fix socket being created without a protocol * Fix socket connect with SSL ##socket * Use select() in r_socket_ready() * Fix read failing if received only protocol answer * Fix double-free * r_socket_http_get: Fail if req. SSL with no support * Follow redirects in r_socket_http_answer() * Fix r_socket_http_get result length with R2_CURL=1 * Also follow redirects * Avoid using curl for downloading PDBs * Use r_socket_http_get() on UNIXs * Use WinINet API on Windows for r_socket_http_get() * Fix command injection * Fix r_sys_cmd_str_full output for binary data * Validate GUID on PDB download * Pass depth to socket_http_get_recursive() * Remove 'r_' and '__' from static function names * Fix is_valid_guid * Fix for comments
Your checklist for this pull request
Detailed description
Reported in #16945, this fixes specifically the vulnerability while downloading a PDB by avoiding calling
curl
through a command and usingradare2
's own http request API, and in case of downloads from https servers with no SSL suport from the r2 api or when extracting compressed PDBs, properly escaping the PDB name with single-quotes (double-quotes on Windows).This includes fixes to compiling
radare2
with SSL support (--with-openssl
), and fixes the handshake process not being executed while connecting with SSL.Also, now r_socket_http_get() will follow redirects automatically.
Test plan
idpd
(works)idpd
(fails because no SSL support)%R2_CURL=1
idpd
(works)idpd
,pwned
file should not get created=h
to run httpserver and in another terminal, connect to it.