Skip to content

Instantly share code, notes, and snippets.

@ei-grad
Last active December 29, 2015 03:29
Show Gist options
  • Select an option

  • Save ei-grad/7608467 to your computer and use it in GitHub Desktop.

Select an option

Save ei-grad/7608467 to your computer and use it in GitHub Desktop.
Find EC private key in the memory dump
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <openssl/ssl.h>
#include <openssl/ec.h>
const char usage[] = "using: %s <memdump.raw> <cert.pem>\n";
int main(int argc, char * argv[]) {
int ret = 1;
FILE *f;
void *data;
long len;
SSL_load_error_strings();
SSL_library_init();
OPENSSL_config();
if (argc != 3) {
printf(usage, argv[0]);
return 1;
}
argc--; argv++;
/* Reading data */
f = fopen(*argv, "rb");
if (f == NULL) {
fprintf(stderr, "Can't open memory dump %s: %s\n", *argv, strerror(errno));
exit(1);
}
argc--; argv++;
ret = fseek(f, 0, SEEK_END);
if (ret == -1) {
perror("fseek failed");
exit(1);
}
len = ftell(f);
if (len == -1) {
perror("Can't determine file size");
exit(1);
}
ret = fseek(f, 0, SEEK_SET);
if (ret == -1) {
perror("fseek failed");
exit(1);
}
data = malloc(len);
ret = fread(data, (size_t)len, (size_t)1, f);
if (ret == 0) {
perror("can't read data");
exit(1);
}
ret = fclose(f);
if (ret == EOF) {
perror("fclose failed");
exit(1);
}
/* Loading certificate */
f = fopen(*argv, "rb");
if (f == NULL) {
fprintf(stderr, "Can't open certificate file %s: %s\n", *argv, strerror(errno));
exit(1);
}
argc--; argv++;
X509 *crt = PEM_read_X509(f, NULL, NULL, NULL);
if (crt == NULL) {
fprintf(stderr, "Can't load X509 certificate from %s: %s\n",
*argv, ERR_reason_error_string(ERR_get_error()));
exit(1);
}
ret = fclose(f);
if (ret == EOF) {
perror("fclose failed");
exit(1);
}
BIO *STDout = BIO_new_fp(stdout, BIO_NOCLOSE);
if (STDout == NULL) {
ERR_print_errors_fp(stderr);
exit(1);
}
EVP_PKEY *x509_pubkey = X509_get_pubkey(crt);
printf("Searching for a Private key of ");
EVP_PKEY_print_public(STDout, x509_pubkey, 0, NULL);
long m;
int l;
BIGNUM *priv_key = BN_new();
EC_KEY *ec = EVP_PKEY_get0(x509_pubkey);
if (!ec) {
printf("Can't get EC_KEY from public key!\n");
ERR_print_errors_fp(stderr);
exit(1);
}
const EC_POINT *pubkey = EC_KEY_get0_public_key(ec);
const EC_GROUP *group = EC_KEY_get0_group(ec);
BN_CTX *ctx = BN_CTX_new();
BN_CTX_start(ctx);
for(l=31; l<34; l++) {
printf("Trying to find matching %d bytes sequence", l);
m = len - l;
int i;
for (i=0; i <= m; i++) {
if (i % (1024) == 0) {
printf(".");
fflush(stdout);
}
priv_key = BN_bin2bn((char*)data + i, l, priv_key);
EC_POINT *pkey = EC_POINT_new(group);
if(!EC_POINT_mul(group, pkey, priv_key, NULL, NULL, ctx)) {
printf("EC_POINT_mul failed!\n");
ERR_print_errors_fp(stderr);
continue;
}
if (EC_POINT_cmp(group, pkey, pubkey, ctx) == 0) {
printf("\n\nKey found: ");
BN_print_fp(stdout, priv_key);
printf("\n");
exit(0);
}
EC_POINT_free(pkey);
}
printf(" not found.\n");
}
return 0;
}
#!/usr/bin/env python2
import sys
import binascii
from textwrap import wrap
from base64 import b64encode
from ctypes import CDLL
from M2Crypto import BIO, SMIME
ssl = CDLL('libssl.so')
def raw2der(k):
d = '0E\x02\x01\x000\x1c\x06\x06*\x85\x03\x02\x02\x130\x12\x06\x07*\x85\x03\x02\x02$\x00\x06\x07*\x85\x03\x02\x02\x1e\x01\x04' + chr(len(k) + 2) + chr(2) + chr(len(k)) + k
return d[0:1] + chr(len(d) - 2) + d[2:]
def der2pem(k):
return '-----BEGIN PRIVATE KEY-----\n' + '\n'.join(wrap(b64encode(k), 64)) + '\n-----END PRIVATE KEY-----\n'
def check(k, crt):
s = SMIME.SMIME()
s.load_key_bio(BIO.MemoryBuffer(der2pem(k)), BIO.File(open(crt)))
s.sign(BIO.MemoryBuffer('qwe'))
def conf():
ssl.OPENSSL_config()
if __name__ == "__main__":
if len(sys.argv) != 3:
print('Usage: %s <memdump.raw> <cert.pem>' % sys.argv[0])
sys.exit(1)
conf()
log = open('log.txt', 'w')
data = open(sys.argv[1], 'rb').read()
for l in range(31, 34):
print('Searching for key with length %d' % l)
for i in range(len(data) + 1 - l):
try:
key = data[i:i+l]
check(raw2der(key), sys.argv[2])
print("Key found: %s" % binascii.b2a_hex(key))
print(der2pem(raw2der(key)))
break
except Exception as e:
log.write(str(e))
log.write('\n')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment