summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsijanec <anton@sijanec.eu>2021-04-11 00:24:44 +0200
committersijanec <anton@sijanec.eu>2021-04-11 00:24:44 +0200
commit2adda1079a19bc3eb6d9457e85aacd0318efc4db (patch)
treecde3f67d63bfd865eed96c231318a4281860ec13
parentfixed styles for min-width and textaress (diff)
downloadsijanec.eu-2adda1079a19bc3eb6d9457e85aacd0318efc4db.tar
sijanec.eu-2adda1079a19bc3eb6d9457e85aacd0318efc4db.tar.gz
sijanec.eu-2adda1079a19bc3eb6d9457e85aacd0318efc4db.tar.bz2
sijanec.eu-2adda1079a19bc3eb6d9457e85aacd0318efc4db.tar.lz
sijanec.eu-2adda1079a19bc3eb6d9457e85aacd0318efc4db.tar.xz
sijanec.eu-2adda1079a19bc3eb6d9457e85aacd0318efc4db.tar.zst
sijanec.eu-2adda1079a19bc3eb6d9457e85aacd0318efc4db.zip
Diffstat (limited to '')
-rw-r--r--_layouts/default.html3
-rw-r--r--_posts/2021-04-09-kako-se-znebiti-NLB-avtentikatorja.html167
-rw-r--r--_sass/main.scss4
-rw-r--r--assets/js/main.js11
4 files changed, 183 insertions, 2 deletions
diff --git a/_layouts/default.html b/_layouts/default.html
index 81d9740..c5f66a1 100644
--- a/_layouts/default.html
+++ b/_layouts/default.html
@@ -3,7 +3,7 @@
<head>
<meta charset=UTF-8 />
<title>
- {% assign htmltitle = page.title | append: "::" | append: site.name %}
+ {% assign htmltitle = page.title | append: " :: " | append: site.name %}
{{ htmltitle }}
</title>
<!-- <link rel=stylesheet href=/assets/css/styles.css /> -->
@@ -28,5 +28,6 @@
<!-- <script src=/assets/js/main.js ></script> -->
<script>{% include main.js %}</script>
{% include analitika.html %}
+ {{ page.endofbody }}
</body>
</html>
diff --git a/_posts/2021-04-09-kako-se-znebiti-NLB-avtentikatorja.html b/_posts/2021-04-09-kako-se-znebiti-NLB-avtentikatorja.html
new file mode 100644
index 0000000..658ea4e
--- /dev/null
+++ b/_posts/2021-04-09-kako-se-znebiti-NLB-avtentikatorja.html
@@ -0,0 +1,167 @@
+---
+author: anton
+title: kako se znebiti NLB avtentikatorja
+categories: alternative
+tags: alternative demonopolizacija
+lastmodified-na: 2021-03-06 21:48:00
+excerpt: Ker NLB za prijavo v spletno banko Klik ne podpira več certifikatov, temveč zgolj zaprtokodno mobilno aplikacijo za izbrane telefone, ki zahteva uporabo Googlovih storitev, sem v tej objavi pripravil algoritem za generiranje OTP žetonov kar v brskalniku in predstavil alternativo, katere obstoj je mogoč zaradi slabe implementacije OTP algoritma.
+endofbody: <script src=//cdn.sijanec.eu/etc/npm/node_modules/@otplib/preset-browser/buffer.js></script><script src=//cdn.sijanec.eu/etc/npm/node_modules/@otplib/preset-browser/index.js></script>
+---
+<p>
+ Med prijavo v banko NLB Klik sem opazil, da od petega maja letos prijava z digitalnimi potrdili ne bo več mogoča. Peti maj 2021 je torej dan, ko bodo uporabniki NLB Klika prisiljeni v uporabo mobilnih telefonov Android ali iOS, s čimer se bo dodatno utrdil monopol Googla in Appla. V tej objavi predstavim način generiranja NLB Klik gesel na svoboden način.
+</p>
+<p>
+ Sam sicer uporabljam NLB Klikin avtentikator, saj bi me digitalno potrdilo stalo 15-30 evrov, vendar sem vseeno proti uporabi le-tega. Po nekaj pokukih v NLB Klikin aplikacijo sem ugotovil, da za izdelavo gesel uporablja skrit algoritem podjetja Entrust, ki ga je verjetno NLB od omenjenega podjetja naročila. Ta algoritem uradno nima odprtokodne implementacije, NLB Klikina pa ne boste spravili na Android telefon, če le-ta nima Googlovih storitev.
+</p>
+<p>
+ V tej objavi rešitev zgolj predstavim, saj algoritma nisem ugotovil sam, <a href=//github.com/ss23/entrust-identityguard-tools>na spletu</a> pa sem našel skupek orodij, ki implementirajo ta algoritem. Ker je GitHub znan po izbrisih programov, je varnostna kopija dostopna <a href=//git.sijanec.eu/anonymous/entrust-identityguard-tools>tukaj</a>.
+</p>
+<p>
+ Za implementacijo boste enkrat še vedno potrebovali NLB Klikin aplikacijo in vse Googlove storitve.
+</p>
+<h2>
+ prvi korak: pridobitev aktivacijske kode in serijske številke
+</h2>
+<p>
+ Odprite spletno mesto <a href=https://aam.nlb.si/>aam.nlb.si</a> in se prijavite s svojim uporabniškim imenom in geslom ter po pozivu vnesite preko SMS poslano aktivacijsko kodo. Če uporabniškega imena in gesla še nimate, povprašajte na bančnem okencu. Nato izberite opcijo <b>Aktivacija generatorja enkratnih gesel OTP</b>. Če ste generator že ustvarili, lahko uporabite opcijo <b>Obnovitev generatorja OTP v mobilni aplikaciji</b> za izdelavo novega generatorja. Sistem vam poda par številk. Zapišite si ju nekam in nato aktivirajte aplikacijo NLB Klikin.
+</p>
+<h2>
+ drugi korak: izpeljava OATH ključa iz znanih podatkov
+</h2>
+<p>
+ Entrustov algoritem, kot je opisano v <a href=//medium.com/@ss23/the-poor-design-decisions-of-entrust-identityguard-soft-tokens-2d355a9fe786>objavi programerja neuradnih odprtokodnih orodij za Entrust</a>, ni zelo varen. S samo dvema bajtoma naključne entropije lahko, če vemo serijsko številko, aktivacijsko kodo in vsaj en pravilen OTP žeton, uspešno dobimo OATH ključ, s katerim lahko nato generiramo neskončno mnogo žetonov in s tem izničimo celotno prednost 2FA. Za uporabo potrebujemo 65536 poskusov krat število tridesetsekundnih intervalov v prihodnost in preteklost, ki jih želimo še šteti kot veljavne.
+</p>
+<div class="noscript nosecurecontext">
+ <p>
+ To lahko s programom `crack-otp.py`, priloženim v Git repozitoriju, avtomatiziramo. Seveda moramo imeti naložen <a href=//python.org>Python</a> in programsko knjižnico <code>oath</code>, dostopno v okviru pypi/pip repozitorijev.
+ </p>
+ <code>
+ python3 -c "import time; int(time.time());" # trenutni izpisan časovni žig uporabimo pri naslednjem ukazu
+ # sedaj hitro generiramo žeton v NLB Klikin in ga pretipkamo v spodnji ukaz
+ ./crack-otp.py [serijska številka] [aktivacijska koda] [ključ] [časovni žig]
+ </code>
+</div>
+
+<div class="yesscript yessecurecontext">
+ <p>
+ Generiranje ključa lahko avtomatiziramo. Uporabite lahko kar orodje na tej spletni strani, ki išče za vaš žeton v preteklih, trenutnih in prihodnjih 30 sekundah. Vpišite podatke iz prvega koraka in trenutni OTP žeton, izpisan v NLB Klikin aplikaciji, in pritisnite <i>izračunaj</i>.
+ </p>
+ <script>
+ function buf2hex(buffer) {
+ return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
+ }
+ async function r () {
+ e = new TextEncoder();
+ var s = e.encode(document.getElementById("s").value.replaceAll("-", "").replaceAll(" ", ""));
+ var a = document.getElementById("a").value.replaceAll("-", "").replaceAll(" ", "");
+ a = new Uint8Array(new BigInt64Array([BigInt(a.substring(0, a.length-1))]).buffer);
+ var t = new Int32Array([1]).buffer;
+ t = new Uint8Array(t);
+ if (t[0]) /* little endian */
+ a = new Uint8Array(Array.from(a).reverse());
+ while (a.length > 7) {
+ a = Array.from(a);
+ a.shift();
+ a = new Uint8Array(a);
+ }
+ console.log(a);
+ var ž = Number(document.getElementById("k").value);
+ var u = Math.floor(Date.now()/1000);
+ window.otplib.hotp.options = {digits: 8, algorithm: "sha256", encoding: "hex"};
+ var F = 0;
+ var č = Math.floor(u/30);
+ console.log("števec: "+String(č));
+ for (var i = 0; i <= 65535; i++) {
+ document.getElementById("r").innerText = Math.floor((i/65535)*100)+"%";
+ var r = Array.from(new Uint8Array(new Int16Array([i]).buffer));
+ if (t[0])
+ r = r.reverse();
+ r = new Uint8Array(Array.from(a).concat(...r));
+ var K = await window.crypto.subtle.importKey("raw", r, {name: "PBKDF2"}, false, ["deriveBits", "deriveKey"]);
+ var B = await window.crypto.subtle.deriveBits(
+ {
+ "iterations": 8,
+ "hash": "SHA-256",
+ salt: s,
+ "name": "PBKDF2"
+ },
+ K,
+ 16*8
+ );
+ var x = buf2hex(B);
+ for (var j = -1; j <= 1; j++) {
+ T = window.otplib.hotp.generate(x, Math.floor(č)+j);
+ if (T == ž) {
+ document.getElementById("r").innerHTML = "<br>najden ključ: <code>"+x+"</code><br><a href="+window.location.href.split("#")[0]+"#g="+x+">povezava do generatorja (desni klik, kopiraj, dodajte jo na namizje)</a>";
+ F++;
+ break;
+ }
+ }
+ if (F)
+ break;
+ }
+ if (!F)
+ document.getElementById("r").innerText = "ključ ni bil najden";
+ }
+ </script>
+ <input id=s placeholder="serijska številka" />
+ <input id=a placeholder="aktivacijska števika" />
+ <input id=k placeholder="trenutni žeton" />
+ <input id=i onclick=r(); type=button value="izračunaj" />
+ <span id=r >[rešitev bo prikazana tukaj]</span>
+</div>
+<p>
+ Po slabi minuti nam program izpljune nekajznačno šestnajstiško zaporedje, ki ga lahko vpišemo v katerokoli odprtokodno programje za generiranje OTP gesel. Lahko uporabimo recimo <code>oathtool</code>, dostopen v Linux distribucijah:
+</p>
+<code>
+ sudo apt install oathtool
+ oathtool -v --totp=sha256 --digits=8 [nekajznačno šestnajstiško zaporedje]
+</code>
+<p>
+ in dobimo pravilen OTP žeton za prijavo v NLB Klik. Sedaj si moramo zgolj nekam zapisati to šestnajstiško zaporedje, aktivacijsko in serijsko številko lahko pozabimo, prav tako si lahko izbrišemo NLB Klikin.
+</p>
+<div class=yesscript>
+ <h2 id=generator-otp-žetonov>
+ generator OTP žetonov
+ </h2>
+ <p>
+ Za generiranje žetonov lahko med drugimi uporabljate tudi vgrajen TOTP generator na tej spletni strani. Povezavo, ki vam jo generira zgornji generator ključev, si shranite na namizje IN JE NE DELITE Z NIKOMER. Ob odprtju povezave vam bo generator vsakih 30 sekund avtomatično generiral žeton za NLB Klik pod tem odstavkom.
+ </p>
+ <p id=g>
+ Če bi bili sedaj na posebni povezavi, s katero generirate žetone, bi se tukaj izpisal trenutno veljaven žeton. Če ste na tej povezavi, očitno nekaj ne deluje.
+ </p>
+ <script>
+ var h;
+ window.onhashchange = function () {
+ h = window.location.hash.split("=").pop();
+ document.getElementById("generator-otp-žetonov").scrollIntoView();
+ };
+ document.addEventListener("DOMContentLoaded", function () {
+ window.otplib.hotp.options = {digits: 8, algorithm: "sha256", encoding: "hex"};
+ h = window.location.hash.split("=").pop();
+ if (h != "")
+ document.getElementById("generator-otp-žetonov").scrollIntoView();
+ });
+ setInterval(function() {
+ if (h != "") {
+ console.log(h);
+ document.getElementById("g").innerText = window.otplib.hotp.generate(h, Math.floor(Math.floor(Date.now()/1000)/30));
+ }
+ }, 1000);
+ </script>
+</div>
+<h2>
+ omejitev odgovornosti in politika zasebnosti glede te objave
+</h2>
+<p>
+ Ker je govora o kočljivi temi (bančnih računih) se mi zdi prav, da povem, da je generator tukaj zgolj kot dokaz koncepta in ni primeren za vsakdanjo uporabo. Nanj se ne zanašajte in ne uporabljajte ga kot primarno sredstvo za dostop do banke, da enkrat ne boste ostali brez dostopa! Vse, kar se generira in obdeluje v okviru teh dveh orodij na strani (generiranje in krekanje žetonov), se dogaja v brskalniku, žetoni se ne pošiljajo nikamor. Vedite, da nisem odgovoren za posledice pridobitve žetonov s strani tretjih oseb in za morebitne izgube denarja zaradi uporabe teh programov.
+</p>
+<h2>
+ zaključek
+</h2>
+<p>
+ Še vedno nismo povsem eliminirali NLB Klikin aplikacije, saj le-ta poskrbi za avtomatsko aktivacijo tega ključa. Verjetno se lahko temu koraku izognemo, če nam uspe prodreti še v zakulisje procesa aktivacije. Naročite se na RSS, če želite dobivati obvestila o objavah.
+</p>
+<p>
+ LP in se beremo naslednjič!
+</p>
diff --git a/_sass/main.scss b/_sass/main.scss
index 608e0cc..fbe1b9c 100644
--- a/_sass/main.scss
+++ b/_sass/main.scss
@@ -160,3 +160,7 @@ code {
color: var(--fgcodec);
background-color: var(--bgcodec);
}
+
+.yesscript {
+ display: none; /* odstrto z javascriptom kasneje. uporabi to kot nasprotje <noscript> */
+}
diff --git a/assets/js/main.js b/assets/js/main.js
index edbed49..1faa8fe 100644
--- a/assets/js/main.js
+++ b/assets/js/main.js
@@ -20,4 +20,13 @@ if (document.location.protocol != "https:"
console.log("ne bom predlagal HTTPS, ker HTTPS ne deluje, ker: "+error);
});
}
-document.querySelectorAll(".commentform").forEach((c)=>{c.parentElement.previousElementSibling.checked=false}); // enovrstičnica, ki skrije komentar-forme, če checkbox statusi ostanejo po reloadu.
+document.querySelectorAll(".commentform").forEach((c)=>{c.parentElement.previousElementSibling.checked=false}); // enovrstičnica, ki skrije komentar-forme, če checkbox statusi ostanejo po reloadu. (firefox)
+document.querySelectorAll(".yesscript").forEach((c)=>{c.style.display="block"}); /* enovrstičnica, ki s classom naredi alt noscri */
+document.querySelectorAll(".noscript").forEach((c)=>{c.hidden=true}); /* enovrstičnica, ki z atributom naredi alternativ noscript */
+if (window.isSecureContext) { /* večvrstičnica, ki bodisi skrije bodisi pokaže yessecurecontext in nosecurecontext elemente */
+ document.querySelectorAll(".yessecurecontext").forEach((c)=>{c.hidden=false});
+ document.querySelectorAll(".nosecurecontext").forEach((c)=>{c.hidden=true});
+} else {
+ document.querySelectorAll(".nosecurecontext").forEach((c)=>{c.hidden=false});
+ document.querySelectorAll(".yessecurecontext").forEach((c)=>{c.hidden=true});
+}