Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
1 contributor

Users who have contributed to this file

155 lines (144 sloc) 3.85 KB
/* ssh2john utility, written in April of 2011 by Dhiru Kholia for GSoC.
*
* This software is Copyright (c) 2011, Dhiru Kholia <dhiru.kholia at gmail.com>,
* and it is hereby released to the general public under the following terms:
* Redistribution and use in source and binary forms, with or without modification,
* are permitted.
*
* Usage:
*
* 1. Run ssh2john on private key file(s) as "ssh2john [key file(s)]". Output
* is written to standard output.
* 2. Run JtR on the output generated by ssh2john as "john [output file]".
*
* Notes:
*
* Output Line Format: filename:$ssh2$hex-encoding-of-entire-file-contents*file-length
*
* TODO:
*
* 1. Support more formats of SSH private keys. */
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
#include <string.h>
#include <openssl/ssl.h>
#include <openssl/dsa.h>
#include <openssl/rsa.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include "misc.h"
#include "common.h"
#include "arch.h"
#include "params.h"
static void process_file(const char *filename)
{
FILE *keyfile;
int i, count;
unsigned char buffer[LINE_BUFFER_SIZE];
BIO *bp;
char *nm = NULL, *header = NULL;
unsigned char *data = NULL;
EVP_CIPHER_INFO cipher;
EVP_PKEY pk;
long len;
DSA *dsapkc = NULL;
RSA *rsapkc = NULL;
const char unsigned *dc;
if (!(keyfile = fopen(filename, "rb"))) {
fprintf(stderr, "! %s : %s\n", filename, strerror(errno));
return;
}
/* verify input files using OpenSSL */
bp = BIO_new(BIO_s_file());
if(!bp) {
fprintf(stderr, "OpenSSL BIO allocation failure\n");
return;
}
if(!BIO_read_filename(bp, filename)) {
fprintf(stderr, "OpenSSL BIO_read_filename failure\n");
ERR_print_errors_fp(stderr);
return;
}
/* PEM_bytes_read_bio function in crypto/pem/pem_lib.c
* check_pem function in crypto/pem/pem_lib.c */
for (;;) {
if (!PEM_read_bio(bp, &nm, &header, &data, &len)) {
if (ERR_GET_REASON(ERR_peek_error()) ==
PEM_R_NO_START_LINE) {
/* ERR_print_errors_fp(stderr); */
fprintf(stderr, "! %s : %s\n", filename, "input keyfile validation failed");
goto out;
}
}
if(!nm) {
fprintf(stderr, "! %s : %s\n", filename, "input keyfile validation failed");
goto out;
}
/* only PEM encoded DSA and RSA private keys are supported. */
if (!strcmp(nm, PEM_STRING_DSA)) {
pk.save_type = EVP_PKEY_DSA;
break;
}
if (!strcmp(nm, PEM_STRING_RSA)) {
pk.save_type = EVP_PKEY_RSA;
break;
}
OPENSSL_free(nm);
OPENSSL_free(header);
OPENSSL_free(data);
BIO_free(bp);
}
if (!PEM_get_EVP_CIPHER_INFO(header, &cipher)) {
ERR_print_errors_fp(stderr);
return;
}
/* check if key has no password */
dc = data;
if (PEM_do_header(&cipher, data, &len, NULL, (char *) "")) {
if (pk.save_type == EVP_PKEY_DSA) {
if ((dsapkc = d2i_DSAPrivateKey(NULL, &dc, len)) != NULL) {
fprintf(stderr, "%s has no password!\n", filename);
DSA_free(dsapkc);
goto out;
}
}
else if (pk.save_type == EVP_PKEY_RSA) {
if ((rsapkc = d2i_RSAPrivateKey(NULL, &dc, len)) != NULL) {
fprintf(stderr, "%s has no password!\n", filename);
RSA_free(rsapkc);
goto out;
}
}
}
/* key has been verified */
count = fread(buffer, 1, LINE_BUFFER_SIZE, keyfile);
printf("%s:$ssh2$", filename);
for (i = 0; i < count; i++) {
printf("%c%c", itoa16[ARCH_INDEX(buffer[i] >> 4)],
itoa16[ARCH_INDEX(buffer[i] & 0x0f)]);
}
printf("*%d\n", count);
out:
fclose(keyfile);
if(bp)
BIO_free(bp);
}
int ssh2john(int argc, char **argv)
{
int i;
/* OpenSSL init, cleanup part is left to OS */
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
if (argc < 2) {
puts("Usage: ssh2john [key file(s)]");
return 0;
}
for (i = 1; i < argc; i++)
process_file(argv[i]);
return 0;
}
You can’t perform that action at this time.