SeBi (18.05.2020)
Thema: [Passwort] Login ab V9.0cab
-
16.05.2020, 23:34 #1
- Registriert seit
- 28.10.2011
- Beiträge
- 625
Thanked 279 Times in 168 Posts[Passwort] Login ab V9.0cab
Ich bin seit gestern dabei, Basis-Klassen für Bots zu erstellen. Hierzu bin ich nun bei dem Password-Hashing angelangt.
Mir ist aufgefallen, dass Knuddels die Passwörter nun nicht mehr (normal) im alten Schema hasht.
Damals wurden aus den Passwörtern ein positiver bzw. negativer Integerwert kalkuliert und direkt im Login-Paket untergebracht (hier als Beispiel -123456):
Code:n\0CHANNEL\0NICKNAME\0PASSWORD\0LOGIN_FLAGS
Code:n\0Flirt\0James\0-123456\0T
Die neuen Passwort-Hashes fangen immer mit einem 0~ an:
Code:0~HASH
Code:30 7E 3b 11 16 3E 72 5D 3C 69 04 (0~;>r]<i) 30 7E 22 27 25 13 4E 19 04 58 79 (0~"'%NXy) 30 7E 70 4d 25 0B 74 3E 36 19 1D (0~pM%t>6)
Folgendes Popup wird hier zurückgesendet:
Keine Aufregung, es könnte...
...die Speicherdauer deines Passworts in der Desktop App abgelaufen sein. Das machen wir zu deinem Schutz. Tippe deshalb dein Passwort einfach nochmals ein und achte auch auf mögliche Groß- und Kleinschreibung.
Man glaubt es kaum...
...doch hin und wieder irrt oder vertippt man sich bei der exakten Schreibweise des Accounts.
Du möchtest ein neues Passwort setzen?
Besuche https://www.knuddels.de/pwd.html und trage dort deinen Nicknamen ein.Geändert von Bubble Gum (16.05.2020 um 23:39 Uhr)
-
17.05.2020, 04:38 #2
- Registriert seit
- 31.12.2012
- Beiträge
- 117
Thanked 237 Times in 71 PostsAW: [Passwort] Login ab V9.0cab
Was ich bisher rausgefunden habe das 0~ ist einfach immer, war in früheren Applet Versionen das alte Hashing und nach "~" war früher einfach eine zweit Version des XOR Algorithmus womit man den Hash wieder zurück wandeln konnte.
Hab das die Tage auch schon mal versucht das in .Net zu rekonstruieren, leider ohne Erfolg.
Die Speicherdauer ist Client intern so weit ich weiß, wenn man schon mal im Client eingeloggt war werden auch im Handshake irgend welche Auth Daten übertragen, muss das noch mal genauer anschauen aber an sich sollte man sic über das normale Login-Paket ("n\0...") einloggen können.
Kannst ja mal schauen ob dir das was hilft, hab alle Methoden in eine eigene Klasse kopiert.
Dder Hash stimmt mit mehrmals getestet.
Wäre nice wenn du es hin bekommst es zu extrahieren.
https://mega.nz/file/zVoSySbQ#nMSGQC...3hsZgLP8ZwTOTQ
Code:import java.text.DateFormat; import java.util.Date; public class Password { public String vg(String var1, String var2, String var3, boolean var4) { byte var14; String var15; Password var10000; int var18; if(this.ow && ch && this.xk) { try { Object var5 = this.n1().l("firstTry"); if(var5 == null) { var10000 = this; var14 = -1; var18 = var14 + 1; var15 = "0"; switch(Integer.parseInt(var15)) { case 0: this.p(1, "stApp.firstTryUniqA"); var10000 = this; var18 += 15; var15 = "26"; break; default: var18 += 7; } var10000.n1().t("firstTry", Boolean.TRUE); } this.ow = false; } catch (Exception var16) { this.p(1, "stApp.exception.firstTry"); var16.printStackTrace(); } } String var17 = this.f4(); int var10002; String var20; int var21; String var23; String var28; StringBuilder var29; StringBuilder var32; if(var17 != null && !var17.equalsIgnoreCase(var1)) { if(fw.g(this)) { var32 = new StringBuilder(); var14 = -1; var18 = var14 + 1; var15 = "0"; switch(Integer.parseInt(var15)) { case 0: var32 = var32.append("Logout ").append(var17); var18 += 8; var15 = "26"; break; default: var18 += 11; var21 = 5 / 22; } switch(var18) { case 0: var18 += 12; var20 = null; var29 = null; break; default: var20 = var32.toString(); var29 = new StringBuilder(); var18 = 0; var15 = "0"; } switch(Integer.parseInt(var15)) { case 0: var29 = var29.append("Logout ").append(var17); var18 += 12; var15 = "26"; break; default: var18 += 14; var10002 = 8 - 16; } Password var10003; switch(var18) { case 0: var18 += 15; var28 = null; var23 = null; var10003 = null; break; default: var28 = var29.toString(); var23 = "Du hast noch mehrere Fenster offen.#Möchtest du wirklich alle Fenster schließen?"; var10003 = this; var18 = 0; var15 = "0"; } short var10004; short var10005; byte var10006; switch(Integer.parseInt(var15)) { case 0: var10004 = 450; var10005 = 310; var10006 = 2; var18 += 15; var15 = "26"; break; default: var18 += 8; var10004 = 256; var10005 = 256; var10006 = 1; } String[] var10007; byte var10008; String[] var27; switch(var18) { case 0: var18 += 7; var27 = null; var10007 = null; var10008 = 0; break; default: var27 = new String[var10006]; var10007 = var27; var10008 = var18 = 0; var15 = "0"; } switch(Integer.parseInt(var15)) { case 0: var10007[var10008] = " Logout "; var10007 = var27; var18 += 6; var15 = "26"; break; default: var18 += 9; } switch(var18) { case 0: var18 += 8; break; default: var10007[1] = " Abbrechen "; var18 = 0; var15 = "0"; } String[] var30; switch(Integer.parseInt(var15)) { case 0: var10007 = new String[2]; var30 = var10007; var18 += 13; var15 = "26"; break; default: var18 += 11; var10007 = null; var30 = null; } switch(var18) { case 0: var18 += 11; break; default: var30[0] = "/closeAllWindowsLogin"; var18 = 0; var15 = "0"; } byte var10009; Object var10010; switch(Integer.parseInt(var15)) { case 0: var30 = var10007; var10009 = 1; var10010 = null; var18 += 8; var15 = "26"; break; default: var18 += 7; var30 = null; var10009 = 1; var10010 = null; } var30[var10009] = (String)var10010; x8.v(var20, var28, var23, var10003, var10004, var10005, var27, var10007); return "confirmationStarted"; } fw.f(this); } String var6 = null; kx var7 = this.tn(var3); if(var7 != null || this.pc()) { var6 = "gf nul"; } if(var7 == null) { if(!this.pc()) { this.q8(var3); if(syr.a1(var1)) { var1 = " "; } if(syr.a1(var2)) { var2 = " "; } var20 = this.mr; var14 = -1; var18 = var14 + 1; var15 = "0"; String var8; int var9; switch(Integer.parseInt(var15)) { case 0: var8 = var20; var9 = 0; var18 += 15; var15 = "26"; break; default: var18 += 14; var8 = null; var9 = 1; } String var10; switch(var18) { case 0: var18 += 7; var10000 = var10 = null; break; default: var10 = "Dwi"; var10000 = this; var18 = 0; var15 = "0"; } switch(Integer.parseInt(var15)) { case 0: var20 = var10000.gm(var8, "vkUEOGHMFeh"); var18 += 15; var15 = "26"; break; default: var18 += 11; var20 = null; } int var22; switch(var18) { case 0: var18 += 15; var22 = 1; break; default: var8 = var20; var22 = var8.length(); var18 = 0; var15 = "0"; } switch(Integer.parseInt(var15)) { case 0: var9 = var22 / 2; var18 += 9; var15 = "26"; break; default: var18 += 14; } switch(var18) { case 0: var18 += 13; var22 = 1; break; default: var22 = var9 * var9; var18 = 0; var15 = "0"; } byte var10001; switch(Integer.parseInt(var15)) { case 0: var22 += var9; var10001 = 12; var18 += 9; var15 = "26"; break; default: var18 += 14; var10001 = 0; } switch(var18) { case 0: var18 += 11; var21 = 1; break; default: var22 += var10001; var21 = var8.length(); var18 = 0; var15 = "0"; } switch(Integer.parseInt(var15)) { case 0: var9 = var22 % var21; var22 = var9; var18 += 14; var15 = "26"; break; default: var18 += 6; } switch(var18) { case 0: var18 += 7; var21 = 1; break; default: var22 *= 37; var21 = var8.length(); var18 = 0; var15 = "0"; } switch(Integer.parseInt(var15)) { case 0: var9 = var22 % var21; var22 = var9; var18 += 7; var15 = "26"; break; default: var18 += 11; } switch(var18) { case 0: var18 += 13; var21 = 1; break; default: var22 *= var22; var21 = var9; var18 = 0; var15 = "0"; } switch(Integer.parseInt(var15)) { case 0: var22 = var22 + var21 + 14; var18 += 12; var15 = "26"; break; default: var18 += 13; } switch(var18) { case 0: var18 += 14; var21 = 11 + 38; break; default: var22 %= var8.length(); var18 = 0; var15 = "0"; } char var31; switch(Integer.parseInt(var15)) { case 0: var9 = var22; var31 = var8.charAt(var9); var18 += 15; var15 = "26"; break; default: var18 += 5; var31 = 1; } switch(var18) { case 0: var18 += 8; var22 = 1; var21 = 1; break; default: var22 = var31 + 2; var21 = var8.length(); var18 = 0; var15 = "0"; } switch(Integer.parseInt(var15)) { case 0: var9 = var22 % var21; var32 = new StringBuilder(); var18 += 15; var15 = "26"; break; default: var18 += 13; var32 = null; } char var26; switch(var18) { case 0: var18 += 6; var26 = 1; break; default: var26 = var8.charAt(var9); var18 = 0; var15 = "0"; } switch(Integer.parseInt(var15)) { case 0: var32 = var32.append(var26); var28 = this.gm(var8, "RB"); var18 += 3; var15 = "26"; break; default: var18 += 7; var28 = null; } switch(var18) { case 0: var18 += 6; break; default: var8 = var32.append(var28).toString(); var18 = 0; var15 = "0"; } switch(Integer.parseInt(var15)) { case 0: var10000 = this; var29 = new StringBuilder(); var18 += 5; var15 = "26"; break; default: var18 += 14; var10000 = null; var29 = null; } switch(var18) { case 0: var18 += 9; var10002 = 1; break; default: var10002 = this.ca(var8); var18 = 0; var15 = "0"; } switch(Integer.parseInt(var15)) { case 0: var29 = var29.append(var10002 ^ 1640034174); var18 += 11; var15 = "26"; break; default: var18 += 7; } switch(var18) { case 0: var18 += 12; var28 = null; break; default: var28 = var29.append("").toString(); var18 = 0; var15 = "0"; } switch(Integer.parseInt(var15)) { case 0: var8 = var10000.gm(var28, var8); var18 += 15; var15 = "26"; break; default: var18 += 5; } switch(var18) { case 0: var18 += 6; var20 = null; break; default: var20 = ue(var2, var8); boolean var19 = false; var15 = "0"; } String var11 = i0(var20); boolean var12; if(var4) { var12 = !this.ea.r.m(); } else { var12 = !this.zb(var3); } var29 = new StringBuilder(); var14 = -1; var18 = var14 + 1; var15 = "0"; switch(Integer.parseInt(var15)) { case 0: var29 = var29.append("n"); var23 = qd; var18 += 9; var15 = "26"; break; default: var18 += 8; var23 = null; } switch(var18) { case 0: var18 += 11; break; default: var29 = var29.append(var23).append(var3); var18 = 0; var15 = "0"; } switch(Integer.parseInt(var15)) { case 0: var29 = var29.append(qd).append(var1); var18 += 10; var15 = "26"; break; default: var18 += 5; var10002 = 5 + 17; } char var24; switch(var18) { case 0: var18 += 15; var24 = 0; break; default: var29 = var29.append(qd); var24 = 48; var18 = 0; var15 = "0"; } switch(Integer.parseInt(var15)) { case 0: var29 = var29.append(var24).append('~'); var18 += 3; var15 = "26"; break; default: var18 += 5; } boolean var13 = this.km(var29.append(var11).append(qd).append(var12?"T":"F").toString()); if(var13) { x8.o7(this); } else { var6 = "discon"; } } } else if(var7.bs()) { _ux.fd(var7); var7.show(); } if(var6 == null) { var32 = new StringBuilder(); var14 = -1; var18 = var14 + 1; var15 = "0"; DateFormat var33; switch(Integer.parseInt(var15)) { case 0: var32 = var32.append("JOIN sent "); var33 = DateFormat.getDateTimeInstance(); var18 += 7; var15 = "26"; break; default: var18 += 8; var33 = null; } Date var25; switch(var18) { case 0: var18 += 9; var25 = null; break; default: var25 = new Date(); var18 = 0; var15 = "0"; } switch(Integer.parseInt(var15)) { case 0: var20 = var32.append(var33.format(var25)).toString(); var18 += 8; var15 = "26"; break; default: var18 += 6; var20 = null; } yg(var20); this.n1().t("KnLL", "java"); } return var6; } public static String i0(final String s) { try { final StringBuffer sb = new StringBuffer(); for (int i = 0; i < s.length(); ++i) { final char char1 = s.charAt(i); if (char1 == '\0') { sb.append("\u00010"); } else if (char1 == '\u0001') { sb.append("\u0001\u0001"); } else { sb.append(char1); } } return sb.toString(); } catch (k2 k2) { return null; } } } public String gm(Object var1, Serializable var2) { String var10000 = var1.toString(); byte var13 = -1; int var15 = var13 + 1; String var14 = "0"; String var3; int var16; switch(Integer.parseInt(var14)) { case 0: var3 = var10000; var16 = var3.length(); var15 += 14; var14 = "20"; break; default: var15 += 13; var16 = 1; var3 = null; } int var4; switch(var15) { case 0: var15 += 10; var10000 = null; var4 = 1; break; default: var4 = var16; var10000 = var2.toString(); var15 = 0; var14 = "0"; } String var5; switch(Integer.parseInt(var14)) { case 0: var5 = var10000; var16 = var5.length(); var15 += 6; var14 = "20"; break; default: var15 += 10; var16 = 1; var5 = null; } int var6; int var10001; switch(var15) { case 0: var15 += 4; var10001 = var6 = 1; break; default: var6 = var16; var16 = var6; var10001 = var4; var15 = 0; var14 = "0"; } switch(Integer.parseInt(var14)) { case 0: var16 ^= var10001 << 3; var15 += 5; var14 = "20"; break; default: var15 += 6; } int var7 = var16; int var8 = var4; if(var6 < 1) { return var3; } else if(var4 < 1) { return var5; } else { if(var6 > var4) { var8 = var6; } StringBuffer var17 = new StringBuffer(var8); var13 = -1; var15 = var13 + 1; var14 = "0"; StringBuffer var9; char var18; switch(Integer.parseInt(var14)) { case 0: var9 = var17; var18 = var5.charAt(0); var15 += 10; var14 = "20"; break; default: var15 += 13; var18 = 1; var9 = null; } int var10 = var18; int var11 = var3.charAt(0); for(int var12 = 0; var12 < var8; ++var11) { if(var10 >= var4) { var10 = 0; } if(var11 >= var6) { var11 = 0; } var9.append((char)(var7 ^ var3.charAt(var10) ^ var5.charAt(var11))); ++var12; ++var10; } return var9.toString(); } } public static String ue(String var0, String var1) { try { StringBuffer var2 = new StringBuffer(); int var3 = g1(var1); for(int var4 = 0; var4 < var0.length(); ++var4) { var3 = _6(var3); var2.append((char)(var0.charAt(var4) ^ var3 & 127)); } return var2.toString(); } catch (k2 var5) { return null; } } public static int _6(int var0) { int var10000 = var0; byte var4 = -1; int var6 = var4 + 1; String var5 = "0"; switch(Integer.parseInt(var5)) { case 0: var10000 = (var0 + 7) * 3; var6 += 4; var5 = "31"; break; default: var6 += 5; } int var1; byte var10001; switch(var6) { case 0: var6 += 9; var10001 = 0; var1 = 1; break; default: var1 = var10000; var10000 = var0; var10001 = 8; var6 = 0; var5 = "0"; } int var7; byte var10002; switch(Integer.parseInt(var5)) { case 0: var10000 >>>= var10001; var7 = var0; var10002 = 24; var6 += 6; var5 = "31"; break; default: var6 += 4; var7 = 1; var10002 = 0; } switch(var6) { case 0: var6 += 4; var0 = 1; break; default: var0 = var10000 | var7 << var10002; var6 = 0; var5 = "0"; } switch(Integer.parseInt(var5)) { case 0: var10000 = var0 >>> 7; var6 += 13; var5 = "31"; break; default: var6 += 8; var10000 = 1; } int var2; switch(var6) { case 0: var6 += 6; var2 = 1; break; default: var2 = var10000 & 1023; var6 = 0; var5 = "0"; } switch(Integer.parseInt(var5)) { case 0: var10000 = var0 >>> 22; var6 += 9; var5 = "31"; break; default: var6 += 12; var10000 = 1; } int var3; switch(var6) { case 0: var6 += 5; var3 = 1; break; default: var3 = var10000 & 1023; var6 = 0; var5 = "0"; } int var8; switch(Integer.parseInt(var5)) { case 0: var10000 = var0; var7 = var2; var8 = var3; var6 += 9; var5 = "31"; break; default: var6 += 11; var10000 = 1; var7 = 1; var8 = 1; } int var10003; switch(var6) { case 0: var6 += 13; var10003 = 1; break; default: var7 *= var8; var8 = 5; var10003 = var1; var6 = 0; var5 = "0"; } switch(Integer.parseInt(var5)) { case 0: var8 *= var10003 + 3; var6 += 4; var5 = "31"; break; default: var6 += 11; } var0 = var10000 ^ var7 + var8; return var0; } private final int ca(Object var1) { String var10000 = var1.toString(); byte var8 = -1; int var10 = var8 + 1; String var9 = "0"; String var2; int var3; switch(Integer.parseInt(var9)) { case 0: var2 = var10000; var3 = 0; var10 += 13; var9 = "9"; break; default: var10 += 10; var2 = null; var3 = 1; } int var4; byte var13; switch(var10) { case 0: var10 += 4; var13 = 0; var4 = 1; break; default: var4 = 0; byte var11; var13 = var11 = 0; var9 = "0"; } int var5 = var13; int var6 = 0; int var14; for(int var7 = var2.length(); var6 < var7; ++var6) { var14 = var4 * ((var5 & 3) != 3?5:3); char var10001 = var2.charAt(var7 - var6 - 1); var8 = -1; var10 = var8 + 1; var9 = "0"; switch(Integer.parseInt(var9)) { case 0: var4 = var14 + var10001; var14 = var3; var10 += 11; var9 = "9"; break; default: var10 += 7; var4 = 1; } switch(var10) { case 0: var10 += 6; var5 = 1; break; default: var5 = var14 ^ var4; boolean var12 = false; var9 = "0"; } var3 = var3 * ((var5 & 4) == 0?3:7) + var2.charAt(var6 * '\uabc5' % var7); } var14 = var5; var8 = -1; var10 = var8 + 1; var9 = "0"; int var15; int var10002; switch(Integer.parseInt(var9)) { case 0: var14 = var5 >>> 26; var15 = var4; var10002 = var3; var10 += 7; var9 = "9"; break; default: var10 += 13; var15 = 1; var10002 = 1; } return var14 ^ (var15 ^ var10002) & 67108863; } private static int g1(String var0) { int var1 = 0; byte var7 = -1; int var10 = var7 + 1; String var8 = "0"; int var2; boolean var10000; switch(Integer.parseInt(var8)) { case 0: var2 = 0; var10000 = false; var10 += 7; var8 = "23"; break; default: var10 += 15; var10000 = false; var2 = 1; } boolean var11; int var12; switch(var10) { case 0: var10 += 6; byte var3; var12 = var3 = 1; break; default: var12 = var0.length(); var11 = false; var8 = "0"; } int var4 = var12; int var5; char var10001; if(var4 < 19) { for(var5 = var4 - 1; var5 >= 0; --var5) { var12 = var1; var7 = -1; var10 = var7 + 1; var8 = "0"; switch(Integer.parseInt(var8)) { case 0: var12 = var1 * 3; var10001 = var0.charAt(var5); var10 += 5; var8 = "23"; break; default: var10 += 14; var10001 = 1; } switch(var10) { case 0: var10 += 5; var1 = 1; break; default: var1 = var12 + var10001; var12 = var2; var10 = 0; var8 = "0"; } switch(Integer.parseInt(var8)) { case 0: var12 *= 5; var10001 = var0.charAt(var4 - var5 - 1); var10 += 2; var8 = "23"; break; default: var10 += 5; var10001 = 1; } var2 = var12 + var10001; } } else { var5 = var4 / 19; for(int var6 = var4 - 1; var6 >= 0; var6 = var12 - var5) { var12 = var1; var7 = -1; var10 = var7 + 1; var8 = "0"; switch(Integer.parseInt(var8)) { case 0: var12 = var1 * 5; var10001 = var0.charAt(var6); var10 += 5; var8 = "23"; break; default: var10 += 9; var10001 = 1; } switch(var10) { case 0: var10 += 15; var1 = 1; break; default: var1 = var12 + var10001; var12 = var2; var10 = 0; var8 = "0"; } switch(Integer.parseInt(var8)) { case 0: var12 *= 3; var10001 = var0.charAt(var4 - var6 - 1); var10 += 15; var8 = "23"; break; default: var10 += 13; var10001 = 1; } switch(var10) { case 0: var10 += 4; var2 = 1; break; default: var2 = var12 + var10001; var12 = var6; var11 = false; var8 = "0"; } } } var12 = var1; var7 = -1; var10 = var7 + 1; var8 = "0"; int var9; switch(Integer.parseInt(var8)) { case 0: var9 = var1 ^ var2; var12 = var9; var10 += 11; var8 = "23"; break; default: var10 += 9; var9 = 1; } int var13; switch(var10) { case 0: var10 += 9; var13 = 1; break; default: var12 &= 16777215; var13 = var9; var11 = false; var8 = "0"; } return var12 ^ var13 >> 24; } private final boolean zb(String var1) { int var2 = var1.lastIndexOf(32); if(var2 <= 0) { return false; } else { for(int var3 = var2 + 1; var3 < var1.length(); ++var3) { char var4 = var1.charAt(var3); if(var4 < 48 || 57 < var4) { return false; } } return true; } } }
Geändert von SeBi (17.05.2020 um 07:34 Uhr)
-
17.05.2020, 13:10 #3
- Registriert seit
- 28.10.2011
- Beiträge
- 625
Thanked 279 Times in 168 PostsAW: [Passwort] Login ab V9.0cab
Das sind glaube ich nicht alle Methoden. Ich habe gestern eine gefunden, die vom logischen her die alten Klassen gleicht, aber viel zu siffig Obfuscated ist.
Diese Methoden werden hier wohl trotzdem noch verwendet, weil einfach die Charakteristiken dafür da sind:
Code:using System; using System.Text; namespace Klass.Passwords { public class k90cab { public static string Hash(string input, string salt) { var a = Encode(input, salt); var b = CalculateHash(a); Console.WriteLine("A = " + a); Console.WriteLine("B = " + b); return "0~" + b; //+Timestamp? } public static int CalculateHash(string data) { int min = 3; // << int max = 5; // << i think, these values will be changed on each Applet-Version int limit = 19; int left = 0; int right = 0; int sum = 0; int length = data.Length; if (length < limit) { for (int index = length - 1; index >= 0; index--) { left = left * min + data[index]; right = right * max + data[length - index - 1]; } } else { for (int index = length - 1; index >= 0; index -= (length / limit)) { left = left * max + data[index]; right = right * min + data[length - index - 1]; } } sum = left ^ right; //& 0xFFFFFF return sum ^ sum >> 24; } public static string Encode(string input, string salt) { int length_input = input.Length; int length_salt = salt.Length; int sum = length_input ^ length_salt << 4; if(length_input < 1) { return input; } if(length_salt < 1) { return salt; } int length_result = length_input; if(length_salt > length_result) { length_result = length_salt; } StringBuilder output = new StringBuilder(length_result); for(int index = 0; index < length_result; index++) { output.Append((char) (input[index % length_input] ^ salt[index % length_salt] ^ sum)); } return output.ToString(); } } }
Zitat von SeBi
[...] aber an sich sollte man sic über das normale Login-Paket ("n\0...") einloggen können.
Code:using System; using System.IO; using System.Net; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace Klass.Helper { public class Password { private static string URL = "https://www.knuddels.de/logincheck.html"; public static void Check(string nickname, string password, Action<JObject> callback) { var request = (HttpWebRequest) WebRequest.Create(URL); request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8"; request.Accept = "application/json"; request.Referer = URL; request.Method = "POST"; request.UserAgent = ""; using(var writer = new StreamWriter(request.GetRequestStream())) { writer.Write("nick=" + nickname + "&pwd=" + password); writer.Close(); } var response = (HttpWebResponse) request.GetResponse(); using(var reader = new StreamReader(response.GetResponseStream())) { callback(JsonConvert.DeserializeObject<JObject>(reader.ReadToEnd())); } } } }
Und so benutze ich momentan das ganze, sogar als Fallback:
Code:switch(this.client.GetCore().GetConfig().GetAppletVersion()) { case "k90cab": string hash = Klass.Passwords.k90cab.Hash(this.Password.Text, this.client.GetPasswordHash()); SendLogin(this.Nickname.Text, hash, this.Channel.Text); break; default: MessageBox.Show("Warning:\nThe Applet-Version " + this.client.GetCore().GetConfig().GetAppletVersion() + " has no Password-Hashing, trying the online-auth by Knuddels."); Klass.Helper.Password.Check(this.Nickname.Text, this.Password.Text, delegate (JObject data) { if((string) data.GetValue("error") != null) { MessageBox.Show((string) data.GetValue("error")); return; } if((JObject) data.GetValue("ok") != null) { JObject ok = (JObject) data.GetValue("ok"); string nickname = (string) ok.GetValue("nick"); string password = (string) ok.GetValue("pwd"); this.Nickname.Text = nickname; SendLogin(this.Nickname.Text, password, this.Channel.Text); return; } MessageBox.Show("Unbekannter Login-Fehler aufgetreten!\n\nResult:\n" + data); }); break; } }
-
18.05.2020, 11:31 #4
- Registriert seit
- 31.12.2012
- Beiträge
- 117
Thanked 237 Times in 71 PostsAW: [Passwort] Login ab V9.0cab
Also wenn ich das Hashing in eine eigene Klasse mit Javassist extrahiert habe und es darüber Hashen lasse funktioniert es also müssten nur die Methoden zu C# portiert werden und es sollte funktionieren.
Hier mal mein Test Source
https://mega.nz/file/LZgARY4K#SwFWiQ...WWz5b_sTaHkEnA
-
18.05.2020, 12:42 #5
- Registriert seit
- 28.10.2011
- Beiträge
- 625
Thanked 279 Times in 168 PostsAW: [Passwort] Login ab V9.0cab
Ich schaue mir das ganze später einmal an, hab leider Spätschicht und kann erst spätestens heute Abend danach schauen.
Das rekonstruieren in C# sollte nicht das Problem sein, das wichtigste ist, die Methoden dafür herauszufinden.
Ich sitze seit gestern Abend am Clienten und sortiere/rename mit Enigma, damit man alles besser nachvollziehen kann. Das Mapping stelle ich später dann zur Verfügung.
-
The Following User Says Thank You to Bubble Gum For This Useful Post:
-
19.05.2020, 01:14 #6
- Registriert seit
- 28.10.2011
- Beiträge
- 625
Thanked 279 Times in 168 PostsAW: [Passwort] Login ab V9.0cab
Vielleicht findest du ja hier das Problem - Wahrscheinlich bin ich gerade einfach nur etwas zu müde dafür
Das hier habe ich aus dem Applet extrahiert. Da JD-GUI/JD-CLI das ganze in falscher Reihenfolge ausspuckt, habe ich dass mit JADX proviert:
Spoiler:
Folgendes gibt's als Ausgabe (Passwort ist "MeinPasswort" und der PasswordSalt vom (-Paket "knuddels"):
+++++++++ PW HASH: |D0lpD:3
7C 44 01 30 07 6C 04 70 44 3D 29 3A 33
Spoiler:
Mit folgender Ausgabe:
+++++++++ PW HASH: |DHU%QdN.
7c 44 48 55 25 51 11 64 4e 2e b 1f
-
19.05.2020, 17:52 #7
- Registriert seit
- 31.12.2012
- Beiträge
- 117
Thanked 237 Times in 71 PostsAW: [Passwort] Login ab V9.0cab
Also ich hab heute mal ein wenig getestet.
Funktioniert schon mal ich mach jetzt noch Verschönerungen, denke bekommen das heute durch.
public class Password {
public static String hashPassword(String password, String key) {
key = xor(key, "vkUEOGHMFeh");
int i = key.length();
int i2 = i / 2;
i = i2 * i2;
i += i2 + 12;
i2 = i % key.length();
i *= i2 + 37;
i2 = i % key.length();
i = i2;
i *= i;
i = i + i2 + 14;
i %= key.length();
i = key.charAt(i) + 2;
i = i % key.length();
key = String.format("%s%s", key.charAt(i), xor(key, "RB"));
key = xor(String.format("%s", (calcInt(key) ^ 1640034174)), key);
return "0~" + escape(hash(password, key));
}
private static String escape(String str) {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < str.length(); ++i)
{
char var3 = str.charAt(i);
if (var3 == 0)
{
buffer.append("\u00010");
}
else if (var3 == 1)
{
buffer.append("\u0001\u0001");
}
else
{
buffer.append(var3);
}
}
return buffer.toString();
}
private static String xor(String str, String key) {
int k = key.length() ^ str.length() << 3;
int m = key.length() > str.length() ? key.length() : str.length();
StringBuilder buffer = new StringBuilder(m);
int n = str.charAt(0);
int z = key.charAt(0);
for (int i2 = 0; i2 < m; i2++)
{
if (n >= key.length())
{
n = 0;
}
if (z >= str.length())
{
z = 0;
}
buffer.append((char)(str.charAt(z) ^ key.charAt(n) ^ k));
n++;
z++;
}
return buffer.toString();
}
private static String hash(String str, String key) {
StringBuilder buffer = new StringBuilder();
int i = hash(key);
for (int j = 0; j < str.length(); j++)
{
i = nextRandom(i);
buffer.append((char)(str.charAt(j) ^ i & 0x7F));
}
return buffer.toString();
}
private static int nextRandom(int num) {
int i = (num + 7) * 3;
num = num >>> 8 | num << 24;
int j = num >>> 7 & 0x3FF;
int k = num >>> 22 & 0x3FF;
num ^= j * k + 5 * (i + 3);
return num;
}
private static int calcInt(String str) {
int i = 0;
int j = 0;
int k = 0;
for (int m = 0; m < str.length(); m++)
{
j = j * ((k & 0x3) != 3 ? 5 : 3) + str.charAt(str.length() - m - 1);
k = i ^ j;
i = i * ((k & 0x4) == 0 ? 3 : 7) + str.charAt(m * 43973 % str.length());
}
return k >>> 26 ^ (j ^ i) & 0x3FFFFFF;
}
private static int hash(String str) {
int i = 0;
int j = 0;
int k = str.length();
if (k < 19)
{
for (int m = k - 1; m >= 0; m--)
{
i = i * 3 + str.charAt(m);
j = j * 5 + str.charAt(k - m - 1);
}
}
else
{
int m = k / 19;
int n = k - 1;
while (n >= 0)
{
i = i * 5 + str.charAt(n);
j = j * 3 + str.charAt(k - n - 1);
n -= m;
}
}
int m = i ^ j;
return m & 0xFFFFFF ^ m >> 24;
}
}
Geändert von SeBi (19.05.2020 um 20:05 Uhr) Grund: Code angepasst
-
19.05.2020, 18:02 #8
- Registriert seit
- 09.11.2011
- Beiträge
- 121
Thanked 129 Times in 46 PostsAW: [Passwort] Login ab V9.0cab
Liegt daran, dass C# keinen triple-shift (>>>) Operator wie Java hat.
Code:int bla = (int)((uint)x >> y); // Java: int bla = x >>> y;
Spoiler:
-
19.05.2020, 18:06 #9
- Registriert seit
- 31.12.2012
- Beiträge
- 117
Thanked 237 Times in 71 PostsAW: [Passwort] Login ab V9.0cab
Der Hash stimmt aber trotzdem nicht
-
19.05.2020, 18:09 #10
- Registriert seit
- 09.11.2011
- Beiträge
- 121
Thanked 129 Times in 46 PostsAW: [Passwort] Login ab V9.0cab
Ich habe auch nur die C#-Version von Bubble Gum geringfügig verbessert. Damit erhalte ich dann auch 7C 44 01 30 07 6C 04 70 44 3D 29 3A 33 wie er in Java.
Ähnliche Themen
-
Wie Passwort entschlüsseln?
Von 5onny6lack im Forum SecurityAntworten: 4Letzter Beitrag: 10.07.2013, 20:41 -
Wie bei PSC passwort einsetzen?
Von Bazs im Forum Internet und TechnikAntworten: 4Letzter Beitrag: 18.04.2012, 23:11 -
MSN Passwort ändern?
Von Scarface im Forum Internet und TechnikAntworten: 4Letzter Beitrag: 18.04.2012, 22:42
Diese Seite nutzt Cookies, um das Nutzererlebnis zu verbessern. Klicken Sie hier, um das Cookie-Tracking zu deaktivieren.