Now that we’ve gotten the SSL library identified in IDA (see last post), it’s time to change the certificate validation mode. This is useful when you want to use a cert that isn’t inside the certificate store, like a self-signed localhost cert.
First we start by finding where SSL_CTX_get_verify_callback
is used. We can search for the function then right-click -> Jump to xref to operand
. You can also place your caret on the function name and use the shortcut X
.
It only had one use in my case:
Disassembly
Assembly view
mov rcx, [rbx+8]
call SSL_CTX_get_verify_callback
mov r8, rax
mov edx, 1
mov rcx, [rbx+8]
call SSL_CTX_set_verify
C view
verify_callback = SSL_CTX_get_verify_callback(*(_QWORD *)(v13 + 8));
SSL_CTX_set_verify(*(_QWORD *)(v13 + 8), 1, verify_callback);
Function signatures
int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int, X509_STORE_CTX *);
void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *));
Let’s take this one line at a time. Compared to x86 assembly, instead of pushing arguments to the stack the compiler sets registers instead. The arguments are set in reverse order.
x86_64 Assembly | C | Description |
---|---|---|
mov rcx, [rbx+8] |
verify_callback = SSL_CTX_get_verify_callback(*(_QWORD *)(v13 + 8)) |
Set the parameter for SSL_CTX_get_verify_callback to the value in [rbx+8] . |
call SSL_CTX_get_verify_callback |
verify_callback = SSL_CTX_get_verify_callback(*(_QWORD *)(v13 + 8)) |
Call the function, the result will be stored in rAX. |
mov r8, rax |
SSL_CTX_set_verify(*(_QWORD *)(v13 + 8), 1, verify_callback) |
Set the 3rd parameter for SSL_CTX_set_verify, which is the callback. |
mov edx, 1 |
SSL_CTX_set_verify(*(_QWORD *)(v13 + 8), 1, verify_callback) |
Set the 2nd parameter for SSL_CTX_set_verify, which is the mode. |
mov rcx, [rbx+8] |
SSL_CTX_set_verify(*(_QWORD *)(v13 + 8), 1, verify_callback) |
Set the 1st parameter for SSL_CTX_set_verify, which is the context. |
call SSL_ctx_set_verify |
SSL_CTX_set_verify(*(_QWORD *)(v13 + 8), 1, verify_callback) |
Call the function to set the verify callback/mode in the context. |
We want to change set_verify’s 2nd argument to use SSL_VERIFY_NONE
(0) instead of SSL_VERIFY_PEER
(1).
Patching
We understand what we’re looking for now – we want to replace the instruction mov edx, 1
to mov edx, 0
.
The hex here shows BA 01 00 00 00
. BA is the opcode for mov eDX
. Its operand is a 32-bit immediate value. We’ll simply want to change this to BA 00 00 00 00
!
You can hex edit the executable directly or write a script to do it, or save a binary diff patch. Either way – that’s all folks.
References
- https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_get_verify_callback.html
- https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_set_verify.html
- https://stackoverflow.com/a/11130969