Created
August 26, 2018 10:41
-
-
Save maldevel/1d46329e00ab0c076150ddbce90d94cd to your computer and use it in GitHub Desktop.
PassCat Decrypt WinSCP passwords snippet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//https://github.com/twelvesec/passcat | |
//GNU General Public License v3.0 | |
//@maldevel | |
//... | |
int libwinscp::decrypt_char(char *hash, char **newhash, size_t *size) { | |
unsigned char hex_flag = 0xA3; | |
char charset[17] = "0123456789ABCDEF"; | |
int unpack1, unpack2, result = 0; | |
char *temp; | |
size_t hashLen = 0; | |
if (strlen(hash) > 0) { | |
temp = strchr(charset, hash[0]); | |
if (temp == NULL) { | |
return result; | |
} | |
unpack1 = (int)(temp - charset); | |
unpack1 <<= 4; | |
temp = strchr(charset, hash[1]); | |
if (temp == NULL) { | |
return result; | |
} | |
unpack2 = (int)(temp - charset); | |
result = ~((unpack1 + unpack2) ^ hex_flag) & 0xff; | |
hashLen = (strlen(hash) - 2) + 1; | |
*size = hashLen; | |
*newhash = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, hashLen); | |
if (*newhash == NULL) { | |
return 0; | |
} | |
strcpy_s(*newhash, hashLen, std::string(hash).substr(2).c_str()); | |
} | |
return result; | |
} | |
std::string libwinscp::decrypt_password(const char *username, const char *hostname, char *hash) { | |
unsigned char hex_flag = 0xFF; | |
int flag; | |
int length; | |
char *newhash = 0; | |
char *currenthash = 0; | |
size_t currenthashlen = 0; | |
int ldel; | |
size_t hashLen = 0; | |
int tempresult; | |
std::string result; | |
std::string key; | |
flag = decrypt_char(hash, &newhash, ¤thashlen); | |
currenthash = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, currenthashlen); | |
if (currenthash == NULL) { | |
if (newhash) { | |
HeapFree(GetProcessHeap(), 0, newhash); | |
newhash = NULL; | |
} | |
return ""; | |
} | |
strcpy_s(currenthash, currenthashlen, newhash); | |
if (newhash) { | |
HeapFree(GetProcessHeap(), 0, newhash); | |
newhash = NULL; | |
} | |
if (flag == hex_flag) { | |
decrypt_char(currenthash, &newhash, ¤thashlen); | |
if (currenthash) { | |
HeapFree(GetProcessHeap(), 0, currenthash); | |
currenthash = NULL; | |
} | |
currenthash = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, currenthashlen); | |
if (currenthash == NULL) { | |
if (newhash) { | |
HeapFree(GetProcessHeap(), 0, newhash); | |
newhash = NULL; | |
} | |
return ""; | |
} | |
strcpy_s(currenthash, currenthashlen, newhash); | |
if (newhash) { | |
HeapFree(GetProcessHeap(), 0, newhash); | |
newhash = NULL; | |
} | |
length = decrypt_char(currenthash, &newhash, ¤thashlen); | |
if (currenthash) { | |
HeapFree(GetProcessHeap(), 0, currenthash); | |
currenthash = NULL; | |
} | |
currenthash = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, currenthashlen); | |
if (currenthash == NULL) { | |
if (newhash) { | |
HeapFree(GetProcessHeap(), 0, newhash); | |
newhash = NULL; | |
} | |
return ""; | |
} | |
strcpy_s(currenthash, currenthashlen, newhash); | |
if (newhash) { | |
HeapFree(GetProcessHeap(), 0, newhash); | |
newhash = NULL; | |
} | |
} | |
else { | |
length = flag; | |
} | |
ldel = decrypt_char(currenthash, &newhash, ¤thashlen) * 2; | |
if (currenthash) { | |
HeapFree(GetProcessHeap(), 0, currenthash); | |
currenthash = NULL; | |
} | |
currenthash = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, currenthashlen); | |
if (currenthash == NULL) { | |
if (newhash) { | |
HeapFree(GetProcessHeap(), 0, newhash); | |
newhash = NULL; | |
} | |
return ""; | |
} | |
strcpy_s(currenthash, currenthashlen, newhash); | |
if (newhash) { | |
HeapFree(GetProcessHeap(), 0, newhash); | |
newhash = NULL; | |
} | |
hashLen = (strlen(currenthash) - ldel) + 1; | |
newhash = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, hashLen); | |
if (newhash == NULL) { | |
return ""; | |
} | |
strcpy_s(newhash, hashLen, std::string(currenthash).substr(ldel, strlen(currenthash)).c_str()); | |
if (currenthash) { | |
HeapFree(GetProcessHeap(), 0, currenthash); | |
currenthash = NULL; | |
} | |
currenthashlen = strlen(newhash) + 1; | |
currenthash = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, currenthashlen); | |
if (currenthash == NULL) { | |
if (newhash) { | |
HeapFree(GetProcessHeap(), 0, newhash); | |
newhash = NULL; | |
} | |
return ""; | |
} | |
strcpy_s(currenthash, currenthashlen, newhash); | |
if (newhash) { | |
HeapFree(GetProcessHeap(), 0, newhash); | |
newhash = NULL; | |
} | |
for (int i = 0;i < length;i++) { | |
tempresult = decrypt_char(currenthash, &newhash, ¤thashlen); | |
if (currenthash) { | |
HeapFree(GetProcessHeap(), 0, currenthash); | |
currenthash = NULL; | |
} | |
currenthash = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, currenthashlen); | |
if (currenthash == NULL) { | |
if (newhash) { | |
HeapFree(GetProcessHeap(), 0, newhash); | |
newhash = NULL; | |
} | |
return ""; | |
} | |
strcpy_s(currenthash, currenthashlen, newhash); | |
if (newhash) { | |
HeapFree(GetProcessHeap(), 0, newhash); | |
newhash = NULL; | |
} | |
result += (char)(tempresult); | |
} | |
if (flag == hex_flag) { | |
key = std::string(username); | |
key += hostname; | |
result = result.substr(key.length(), result.length()); | |
} | |
if (currenthash) { | |
HeapFree(GetProcessHeap(), 0, currenthash); | |
currenthash = NULL; | |
} | |
return result; | |
} | |
//... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment