Following the PS3 FNIDS Python Scripts by PlayStation developer @zecoxao, today he let us know on Twitter that jarveson added PS4 NIDs and PS3 NIDs to his Hashcat bruteforcer password recovery utility. 
Download: Hashcat v3.40 / PS4 NIDs / PS3 NIDs
Intended for developers, the NIDs can be used with the attack tool to determine PlayStation 4 and PlayStation 3 System Firmware function names.
From the README.md: hashcat
hashcat is the world's fastest and most advanced password recovery utility, supporting five unique modes of attack for over 200 highly-optimized hashing algorithms.
hashcat currently supports CPUs, GPUs, and other hardware accelerators on Linux, Windows, and OSX, and has facilities to help enable distributed password cracking.
PS4 NIDs
include/interface.h
src/interface.c
src/usage.c
Download: PS4_Function_Finder.idc / GIT
NIDs Explained
What are they:
Function names, variables, etc, but obfuscated. Known as (N)ame(ID)entifiers.
How to get a nid from:
PSP
sha1 hash of string of function name or variable , grab first 4 bytes, endian swap 32
Warning: Some nids have to be manually guessed! From 3.70 at least. there is no solution to find the suffix (yet)
PSVita
sha1 hash of string of function name or variable , grab first 4 bytes, endian swap 32
Warning: Some nids have to be manually guessed! there is no solution to find the suffix (yet)
Warning2: nids like module_start, etc(NONAME) have suffix c1b886af5c31846467e7ba5e2cffd64a as key
PS3
sha1 hash of string of function name plus binary key 6759659904250490566427499489741A in hex,
grab first 4 bytes, endian swap 32
Warning: nids like module_start, etc (NONAME) have suffix bc5eba9e042504905b64274994d9c41f as binary key
PS4
sha1 hash of string of function name or variable plus binary key 518D64A635DED8C1E6B039B1C3E55230
grab first 8 bytes?, endian swap 64? and finally convert to sony's special base64
(i believe replace - with = for charset)
Bruteforcing:
Using custom hashcat.
Algos:
Download: Hashcat v3.40 / PS4 NIDs / PS3 NIDs
Intended for developers, the NIDs can be used with the attack tool to determine PlayStation 4 and PlayStation 3 System Firmware function names.
From the README.md: hashcat
hashcat is the world's fastest and most advanced password recovery utility, supporting five unique modes of attack for over 200 highly-optimized hashing algorithms.
hashcat currently supports CPUs, GPUs, and other hardware accelerators on Linux, Windows, and OSX, and has facilities to help enable distributed password cracking.
PS4 NIDs
include/interface.h
Code:
@@ -1761,6 +1761,7 @@ int filezilla_server_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_bu
int netbsd_sha1crypt_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UNUSED const hashconfig_t *hashconfig);
int atlassian_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UNUSED const hashconfig_t *hashconfig);
int ps3_nid_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UNUSED const hashconfig_t *hashconfig);
+int ps4_nid_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UNUSED const hashconfig_t *hashconfig);
/**
* hook functions
Code:
@@ -240,6 +240,7 @@ static const char HT_14900[] = "Skip32";
static const char HT_15000[] = "FileZilla Server >= 0.9.55";
static const char HT_15100[] = "Juniper/NetBSD sha1crypt";
static const char HT_16110[] = "PS3 Function NIDs";
+static const char HT_16111[] = "PS4 Function NIDs";
static const char HT_99999[] = "Plaintext";
static const char HT_00011[] = "Joomla < 2.5.18";
@@ -14456,6 +14457,43 @@ int ps3_nid_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UN
return (PARSER_OK);
}
+int ps4_nid_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UNUSED const hashconfig_t *hashconfig)
+{
+ if ((input_len < DISPLAY_LEN_MIN_16110) || (input_len > DISPLAY_LEN_MAX_16110)) return (PARSER_GLOBAL_LENGTH);
+
+ u32 *digest = (u32 *) hash_buf->digest;
+
+ salt_t *salt = hash_buf->salt;
+
+ if (is_valid_hex_string (input_buf, 8) == false) return (PARSER_HASH_ENCODING);
+
+ digest[0] = hex_to_u32 ((const u8 *) &input_buf[ 0]);
+ digest[1] = 0;
+ digest[2] = 0;
+ digest[3] = 0;
+ digest[4] = 0;
+
+ digest[0] -= SHA1M_A;
+ digest[1] -= SHA1M_B;
+ digest[2] -= SHA1M_C;
+ digest[3] -= SHA1M_D;
+ digest[4] -= SHA1M_E;
+
+ u32 salt_len = 32;
+
+ u8 salt_buf[32] = "518D64A635DED8C1E6B039B1C3E55230";
+
+ u8 *salt_buf_ptr = (u8 *) salt->salt_buf;
+
+ salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len, hashconfig);
+
+ if (salt_len != 16) return (PARSER_SALT_LENGTH);
+
+ salt->salt_len = salt_len;
+
+ return (PARSER_OK);
+}
+
int atlassian_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UNUSED const hashconfig_t *hashconfig)
{
if ((input_len < DISPLAY_LEN_MIN_12001) || (input_len > DISPLAY_LEN_MAX_12001)) return (PARSER_GLOBAL_LENGTH);
@@ -15121,6 +15159,7 @@ char *strhashtype (const u32 hash_mode)
case 15000: return ((char *) HT_15000);
case 15100: return ((char *) HT_15100);
case 16110: return ((char *) HT_16110);
+ case 16111: return ((char *) HT_16111);
case 99999: return ((char *) HT_99999);
}
@@ -22488,6 +22527,29 @@ int hashconfig_init (hashcat_ctx_t *hashcat_ctx)
hashconfig->dgst_pos3 = 3;
break;
+ case 16111: hashconfig->hash_type = HASH_TYPE_SHA1;
+ hashconfig->salt_type = SALT_TYPE_EMBEDDED;
+ hashconfig->attack_exec = ATTACK_EXEC_INSIDE_KERNEL;
+ hashconfig->opts_type = OPTS_TYPE_PT_GENERATE_BE
+ | OPTS_TYPE_ST_ADD80
+ | OPTS_TYPE_ST_ADDBITS15
+ | OPTS_TYPE_ST_HEX;
+ hashconfig->kern_type = KERN_TYPE_PS3_NID;
+ hashconfig->dgst_size = DGST_SIZE_4_5;
+ hashconfig->parse_func = ps4_nid_parse_hash;
+ hashconfig->opti_type = OPTI_TYPE_ZERO_BYTE
+ | OPTI_TYPE_PRECOMPUTE_INIT
+ | OPTI_TYPE_PRECOMPUTE_MERKLE
+ | OPTI_TYPE_EARLY_SKIP
+ | OPTI_TYPE_NOT_ITERATED
+ | OPTI_TYPE_APPENDED_SALT
+ | OPTI_TYPE_RAW_HASH;
+ hashconfig->dgst_pos0 = 0;
+ hashconfig->dgst_pos1 = 1;
+ hashconfig->dgst_pos2 = 2;
+ hashconfig->dgst_pos3 = 3;
+ break;
+
case 99999: hashconfig->hash_type = HASH_TYPE_PLAINTEXT;
hashconfig->salt_type = SALT_TYPE_NONE;
hashconfig->attack_exec = ATTACK_EXEC_INSIDE_KERNEL;
Code:
@@ -271,6 +271,7 @@ static const char *USAGE_BIG[] =
" 9900 | Radmin2 | Operating-Systems",
" 125 | ArubaOS | Operating-Systems",
" 16110 | PS3 Function NID | Operating-Systems",
+ " 16111 | PS4 Function NID | Operating-Systems",
" 7700 | SAP CODVN B (BCODE) | Enterprise Application Software (EAS)",
" 7800 | SAP CODVN F/G (PASSCODE) | Enterprise Application Software (EAS)",
" 10300 | SAP CODVN H (PWDSALTEDHASH) iSSHA-1 | Enterprise Application Software (EAS)",
Download: PS4_Function_Finder.idc / GIT
NIDs Explained
What are they:
Function names, variables, etc, but obfuscated. Known as (N)ame(ID)entifiers.
How to get a nid from:
PSP
sha1 hash of string of function name or variable , grab first 4 bytes, endian swap 32
Warning: Some nids have to be manually guessed! From 3.70 at least. there is no solution to find the suffix (yet)
PSVita
sha1 hash of string of function name or variable , grab first 4 bytes, endian swap 32
Warning: Some nids have to be manually guessed! there is no solution to find the suffix (yet)
Warning2: nids like module_start, etc(NONAME) have suffix c1b886af5c31846467e7ba5e2cffd64a as key
PS3
sha1 hash of string of function name plus binary key 6759659904250490566427499489741A in hex,
grab first 4 bytes, endian swap 32
Warning: nids like module_start, etc (NONAME) have suffix bc5eba9e042504905b64274994d9c41f as binary key
PS4
sha1 hash of string of function name or variable plus binary key 518D64A635DED8C1E6B039B1C3E55230
grab first 8 bytes?, endian swap 64? and finally convert to sony's special base64
(i believe replace - with = for charset)
Bruteforcing:
Using custom hashcat.
Algos:
- PS3, Python
Code:import sys, os import struct from hashlib import sha1 import hashlib from base64 import b64encode as base64enc from binascii import unhexlify as uhx #ref https://github.com/SocraticBliss/ps4_name2nid_plugin NEW_NIDS = {} AEROLIB = 'nids.txt' NAMES = 'ps3_names.txt' def name2nid(name): symbol = sha1(name.encode() + uhx(b'6759659904250490566427499489741A')).digest() nid = struct.unpack('<I', symbol[:4])[0] NEW_NIDS[nid]=name def save_nids(NIDS): csvFile=open(AEROLIB,"w") for nid, name in sorted(NIDS.items(), key=lambda x: x[1]): csvFile.writelines('0x%08X %s\n' % (nid, name)) csvFile.close() f = open(NAMES,"r") for line in f.readlines(): line = line.strip() name2nid(line) f.close() save_nids(NEW_NIDS)
- PS4, Python
Code:import sys, os import struct #from hashlib import sha1 import hashlib from base64 import b64encode as base64enc from binascii import unhexlify as uhx #ref https://github.com/SocraticBliss/ps4_name2nid_plugin NEW_NIDS = {} AEROLIB = 'aerolib.csv' NAMES = 'ps4_names.txt' def name2nid(name): symbol = hashlib.sha1(name.encode() + uhx('518D64A635DED8C1E6B039B1C3E55230')).digest() id = struct.unpack('<Q', symbol[:8])[0] nid = base64enc(uhx('%016x' % id), b'+-').rstrip(b'=') NEW_NIDS[nid]=name def save_nids(NIDS): csvFile=open(AEROLIB,"w") for nid, name in sorted(NIDS.items(), key=lambda x: x[1]): csvFile.writelines('%s %s\n' % (str(nid,'utf-8'), name)) csvFile.close() f = open(NAMES,"r") for line in f.readlines(): line = line.strip() name2nid(line) f.close() save_nids(NEW_NIDS)
- nidcracker (also excellent bruter but for psp)
- nid-explained
- ps4_module_loader (aerolib.csv)
- ps4libdoc
- Ps3GhidraScripts (nids.txt)
- vita-headers (db folder)