WINSCP默认保存用户密码在注册表中的如下位置
Default
HKEY_USERS/SID/Software/Martin Prikryl/WinSCP 2/Sessions/
但是WIN7/8下WinSCP默认路径在:
Default
C:/Users/USERNAME/AppData/Local/VirtualStore/Program Files (x86)/WinSCP/WinSCP.ini (64位操作系统) C:/Program Files (x86)/WinSCP/WinSCP.ini (64位操作系统) C:/Users/USERNAME/AppData/Local/VirtualStore/Program Files/WinSCP/WinSCP.ini (32位操作系统) - 专注网络安全2 p% t+ /* j$ r- a C:/Program Files/WinSCP/WinSCP.ini (32位操作系统)
记忆中最早的就是这个
https://bitbucket.org/knarf/winscppwd/overview / s, u+ I+ P0 n3 m: [
有源码提供下载,还有编译好的程序可供下载使用
https://bitbucket.org/knarf/winscppwd/downloads/winscppwd.exe
还有就是一个GO语言的
https://github.com/anoopengineer/winscppasswd/blob/master/main.go
Default
package main import ( "fmt" "os" "runtime" "strconv" ) const ( PW_MAGIC = 0xA3 PW_FLAG = 0xFF ) func main() { args := os.Args[1:] if len(args) != 3 { fmt.Println("WinSCP stored password finder") fmt.Println("Open regedit and navigate to [HKEY_CURRENT_USER//Software//Martin Prikryl//WinSCP 2//Sessions] to get the hostname, username and encrypted password/n") if runtime.GOOS == "windows" { fmt.Println("Usage winscppasswd.exe <host> <username> <encrypted_password>") } else { fmt.Printf("Usage ./winscppasswd <host> <username> <encrypted_password>") } return } fmt.Println(decrypt(args[0], args[1], args[2])) } func decrypt(host, username, password string) string { key := username + host passbytes := []byte{} for i := 0; i < len(password); i++ { val, _ := strconv.ParseInt(string(password[i]), 16, 8) passbytes = append(passbytes, byte(val)) } var flag byte flag, passbytes = dec_next_char(passbytes) var length byte = 0 if flag == PW_FLAG { _, passbytes = dec_next_char(passbytes) length, passbytes = dec_next_char(passbytes) } else { length = flag } toBeDeleted, passbytes := dec_next_char(passbytes) passbytes = passbytes[toBeDeleted*2:] clearpass := "" var ( i byte val byte ) for i = 0; i < length; i++ { val, passbytes = dec_next_char(passbytes) clearpass += string(val) } if flag == PW_FLAG { clearpass = clearpass[len(key):] } return clearpass } func dec_next_char(passbytes []byte) (byte, []byte) { if len(passbytes) <= 0 { return 0, passbytes } a := passbytes[0] b := passbytes[1] passbytes = passbytes[2:] return ^(((a << 4) + b) ^ PW_MAGIC) & 0xff, passbytes }
附加一个java的
https://github.com/YuriMB/WinSCP-Password-Recovery/blob/master/src/main/java/Main.java
Default
import java.util.ArrayList; import java.util.List; /** * Created by Yuri Meiburg on 30-4-2015. */ public class Main { /** * ./core/Security.h:#define PWALG_SIMPLE_FLAG 0xFF */ public static final int PWALG_SIMPLE_FLAG = 0xFF; /** * ./core/Security.h:#define PWALG_SIMPLE_MAGIC 0xA3 */ public static final char PWALG_SIMPLE_MAGIC = 0xA3; public static List<Character> fPassword = new ArrayList<Character>(); public static String hostname, username; public static void main(String [] args){ if (args.length != 3) { System.exit(0); } hostname = args[0]; username = args[1]; for( int i=0; i< args[2].length(); ++i){ fPassword.add((char) Integer.parseInt(""+args[2].charAt(i),16)); } System.out.println("username = " + username); System.out.println("hostname = " + hostname); System.out.println("getPassword() = " + getPassword()); } /** * UnicodeString __fastcall TSessionData::GetPassword() const { return DecryptPassword(FPassword, UserName+HostName); } */ static String getPassword(){ return decryptPassword(fPassword, username + hostname); } /** * UnicodeString DecryptPassword(RawByteString Password, UnicodeString UnicodeKey, Integer) * { * UTF8String Key = UnicodeKey; * UTF8String Result(""); * Integer Index; * unsigned char Length, Flag; * * Flag = simpleDecryptNextChar(Password); * if (Flag == PWALG_SIMPLE_FLAG) * { * simpleDecryptNextChar(Password); * Length = simpleDecryptNextChar(Password); * } * else Length = Flag; * Password.Delete(1, ((Integer)simpleDecryptNextChar(Password))*2); * for (Index = 0; Index < Length; Index++) * Result += (char)simpleDecryptNextChar(Password); * if (Flag == PWALG_SIMPLE_FLAG) * { * if (Result.SubString(1, Key.Length()) != Key) Result = ""; * else Result.Delete(1, Key.Length()); * } * return UnicodeString(Result); *} */ static String decryptPassword(List<Character> password, String unicodeKey){ System.out.println("unicodeKey = " + unicodeKey); String key = unicodeKey; String result = ""; char length, flag; flag = simpleDecryptNextChar(password); System.out.println("flag = " + (int) flag); if(flag == PWALG_SIMPLE_FLAG){ /* Dummy = */ simpleDecryptNextChar(password); length = simpleDecryptNextChar(password); } else length = flag; System.out.println("length = " + (int) length); int newStart = ((int)simpleDecryptNextChar(password)*2); System.out.println("newStart = " + newStart + ", password.size() = " + password.size()); removeItems(password, 0, newStart); for(int index=0; index < length; ++index) result += simpleDecryptNextChar(password); System.out.println("result = " + result); if(flag == PWALG_SIMPLE_FLAG) { if (!result.substring(0, key.length()).equals(key)) result = ""; else result = result.substring(key.length()); } return result; } /** * unsigned char simpleDecryptNextChar(RawByteString &Str) { if (Str.Length() > 0) { unsigned char Result = (unsigned char) ~((((PWALG_SIMPLE_STRING.Pos(Str.c_str()[0])-1) << 4) + ((PWALG_SIMPLE_STRING.Pos(Str.c_str()[1])-1) << 0)) ^ PWALG_SIMPLE_MAGIC); Str.Delete(1, 2); return Result; } else return 0x00; } * @param str * @return */ static public char simpleDecryptNextChar(List<Character> str){ if(str.size() > 0){ char result = unsignedChar( ~( ( unsignedChar(str.get(0) << 4) + str.get(1) // Remove bitshift overflow bits. ) ^ PWALG_SIMPLE_MAGIC ) ); removeItems(str, 0, 2); return result; } else return 0x00; } /** * Cut off anything over 255. * @param v * @return */ static char unsignedChar(int v){ return (char) (v & 0xFF); } /** * Remove items from list */ static void removeItems(List lst, int start, int end){ for(int i=0; i<end-start; ++i){ lst.remove(start); } } }