-->
当前位置:首页 > DayDayUp > 正文内容

Finalshell密码批量解密(工具)

Luz6个月前 (11-16)DayDayUp1677

经常忘记服务器密码,finalshell里保存了又不能查看


默认配置文件目录

C:\Users\用户名\AppData\Local\finalshell\conn


核心解密代码

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.Random;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

public class FinalShellDecodePass {
    public static void main(String[] args)throws Exception {
        System.out.println(decodePass("VS8vGQ5RYU+G1SR5OIMPUybgeZbWTc/t"));
    }
    public static byte[] desDecode(byte[] data, byte[] head) throws Exception {
        SecureRandom sr = new SecureRandom();
        DESKeySpec dks = new DESKeySpec(head);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey securekey = keyFactory.generateSecret(dks);
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(2, securekey, sr);
        return cipher.doFinal(data);
    }
    public static String decodePass(String data) throws Exception {
        if (data == null) {
            return null;
        } else {
            String rs = "";
            byte[] buf = Base64.getDecoder().decode(data);  //base64 decode
            byte[] head = new byte[8];
            System.arraycopy(buf, 0, head, 0, head.length);  //取解码后前8字节
            byte[] d = new byte[buf.length - head.length];
            System.arraycopy(buf, head.length, d, 0, d.length); //取剩余字节
            byte[] bt = desDecode(d, ranDomKey(head));   //des解密,密文为d,前8字节计算key
            rs = new String(bt);

            return rs;
        }
    }
    static byte[] ranDomKey(byte[] head) {
        long ks = 3680984568597093857L / (long)(new Random((long)head[5])).nextInt(127);
        Random random = new Random(ks);
        int t = head[0];

        for(int i = 0; i < t; ++i) {
            random.nextLong();
        }

        long n = random.nextLong();
        Random r2 = new Random(n);
        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]};
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(bos);
        long[] var15 = ld;
        int var14 = ld.length;

        for(int var13 = 0; var13 < var14; ++var13) {
            long l = var15[var13];

            try {
                dos.writeLong(l);
            } catch (IOException var18) {
                var18.printStackTrace();
            }
        }

        try {
            dos.close();
        } catch (IOException var17) {
            var17.printStackTrace();
        }

        byte[] keyData = bos.toByteArray();
        keyData = md5(keyData);
        return keyData;
    }
    public static byte[] md5(byte[] data) {
        String ret = null;
        byte[] res=null;

        try {
            MessageDigest m;
            m = MessageDigest.getInstance("MD5");
            m.update(data, 0, data.length);
            res=m.digest();
            ret = new BigInteger(1, res).toString(16);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return res;
    }
}

代码很多,但是都大同小异,需要用java去生成随机数序列,这点无法用python去实现,关键时候电脑可能没有java环境,所以做了个api来在线解密





遍历文件夹解密

本地的json也很多,一个一个扒password太慢,顺便python打包了个程序去遍历当前用户的finalshell数据文件夹

效果:1700131434374.png

程序下载(会把加密的密文上传到我的服务器,介意慎用)

Finalshell配置文件解密.zip



一个Web_Demo

http://150.158.156.12:50000



源代码

客户端

import os
import requests
import json
def list_files(directory):
    # 获取目录中的所有文件和子目录
    files = os.listdir(directory)
    ret_list=[]
    # 遍历所有文件和子目录
    for file in files:
        # 获取文件或子目录的完整路径
        full_path = os.path.join(directory, file)

        # 判断是否为文件
        if os.path.isfile(full_path):
#            print(f"文件: {full_path}")
            ret_list.append(full_path)
    return ret_list



# 获取当前用户目录
user_home = os.path.expanduser("~")
print("当前用户目录:", user_home)
finalshell_dir=user_home+'\\AppData\\Local\\finalshell\\conn'
print(finalshell_dir)
use_dir=''
if os.path.exists(finalshell_dir):
    print(f"自动检测到finalshell配置文件路径:'{finalshell_dir}'")
    use_dir=input('请输入配置文件路径,为空则使用自动检测路径:')
    if(use_dir==''):
        use_dir=finalshell_dir
else:
    use_dir=input('未检测到配置文件路径,请手动输入:')

print(f"使用finalshell配置文件路径:'{use_dir}'")
json_list=list_files(use_dir)
if json_list != []:
    for i in json_list:
        try:
            f=open(i)
            tmp=f.read()
            f.close()
            json_info=json.loads(tmp)
            name=json_info['name']
            user_name=json_info['user_name']
            port=json_info['port']
            host=json_info['host']
            password=json_info['password']
            data={
                'encrypted_text':password
            }
            result=json.loads(requests.post('http://150.158.156.12:50000/decrypt',json=data).text)['decrypted_result']
            print(f"{name}\t{host}\t{port}\t{user_name}\t{result}")
        except:
            print('err')
else:
    print('请检查目录')


服务端

#coding:utf-8
from flask import Flask, request, jsonify
import subprocess

app = Flask(__name__)

html="""
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Finalshell密码解密</title>
</head>
<body>

<div>
    <label for="encryptedText">Encrypted Text:</label>
    <input type="text" id="encryptedText" placeholder="Enter encrypted text">
    <button onclick="decrypt()">解密</button>

</div>


<div>
    <label for="decryptedResult">Decrypted Result:</label>
    <textarea id="decryptedResult" rows="4" cols="50" readonly></textarea>
</div>

<script>
    function decrypt() {
        // 获取输入的密文
        const encryptedText = document.getElementById('encryptedText').value;

        // 发送POST请求给后端
        fetch('/decrypt', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ 'encrypted_text': encryptedText })
        })
        .then(response => response.json())
        .then(data => {
            // 更新解密结果文本框
            document.getElementById('decryptedResult').value = data.decrypted_result || data.error || 'Error occurred.';
        })
        .catch(error => {
            console.error('Error:', error);
            document.getElementById('decryptedResult').value = 'Error occurred.';
        });
    }
</script>

</body>
</html>

"""

@app.route('/', methods=['GET'])
def main():
 return html




@app.route('/decrypt', methods=['POST'])
def decrypt():
 try:
 encrypted_text = request.json.get('encrypted_text')

 # 调用Java程序执行解密
 java_command = ['java', 'main', encrypted_text]
 #return(java_command)
 result = subprocess.run(java_command, stdout=subprocess.PIPE)


 # 获取解密结果
 decrypted_result = result.stdout.decode('utf-8').strip()

 # 返回解密结果给前端
 return jsonify({'decrypted_result': decrypted_result})

 except Exception as e:
 return jsonify({'error': str(e)})

if __name__ == '__main__':
 app.run(host='0.0.0.0',port=50000)



发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。