Ir al contenido


Foto

Extrayendo las Password de las Wifi alojadas en el PC


  • Por favor identifícate para responder
17 respuestas en este tema

#1 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 13 septiembre 2015 - 10:23

He continuado jugando con la APINative Wifi y se me ocurrió una interesante aplicación que extrajese las Password de las redes Wifi configuradas en el PC. ¿A quién no se le ha olvidado uno y le interesa conectarse desde un smartphone o tablet?. Aquí está la solución.
Debo comentar que la dificultad está en S.O. anteriores a Vista, pues en los posteriores no estamos obligados a desencriptar la pasword pues existe una opción para que la API nos devuelva la clave plana. Pero como no he querido olvidar al viejo XP, me he puesto a desencriptar, para lo que debemos suplantar el contexto de seguridad de winlogon.exe y esto requiere ejecutar la aplicación como administrador.

Aprovechando algunas definiciones y APIs descritas aquí y añadiendo algunas más, el código queda como sigue:

delphi
  1. function EnablePrivilege(name: String; Enable: boolean = true): boolean;
  2. var
  3. hToken: THANDLE;
  4. priv: TOKEN_PRIVILEGES;
  5. begin
  6. priv.PrivilegeCount:= 1;
  7. priv.Privileges[0].Attributes:= 0;
  8. if Enable then priv.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED;
  9. LookupPrivilegeValue(nil, PCHAR(name), priv.Privileges[0].Luid);
  10. OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken);
  11. AdjustTokenPrivileges (hToken, FALSE, priv, sizeof(priv), nil, PDWORD(nil)^);
  12. Result:= (GetLastError = ERROR_SUCCESS);
  13. CloseHandle (hToken);
  14. end;
  15.  
  16. function GetProcessId(FileName: String): DWORD;
  17. var
  18. proc: TProcessEntry32;
  19. hSysSnapshot: THandle;
  20. begin
  21. proc.dwSize := SizeOf(TProcessEntry32);
  22. hSysSnapshot:= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  23. if (hSysSnapshot <> INVALID_HANDLE_VALUE) and Process32First(hSysSnapshot, proc) then
  24. begin
  25. repeat
  26. if String(proc.szExeFile) = FileName then
  27. begin
  28. Result:= proc.th32ProcessID;
  29. break;
  30. end;
  31. until not (Process32Next(hSysSnapshot, proc));
  32. end;
  33. CloseHandle(hSysSnapshot);
  34. end;
  35.  
  36. function ImpersonateToLoginUser: BOOL;
  37. var
  38. hProcess, hToken: THANDLE ;
  39. ID: DWORD;
  40. begin
  41. Result:= false;
  42. ID:= GetProcessID ('winlogon.exe');
  43. if ID > 0 then
  44. begin
  45. hProcess:= OpenProcess (MAXIMUM_ALLOWED, FALSE, ID);
  46. if hProcess <> INVALID_HANDLE_VALUE then
  47. begin
  48. Result:= OpenProcessToken(hProcess, MAXIMUM_ALLOWED, hToken);
  49. if Result then
  50. begin
  51. EnablePrivilege('SeDebugPrivilege');
  52. Result:= ImpersonateLoggedOnUser(hToken);
  53. CloseHandle(hToken);
  54. end;
  55. CloseHandle (hProcess);
  56. end;
  57. end;
  58. end;
  59.  
  60. function ExtractKey(XMLText: String): String;
  61. var
  62. ini, fin: integer;
  63. begin
  64. Result:= '';
  65. ini:= Pos('<keyMaterial>', XMLText);
  66. fin:= Pos('</keyMaterial>', XMLText);
  67. if (ini <> -1) and (fin <> -1) then
  68. begin
  69. ini:= ini + Length('<keyMaterial>');
  70. Result:= Copy(XMLText, ini, fin-ini);
  71. end;
  72. end;
  73.  
  74. function DecryptData(Key: String): String;
  75. var
  76. Buffer: array [0..1023] of BYTE;
  77. Len: DWORD;
  78. DataIn, DataOut: TDATA_BLOB;
  79. begin
  80. Result:= Key;
  81. Len:= 1024;
  82. ImpersonateToLoginUser;
  83. if CryptStringToBinary(PCHAR(Key), Length(Key), CRYPT_STRING_HEX, @Buffer[0], @Len, 0, 0) then
  84. begin
  85. DataIn.cbData:= Len;
  86. DataIn.pbData:= @Buffer[0];
  87. DataOut.cbData:= 0;
  88. DataOut.pbData:= nil;
  89. if CryptUnprotectData (@DataIn, nil, nil, nil, nil, 0, @DataOut) then
  90. Result:= PCHAR(DataOut.pbData);
  91. end;
  92. RevertToSelf;
  93. end;
  94.  
  95. function WifiGetPassWords: String;
  96. var
  97. hClient: THandle;
  98. dwVersion: DWORD;
  99. pInterfaceInfoList: PWLAN_INTERFACE_INFO_LIST;
  100. pInterfaceGuid: PGUID;
  101. pProfileList: PWLAN_PROFILE_INFO_LIST;
  102. pstrProfileXml: PWCHAR;
  103. dwFlags: DWORD;
  104. dwGrantedAccess: DWORD;
  105. i,j: integer;
  106. begin
  107. Result:= '';
  108. if ERROR_SUCCESS = WlanOpenHandle(1, nil, @dwVersion, @hClient) then
  109. begin
  110. if ERROR_SUCCESS = WlanEnumInterfaces(hClient, nil, @pInterfaceInfoList) then
  111. begin
  112. for i:= 0 to pInterfaceInfoList^.dwNumberOfItems - 1 do
  113. begin
  114. pInterfaceGuid:= @pInterfaceInfoList^.InterfaceInfo[pInterfaceInfoList^.dwIndex].InterfaceGuid;
  115. if ERROR_SUCCESS = WlanGetProfileList(hClient, pInterfaceGuid, nil, @pProfileList) then
  116. begin
  117. for j:=0 to pProfileList.dwNumberOfItems-1 do
  118. begin
  119. if ERROR_SUCCESS = WlanGetProfile(hClient, pInterfaceGuid, pProfileList.ProfileInfo[j].strProfileName, nil, @pstrProfileXml, @dwFlags, @dwGrantedAccess) then
  120. begin
  121. Result:= Result + String(pProfileList.ProfileInfo[j].strProfileName) + ': '+ DecryptData(ExtractKey(String(pstrProfileXml))) + #13 + #10;
  122. WlanFreeMemory(pstrProfileXml);
  123. end;
  124. end;
  125. end;
  126. WlanFreeMemory(pProfileList);
  127. end;
  128. WlanFreeMemory(pInterfaceInfoList);
  129. end;
  130. WlanCloseHandle(hClient, nil);
  131. end;
  132. end;


La forma de uso:

delphi
  1. var
  2. Keys: String;
  3. begin
  4. Keys:= WifiGetPassWords;
  5. end;


Espero que sea de utilidad.
Subo un proyecto completo.
 
 
Saludos.

PD: he actualizado el código aquí.

Archivos adjuntos


  • 4

#2 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 13 septiembre 2015 - 10:46

Bravo Maestro!!


  • 0

#3 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 13 septiembre 2015 - 04:02

Descargado ...  Muchas gracias maestro.

 

Un cordial saludo.


  • 0

#4 poliburro

poliburro

    Advanced Member

  • Administrador
  • 4.945 mensajes
  • LocationMéxico

Escrito 14 septiembre 2015 - 08:18

Que interesante código nos has compartido amigo.

 

Muchas gracias por ello. Saludos


  • 0

#5 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 14 septiembre 2015 - 10:13

Con una pequeña modificación podemos ejecutar como usuario no administrador en S.O. mayores de Vista y nos dará las claves directamente sin necesidad de desencriptarlas.

delphi
  1. function WifiGetPassWords: String;
  2. var
  3. hClient: THandle;
  4. dwVersion: DWORD;
  5. pInterfaceInfoList: PWLAN_INTERFACE_INFO_LIST;
  6. pInterfaceGuid: PGUID;
  7. pProfileList: PWLAN_PROFILE_INFO_LIST;
  8. pstrProfileXml: PWCHAR;
  9. dwFlags: DWORD;
  10. dwGrantedAccess: DWORD;
  11. i,j: integer;
  12. begin
  13. Result:= '';
  14. dwFlags:= 0;
  15. dwGrantedAccess:= 0;
  16.  
  17. if ERROR_SUCCESS = WlanOpenHandle(1, nil, @dwVersion, @hClient) then
  18. begin
  19. if ERROR_SUCCESS = WlanEnumInterfaces(hClient, nil, @pInterfaceInfoList) then
  20. begin
  21. for i:= 0 to pInterfaceInfoList^.dwNumberOfItems - 1 do
  22. begin
  23. pInterfaceGuid:= @pInterfaceInfoList^.InterfaceInfo[pInterfaceInfoList^.dwIndex].InterfaceGuid;
  24. if ERROR_SUCCESS = WlanGetProfileList(hClient, pInterfaceGuid, nil, @pProfileList) then
  25. begin
  26. for j:=0 to pProfileList.dwNumberOfItems-1 do
  27. begin
  28. dwFlags:= WLAN_PROFILE_GET_PLAINTEXT_KEY;
  29. if ERROR_SUCCESS = WlanGetProfile(hClient, pInterfaceGuid, pProfileList.ProfileInfo[j].strProfileName, nil, @pstrProfileXml, @dwFlags, @dwGrantedAccess) then
  30. begin
  31. Result:= Result + String(pProfileList.ProfileInfo[j].strProfileName) + ': '+ DecryptData(ExtractKey(String(pstrProfileXml))) + #13 + #10;
  32. WlanFreeMemory(pstrProfileXml);
  33. end;
  34. end;
  35. end;
  36. WlanFreeMemory(pProfileList);
  37. end;
  38. WlanFreeMemory(pInterfaceInfoList);
  39. end;
  40. WlanCloseHandle(hClient, nil);
  41. end;
  42. end;


Subo la actualización, que lo disfrutéis.
 
Saludos.

Archivos adjuntos


  • 1

#6 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 14 septiembre 2015 - 10:45

jojo, a mi me pasa que tengo 3 redes en mi casa (2 repetidores de señal y el router para que alcance en toda la casa la señal) y me preguntan la contraseña de cada una y no me la sé, tengo que sacar mi hoja de contraseñas jajajaja

 

Excelente aporte amigo y sobre todo muy útil :)

 

Saludos


  • 0

#7 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 14 septiembre 2015 - 11:00

jojo, a mi me pasa que tengo 3 redes en mi casa (2 repetidores de señal y el router para que alcance en toda la casa la señal) y me preguntan la contraseña de cada una y no me la sé, tengo que sacar mi hoja de contraseñas jajajaja
 
Excelente aporte amigo y sobre todo muy útil :)
 
Saludos


Yo también tengo tres, pero los "repetidores Wifi" están configurados como puntos de acceso y conectados al router por cable. Todos los puntos tienen el mismo SSID y la misma clave, así nadie tiene líos esté donde esté dentro de casa y solo tengo una red real desde la que accedo a cualquier PC o dispositivo.

El asunto se me ocurrió para aquellas redes a las que se conectó determinado portátil, fuera de casa, y cuya clave no recuerdo. Obtengo la lista y listo. 15.gif

 

 

Saludos.


  • 0

#8 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 14 septiembre 2015 - 11:55

Yo también tengo tres, pero los "repetidores Wifi" están configurados como puntos de acceso y conectados al router por cable. Todos los puntos tienen el mismo SSID y la misma clave, así nadie tiene líos esté donde esté dentro de casa y solo tengo una red real desde la que accedo a cualquier PC o dispositivo.

El asunto se me ocurrió para aquellas redes a las que se conectó determinado portátil, fuera de casa, y cuya clave no recuerdo. Obtengo la lista y listo. 15.gif

 

 

Saludos.

 

Los que yo tengo son a través de la corriente eléctrica, no se si se puede colocar el mismo SSID, la clave pudiera ponerle la misma a todas, pero cuando las conecté no tenia la contraseña del router a la mano :D

 

Saludos


  • 0

#9 genriquez

genriquez

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 539 mensajes
  • LocationCali, Colombia

Escrito 16 septiembre 2015 - 07:16

Excelente, felicitaciones y muchas gracias por compartir.

 

Saludos.


  • 0

#10 monchito_elroro

monchito_elroro

    Advanced Member

  • Miembros
  • PipPipPip
  • 259 mensajes

Escrito 06 septiembre 2016 - 08:48

Buenas amigo Escafadra, ante todo muy buen código gracias por compartir :) , también le solicitaría su ayuda para poder usarlo en lazarus, pues me sale error cuando lo quiero usar. Estos son los errores que me sale:

 

En:


php
  1. AdjustTokenPrivileges (hToken, FALSE, priv, sizeof(priv), nil, PDWORD(nil)^);

Se detiene en "nil" y Sale error:

unit1.pas(104,64) Error: Call by var for arg no. 5 has to match exactly: Got "Pointer" expected "TOKEN_PRIVILEGES"

 

En:


php
  1. if CryptStringToBinary(PCHAR(Key), Length(Key), CRYPT_STRING_HEX, @Buffer[0], @Len, 0, 0) then

Apunta a los "0" y sale:

unit1.pas(177,91) Error: Incompatible type for arg no. 7: Got "ShortInt", expected "PDWord"

 

En:


php
  1. for j:=0 to pProfileList.dwNumberOfItems-1 do

selecciona "dwNumberOfItems" y sale error:

unit1.pas(214,36) Error: Illegal qualifier

 

Por favor si me pueden ayudar. :(


  • 0

#11 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 07 septiembre 2016 - 06:59

Buenas amigo Escafadra, ante todo muy buen código gracias por compartir :) , también le solicitaría su ayuda para poder usarlo en lazarus, pues me sale error cuando lo quiero usar. Estos son los errores que me sale:
 
En:


delphi
  1. AdjustTokenPrivileges (hToken, FALSE, priv, sizeof(priv), nil, PDWORD(nil)^);

Se detiene en "nil" y Sale error:
unit1.pas(104,64) Error: Call by var for arg no. 5 has to match exactly: Got "Pointer" expected "TOKEN_PRIVILEGES"

 

 
El problema está en la diferente declaración de AdjustTokenPrivileges entre delphi y Lazarus. Hazlo así: 


delphi
  1. AdjustTokenPrivileges (hToken, FALSE, priv, sizeof(priv), PTOKEN_PRIVILEGES(nil)^, PDWORD(nil)^);

 
 

En:


delphi
  1. if CryptStringToBinary(PCHAR(Key), Length(Key), CRYPT_STRING_HEX, @Buffer[0], @Len, 0, 0) then

Apunta a los "0" y sale:
unit1.pas(177,91) Error: Incompatible type for arg no. 7: Got "ShortInt", expected "PDWord"

 


Hazlo de esta manera:


delphi
  1. CryptStringToBinary(PCHAR(Key), Length(Key), CRYPT_STRING_HEX, @Buffer[0], @Len, nil, nil)

En:


delphi
  1. for j:=0 to pProfileList.dwNumberOfItems-1 do

selecciona "dwNumberOfItems" y sale error:
unit1.pas(214,36) Error: Illegal qualifier
 
Por favor si me pueden ayudar. :(

 


Se debe a que no activaste la compatibilidad con delphi, si no lo quieres hacer, utiliza los miembros de punteros a estructuras o clases con ^.


delphi
  1. for j:=0 to pProfileList^.dwNumberOfItems-1 do

Subo un proyecto Lazarus

 

Saludos.

Archivos adjuntos


  • 0

#12 monchito_elroro

monchito_elroro

    Advanced Member

  • Miembros
  • PipPipPip
  • 259 mensajes

Escrito 07 septiembre 2016 - 10:25

Guauuuuu, amigo Escafandra es usted un GENIO me funciona a la perfección, lo he probado en Win8.1x64 y me funciona perfecto, muchisimas Gracias amigo :)  :)  :) .

 

PD: también he visto que ha publicado un post sobre conexiones wifi, me voy a dar el tiempo para poder leerlo con detenimiento y aplicarlo en Lazarus también, saludos con todos.


  • 0

#13 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 07 septiembre 2016 - 10:45

Aprovechando que he revisado el tema tras la pregunta de monchito_elroro, voy a subir el mismo proyecto, pero esta vez en C/C++

 

El archivo cabecera C++ es un poco amplio y quizás sobran cosas, pero por pereza he hecho un copy-paste de otro proyecto más amplio y no me apetece borrar cosas  |-)

 
 unit1.h


cpp
  1. //---------------------------------------------------------------------------
  2.  
  3. #ifndef Unit1H
  4. #define Unit1H
  5. //---------------------------------------------------------------------------
  6. #include <Classes.hpp>
  7. #include <Controls.hpp>
  8. #include <StdCtrls.hpp>
  9. #include <Forms.hpp>
  10.  
  11.  
  12.  
  13. #define WLAN_REASON_CODE_SUCCESS 0
  14.  
  15. #define WLAN_MAX_NAME_LENGTH 256
  16. #define DOT11_SSID_MAX_LENGTH 32
  17. #define WLAN_MAX_PHY_TYPE_NUMBER 8
  18. #define WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_ADHOC_PROFILES 0x00000001
  19. #define WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_MANUAL_HIDDEN_PROFILES 0x00000002
  20. #define WLAN_AVAILABLE_NETWORK_CONNECTED 0x00000001
  21. #define WLAN_AVAILABLE_NETWORK_HAS_PROFILE 0x00000002
  22. #define WLAN_NOTIFICATION_SOURCE_ALL 0x0000FFFF
  23. #define WLAN_NOTIFICATION_SOURCE_ONEX 0x00000004
  24. #define WLAN_NOTIFICATION_SOURCE_ACM 0x00000008
  25.  
  26. #define WLAN_PROFILE_GROUP_POLICY 0x00000001
  27. #define WLAN_PROFILE_USER 0x00000002
  28. #define WLAN_PROFILE_GET_PLAINTEXT_KEY 0x00000004
  29. // the following flags are only used for WlanSaveTemporaryProfile API
  30. #define WLAN_PROFILE_CONNECTION_MODE_SET_BY_CLIENT 0x00010000
  31. #define WLAN_PROFILE_CONNECTION_MODE_AUTO 0x00020000
  32.  
  33.  
  34. typedef enum _WLAN_INTERFACE_STATE {
  35. wlan_interface_state_not_ready = 0,
  36. wlan_interface_state_connected = 1,
  37. wlan_interface_state_ad_hoc_network_formed = 2,
  38. wlan_interface_state_disconnecting = 3,
  39. wlan_interface_state_disconnected = 4,
  40. wlan_interface_state_associating = 5,
  41. wlan_interface_state_discovering = 6,
  42. wlan_interface_state_authenticating = 7
  43. } WLAN_INTERFACE_STATE, *PWLAN_INTERFACE_STATE;
  44.  
  45.  
  46. typedef enum _DOT11_PHY_TYPE {
  47. dot11_phy_type_unknown = 0,
  48. dot11_phy_type_any = 0,
  49. dot11_phy_type_fhss = 1,
  50. dot11_phy_type_dsss = 2,
  51. dot11_phy_type_irbaseband = 3,
  52. dot11_phy_type_ofdm = 4,
  53. dot11_phy_type_hrdsss = 5,
  54. dot11_phy_type_erp = 6,
  55. dot11_phy_type_ht = 7,
  56. dot11_phy_type_vht = 8,
  57. dot11_phy_type_IHV_start = 0x80000000,
  58. dot11_phy_type_IHV_end = 0xffffffff
  59. } DOT11_PHY_TYPE, *PDOT11_PHY_TYPE;
  60.  
  61. typedef enum _DOT11_AUTH_ALGORITHM {
  62. DOT11_AUTH_ALGO_80211_OPEN = 1,
  63. DOT11_AUTH_ALGO_80211_SHARED_KEY = 2,
  64. DOT11_AUTH_ALGO_WPA = 3,
  65. DOT11_AUTH_ALGO_WPA_PSK = 4,
  66. DOT11_AUTH_ALGO_WPA_NONE = 5,
  67. DOT11_AUTH_ALGO_RSNA = 6,
  68. DOT11_AUTH_ALGO_RSNA_PSK = 7,
  69. DOT11_AUTH_ALGO_IHV_START = 0x80000000,
  70. DOT11_AUTH_ALGO_IHV_END = 0xffffffff
  71. } DOT11_AUTH_ALGORITHM, *PDOT11_AUTH_ALGORITHM;
  72.  
  73. typedef enum _DOT11_CIPHER_ALGORITHM {
  74. DOT11_CIPHER_ALGO_NONE = 0x00,
  75. DOT11_CIPHER_ALGO_WEP40 = 0x01,
  76. DOT11_CIPHER_ALGO_TKIP = 0x02,
  77. DOT11_CIPHER_ALGO_CCMP = 0x04,
  78. DOT11_CIPHER_ALGO_WEP104 = 0x05,
  79. DOT11_CIPHER_ALGO_WPA_USE_GROUP = 0x100,
  80. DOT11_CIPHER_ALGO_RSN_USE_GROUP = 0x100,
  81. DOT11_CIPHER_ALGO_WEP = 0x101,
  82. DOT11_CIPHER_ALGO_IHV_START = 0x80000000,
  83. DOT11_CIPHER_ALGO_IHV_END = 0xffffffff
  84. } DOT11_CIPHER_ALGORITHM, *PDOT11_CIPHER_ALGORITHM;
  85.  
  86. typedef struct _DOT11_SSID {
  87. ULONG uSSIDLength;
  88. UCHAR ucSSID[DOT11_SSID_MAX_LENGTH];
  89. } DOT11_SSID, *PDOT11_SSID;
  90.  
  91. typedef enum _DOT11_BSS_TYPE {
  92. dot11_BSS_type_infrastructure = 1,
  93. dot11_BSS_type_independent = 2,
  94. dot11_BSS_type_any = 3
  95. } DOT11_BSS_TYPE, *PDOT11_BSS_TYPE;
  96.  
  97. typedef enum _WLAN_CONNECTION_MODE {
  98. wlan_connection_mode_profile,
  99. wlan_connection_mode_temporary_profile,
  100. wlan_connection_mode_discovery_secure,
  101. wlan_connection_mode_discovery_unsecure,
  102. wlan_connection_mode_auto,
  103. wlan_connection_mode_invalid
  104. } WLAN_CONNECTION_MODE, *PWLAN_CONNECTION_MODE;
  105.  
  106. typedef DWORD WLAN_REASON_CODE, *PWLAN_REASON_CODE;
  107.  
  108. //#pragma pack( push )
  109. //#pragma pack( 8 )
  110. typedef struct _WLAN_CONNECTION_NOTIFICATION_DATA {
  111. WLAN_CONNECTION_MODE wlanConnectionMode;
  112. // DWORD wlanConnectionMode;
  113. WCHAR strProfileName[WLAN_MAX_NAME_LENGTH];
  114. DOT11_SSID dot11Ssid;
  115. DOT11_BSS_TYPE dot11BssType;
  116. BOOL bSecurityEnabled;
  117. WLAN_REASON_CODE wlanReasonCode;
  118. DWORD dwFlags;
  119. WCHAR strProfileXml[1];
  120. } WLAN_CONNECTION_NOTIFICATION_DATA, *PWLAN_CONNECTION_NOTIFICATION_DATA;
  121.  
  122. typedef struct _WLAN_INTERFACE_INFO {
  123. GUID InterfaceGuid;
  124. WCHAR strInterfaceDescription[256];
  125. WLAN_INTERFACE_STATE isState;
  126. } WLAN_INTERFACE_INFO, *PWLAN_INTERFACE_INFO;
  127.  
  128. typedef struct _WLAN_INTERFACE_INFO_LIST {
  129. DWORD dwNumberOfItems;
  130. DWORD dwIndex;
  131. WLAN_INTERFACE_INFO InterfaceInfo[];
  132. } WLAN_INTERFACE_INFO_LIST, *PWLAN_INTERFACE_INFO_LIST;
  133.  
  134. typedef struct _WLAN_AVAILABLE_NETWORK {
  135. WCHAR strProfileName[256];
  136. DOT11_SSID dot11Ssid;
  137. DOT11_BSS_TYPE dot11BssType; //DWORD
  138. ULONG uNumberOfBssids;
  139. BOOL bNetworkConnectable;
  140. WLAN_REASON_CODE wlanNotConnectableReason; //DWORD
  141. ULONG uNumberOfPhyTypes;
  142. DOT11_PHY_TYPE dot11PhyTypes[WLAN_MAX_PHY_TYPE_NUMBER]; //DWORD
  143. BOOL bMorePhyTypes;
  144. //WLAN_SIGNAL_QUALITY wlanSignalQuality;
  145. ULONG wlanSignalQuality;
  146. BOOL bSecurityEnabled;
  147. DOT11_AUTH_ALGORITHM dot11DefaultAuthAlgorithm; //DWORD
  148. DOT11_CIPHER_ALGORITHM dot11DefaultCipherAlgorithm; //DWORD
  149. DWORD dwFlags;
  150. DWORD dwReserved;
  151. } WLAN_AVAILABLE_NETWORK, *PWLAN_AVAILABLE_NETWORK;
  152.  
  153. typedef struct _WLAN_AVAILABLE_NETWORK_LIST {
  154. DWORD dwNumberOfItems;
  155. DWORD dwIndex;
  156. WLAN_AVAILABLE_NETWORK Network[1];
  157. } WLAN_AVAILABLE_NETWORK_LIST, *PWLAN_AVAILABLE_NETWORK_LIST;
  158.  
  159. typedef struct _NDIS_OBJECT_HEADER {
  160. UCHAR Type;
  161. UCHAR Revision;
  162. USHORT Size;
  163. } NDIS_OBJECT_HEADER, *PNDIS_OBJECT_HEADER;
  164.  
  165. typedef UCHAR DOT11_MAC_ADDRESS[6];
  166. typedef DOT11_MAC_ADDRESS* PDOT11_MAC_ADDRESS;
  167.  
  168. typedef struct _DOT11_BSSID_LIST {
  169. NDIS_OBJECT_HEADER Header;
  170. ULONG uNumOfEntries;
  171. ULONG uTotalNumOfEntries;
  172. DOT11_MAC_ADDRESS BSSIDs[1];
  173. } DOT11_BSSID_LIST, *PDOT11_BSSID_LIST;
  174.  
  175. typedef struct _WLAN_CONNECTION_PARAMETERS {
  176. WLAN_CONNECTION_MODE wlanConnectionMode; //DWORD
  177. LPCWSTR strProfile; //PWCHAR
  178. PDOT11_SSID pDot11Ssid;
  179. PDOT11_BSSID_LIST pDesiredBssidList; //PVOID
  180. DOT11_BSS_TYPE dot11BssType; //DWORD
  181. DWORD dwFlags;
  182. } WLAN_CONNECTION_PARAMETERS, *PWLAN_CONNECTION_PARAMETERS;
  183.  
  184. typedef struct _WLAN_NOTIFICATION_DATA {
  185. DWORD NotificationSource;
  186. DWORD NotificationCode;
  187. GUID InterfaceGuid;
  188. DWORD dwDataSize;
  189. PVOID pData;
  190. } WLAN_NOTIFICATION_DATA, *PWLAN_NOTIFICATION_DATA;
  191.  
  192. typedef struct _WLAN_PROFILE_INFO {
  193. WCHAR strProfileName[256];
  194. DWORD dwFlags;
  195. } WLAN_PROFILE_INFO, *PWLAN_PROFILE_INFO;
  196.  
  197. typedef struct _WLAN_PROFILE_INFO_LIST {
  198. DWORD dwNumberOfItems;
  199. DWORD dwIndex;
  200. WLAN_PROFILE_INFO ProfileInfo[1];
  201. } WLAN_PROFILE_INFO_LIST, *PWLAN_PROFILE_INFO_LIST;
  202. //#pragma pack( pop )
  203.  
  204.  
  205. typedef VOID (WINAPI *WLAN_NOTIFICATION_CALLBACK)(PWLAN_NOTIFICATION_DATA data, PVOID context);
  206.  
  207. typedef DWORD (WINAPI *PWlanOpenHandle)(DWORD dwClientVersion, PVOID pReserved, PDWORD pdwNegotiatedVersion, PHANDLE phClientHandle);
  208. typedef DWORD (WINAPI *PWlanCloseHandle)(HANDLE hClientHandle, PVOID pReserved);
  209. typedef DWORD (WINAPI *PWlanEnumInterfaces)(HANDLE hClientHandle, PVOID pReserved, PWLAN_INTERFACE_INFO_LIST *ppInterfaceList);
  210. typedef DWORD (WINAPI *PWlanGetAvailableNetworkList)(HANDLE hClientHandle, const GUID *pInterfaceGuid, DWORD dwFlags, PVOID pReserved, PWLAN_AVAILABLE_NETWORK_LIST *ppAvailableNetworkList);
  211. typedef PVOID (WINAPI *PWlanAllocateMemory)(DWORD dwMemorySize);
  212. typedef VOID (WINAPI *PWlanFreeMemory)(PVOID pMemory);
  213. typedef DWORD (WINAPI *PWlanConnect)(HANDLE hClientHandle, const GUID *pInterfaceGuid, const PWLAN_CONNECTION_PARAMETERS pConnectionParameters, PVOID pReserved);
  214. typedef DWORD (WINAPI *PWlanDisconnect)(HANDLE hClientHandle, const GUID *pInterfaceGuid, PVOID pReserved);
  215. typedef DWORD (WINAPI *PWlanRegisterNotification)(HANDLE hClientHandle, DWORD dwNotifSource, BOOL bIgnoreDuplicate, WLAN_NOTIFICATION_CALLBACK funcCallback, PVOID pCallbackContext, PVOID pReserved, PDWORD pdwPrevNotifSource);
  216. typedef DWORD (WINAPI *PWlanSetProfile)(HANDLE hClientHandle, const GUID *pInterfaceGuid, DWORD dwFlags, LPCWSTR strProfileXml, LPCWSTR strAllUserProfileSecurity, BOOL bOverwrite, PVOID pReserved, PDWORD dwReasonCode);
  217. typedef DWORD (WINAPI *PWlanDeleteProfile)(HANDLE hClientHandle, const GUID *pInterfaceGuid, LPCWSTR strProfileName, PVOID pReserved);
  218. typedef DWORD (WINAPI *PWlanGetProfile)(HANDLE hClientHandle, const GUID *pInterfaceGuid, LPCWSTR strProfileName, PVOID pReserved, LPWSTR* pstrProfileXml, PDWORD pdwFlags, PDWORD pdwGrantedAccess);
  219. typedef DWORD (WINAPI *PWlanReasonCodeToString)(DWORD dwReasonCode, DWORD dwBufferSize, PWCHAR pStringBuffer, PVOID pReserved);
  220. typedef DWORD (WINAPI *PWlanGetProfileList)(HANDLE hClientHandle, const GUID *pInterfaceGuid, PVOID pReserved, PWLAN_PROFILE_INFO_LIST *ppProfileList);
  221.  
  222. typedef DWORD (WINAPI *PWlanScan)(HANDLE hClientHandle, const GUID *pInterfaceGuid, PDOT11_SSID pDot11Ssid, PVOID pIeData, PVOID pReserved);
  223.  
  224.  
  225.  
  226.  
  227. //---------------------------------------------------------------------------
  228. class TForm1 : public TForm
  229. {
  230. __published: // IDE-managed Components
  231. TLabel *Label1;
  232. TLabel *Label2;
  233. TMemo *Memo1;
  234. TButton *Button1;
  235. void __fastcall Button1Click(TObject *Sender);
  236. private: // User declarations
  237. public: // User declarations
  238. __fastcall TForm1(TComponent* Owner);
  239. };
  240. //---------------------------------------------------------------------------
  241. extern PACKAGE TForm1 *Form1;
  242. //---------------------------------------------------------------------------
  243. #endif

 

 
 unit1.cpp


cpp
  1. //---------------------------------------------------------------------------
  2.  
  3. #include <vcl.h>
  4. #pragma hdrstop
  5.  
  6. #include "Unit1.h"
  7. #include <tlhelp32.h>
  8.  
  9. //---------------------------------------------------------------------------
  10. #pragma package(smart_init)
  11. #pragma resource "*.dfm"
  12. TForm1 *Form1;
  13.  
  14.  
  15.  
  16. PWlanOpenHandle              WlanOpenHandle;
  17. PWlanCloseHandle             WlanCloseHandle;
  18. PWlanEnumInterfaces          WlanEnumInterfaces;
  19. PWlanGetAvailableNetworkList WlanGetAvailableNetworkList;
  20. PWlanAllocateMemory          WlanAllocateMemory;
  21. PWlanFreeMemory              WlanFreeMemory;
  22. PWlanConnect                 WlanConnect;
  23. PWlanDisconnect              WlanDisconnect;
  24. PWlanRegisterNotification    WlanRegisterNotification;
  25. PWlanSetProfile              WlanSetProfile;
  26. PWlanDeleteProfile           WlanDeleteProfile;
  27. PWlanGetProfile              WlanGetProfile;
  28. PWlanReasonCodeToString      WlanReasonCodeToString;
  29. PWlanGetProfileList          WlanGetProfileList;
  30.  
  31. BOOL InitWLanAPI()
  32. {
  33.   HMODULE hWlanapi = LoadLibrary("Wlanapi.dll");
  34.   if(hWlanapi){
  35.     WlanOpenHandle  = (PWlanOpenHandle)GetProcAddress(hWlanapi, "WlanOpenHandle");
  36.     WlanCloseHandle = (PWlanCloseHandle)GetProcAddress(hWlanapi, "WlanCloseHandle");
  37.     WlanEnumInterfaces = (PWlanEnumInterfaces)GetProcAddress(hWlanapi, "WlanEnumInterfaces");
  38.     WlanGetAvailableNetworkList = (PWlanGetAvailableNetworkList)GetProcAddress(hWlanapi, "WlanGetAvailableNetworkList");
  39.     WlanAllocateMemory = (PWlanAllocateMemory)GetProcAddress(hWlanapi, "WlanAllocateMemory");
  40.     WlanFreeMemory = (PWlanFreeMemory)GetProcAddress(hWlanapi, "WlanFreeMemory");
  41.     WlanConnect = (PWlanConnect)GetProcAddress(hWlanapi, "WlanConnect");
  42.     WlanDisconnect = (PWlanDisconnect)GetProcAddress(hWlanapi, "WlanDisconnect");
  43.     WlanRegisterNotification = (PWlanRegisterNotification)GetProcAddress(hWlanapi, "WlanRegisterNotification");
  44.     WlanSetProfile = (PWlanSetProfile)GetProcAddress(hWlanapi, "WlanSetProfile");
  45.     WlanDeleteProfile = (PWlanDeleteProfile)GetProcAddress(hWlanapi, "WlanDeleteProfile");
  46.     WlanGetProfile = (PWlanGetProfile)GetProcAddress(hWlanapi, "WlanGetProfile");
  47.     WlanReasonCodeToString =(PWlanReasonCodeToString)GetProcAddress(hWlanapi, "WlanReasonCodeToString");
  48.     WlanGetProfileList = (PWlanGetProfileList)GetProcAddress(hWlanapi, "WlanGetProfileList");
  49.     
  50.     return WlanOpenHandle && WlanCloseHandle && WlanCloseHandle && WlanGetAvailableNetworkList &&
  51.            WlanAllocateMemory && WlanFreeMemory && WlanConnect && WlanDisconnect &&
  52.            WlanRegisterNotification && WlanSetProfile && WlanDeleteProfile && WlanGetProfile;
  53.   }
  54.   return false;
  55. }
  56.  
  57. //----------------------------------------------------------------------------------
  58. // Constantes y funciones de apoyo
  59.  
  60. // devuelbe el Pid de un proceso conociendo el nombre del exe
  61. DWORD GetProcessID(char* FileName)
  62. {
  63.   DWORD Result = 0;
  64.   PROCESSENTRY32 proc = { sizeof(proc) };
  65.   HANDLE hSysSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  66. //  if(hSysSnapshot != reinterpret_cast<HANDLE>(-1) && Process32First(hSysSnapshot, &proc)){
  67.   if(hSysSnapshot != INVALID_HANDLE_VALUE && Process32First(hSysSnapshot, &proc)){
  68.     do{
  69.       if(!stricmp(proc.szExeFile, FileName)){
  70.         Result = proc.th32ProcessID;
  71.       }
  72.     }while(Process32Next(hSysSnapshot, &proc));
  73.   }
  74.   CloseHandle(hSysSnapshot);
  75.   return Result;
  76. }
  77.  
  78. BOOL EnablePrivilege(PCSTR name, BOOL Enable = true)
  79. {
  80.   BOOL Result;
  81.   HANDLE hToken;
  82.   TOKEN_PRIVILEGES priv = {1, {0, 0, SE_PRIVILEGE_ENABLED}};
  83.   if(!Enable) priv.Privileges[0].Attributes = 0;
  84.   LookupPrivilegeValue(0, name, &priv.Privileges[0].Luid);
  85.   OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
  86.   AdjustTokenPrivileges (hToken, FALSE, &priv, sizeof priv, 0, 0);
  87.   Result = (GetLastError() == ERROR_SUCCESS);
  88.   CloseHandle (hToken);
  89.   return Result;
  90. }
  91.  
  92. BOOL ImpersonateToLoginUser()
  93. {
  94.   HANDLE hProcess, hToken;
  95.   DWORD  ID;
  96.   BOOL   Result = false;
  97.  
  98.   ID = GetProcessID("winlogon.exe");
  99.   if(ID > 0){
  100.     hProcess = OpenProcess (MAXIMUM_ALLOWED, FALSE, ID);
  101.     if(hProcess != INVALID_HANDLE_VALUE){
  102.       Result = OpenProcessToken(hProcess, MAXIMUM_ALLOWED, &hToken);
  103.       if(Result){
  104.         EnablePrivilege("SeDebugPrivilege");
  105.         Result = ImpersonateLoggedOnUser(hToken);
  106.         CloseHandle(hToken);
  107.       }
  108.       CloseHandle (hProcess);
  109.     }
  110.   }
  111. }
  112.  
  113. String ExtractKey(String XMLText)
  114. {
  115.   int ini, fin;
  116.   String Result = "";
  117.  
  118.   ini = XMLText.Pos("<keyMaterial>");
  119.   fin = XMLText.Pos("</keyMaterial>");
  120.   if(ini != -1 && fin != -1){
  121.     ini = ini + lstrlen("<keyMaterial>");
  122.     Result = XMLText.SubString(ini, fin-ini);
  123.   }
  124.   return Result;
  125. }
  126.  
  127. String DecryptData(String Key)
  128. {
  129.   #define CRYPT_STRING_HEX  0x00000004
  130.  
  131.   typedef BOOL (WINAPI *PCryptStringToBinary)(LPCTSTR pszString, DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags);
  132.   typedef BOOL (WINAPI *PCryptUnprotectData)(DATA_BLOB *pDataIn, LPWSTR *ppszDataDescr, DATA_BLOB *pOptionalEntropy, PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct, DWORD dwFlags, DATA_BLOB *pDataOut);
  133.  
  134.  
  135.   BYTE Buffer[1024];
  136.   DWORD Len;
  137.   DATA_BLOB DataIn, DataOut;
  138.   PCryptStringToBinary _CryptStringToBinary = (PCryptStringToBinary)GetProcAddress(LoadLibrary("Crypt32.dll"), "CryptStringToBinaryA");
  139.   PCryptUnprotectData  _CryptUnprotectData  = (PCryptUnprotectData)GetProcAddress(LoadLibrary("Crypt32.dll"), "CryptUnprotectData");
  140.   String Result = Key;
  141.   Len = 1024;
  142.   ImpersonateToLoginUser();
  143.   if(_CryptStringToBinary(Key.c_str(), Key.Length(), CRYPT_STRING_HEX, Buffer, &Len, 0, 0)){
  144.     DataIn.cbData = Len;
  145.     DataIn.pbData = Buffer;
  146.     DataOut.cbData = 0;
  147.     DataOut.pbData = NULL;
  148.     if(_CryptUnprotectData(&DataIn, NULL, NULL, NULL, NULL, 0, &DataOut))
  149.       Result = String((PCHAR)DataOut.pbData);
  150.   }
  151.   RevertToSelf();
  152.   return Result;
  153. }
  154.  
  155. String WifiGetPassWords()
  156. {
  157.   HANDLE hClient;
  158.   DWORD dwVersion;
  159.   PWLAN_INTERFACE_INFO_LIST pInterfaceInfoList;
  160.   PGUID pInterfaceGuid;
  161.   PWLAN_PROFILE_INFO_LIST pProfileList;
  162.   PWCHAR pstrProfileXml;
  163.   DWORD dwFlags;
  164.   DWORD dwGrantedAccess;
  165.   String Result = "";
  166.  
  167.   if(ERROR_SUCCESS == WlanOpenHandle(1, NULL, &dwVersion, &hClient)){
  168.     if(ERROR_SUCCESS == WlanEnumInterfaces(hClient, NULL, &pInterfaceInfoList)){
  169.       for(int i = 0; i<pInterfaceInfoList->dwNumberOfItems; i++){
  170.         pInterfaceGuid = &pInterfaceInfoList->InterfaceInfo[pInterfaceInfoList->dwIndex].InterfaceGuid;
  171.         if(ERROR_SUCCESS == WlanGetProfileList(hClient, pInterfaceGuid, NULL, &pProfileList)){
  172.           for(int j =0; j < pProfileList->dwNumberOfItems; j++){
  173.             dwFlags = WLAN_PROFILE_GET_PLAINTEXT_KEY;
  174.             if(ERROR_SUCCESS == WlanGetProfile(hClient, pInterfaceGuid, pProfileList->ProfileInfo[j].strProfileName, NULL, &pstrProfileXml, &dwFlags, &dwGrantedAccess)){
  175.               Result = Result + String(pProfileList->ProfileInfo[j].strProfileName) + ": "+ DecryptData(ExtractKey(String(pstrProfileXml))) + "\r\n";
  176.               WlanFreeMemory(pstrProfileXml);
  177.             }
  178.           }
  179.         }
  180.         WlanFreeMemory(pProfileList);
  181.       }
  182.       WlanFreeMemory(pInterfaceInfoList);
  183.     }
  184.     WlanCloseHandle(hClient, NULL);
  185.   }
  186.   return Result;
  187. }
  188.  
  189.  
  190.  
  191.  
  192. //---------------------------------------------------------------------------
  193. __fastcall TForm1::TForm1(TComponent* Owner)
  194.   : TForm(Owner)
  195. {
  196.   InitWLanAPI();
  197. }
  198. //---------------------------------------------------------------------------
  199.  
  200. void __fastcall TForm1::Button1Click(TObject *Sender)
  201. {
  202.   Memo1->Lines->Clear();
  203.   Memo1->Lines->Add(WifiGetPassWords());
  204. }
  205. //---------------------------------------------------------------------------



Saludos.

Archivos adjuntos


  • 1

#14 monchito_elroro

monchito_elroro

    Advanced Member

  • Miembros
  • PipPipPip
  • 259 mensajes

Escrito 07 septiembre 2016 - 10:51

Excelente Maestro se que a muchos les será muy útil :) :)


  • 0

#15 tmsanchez

tmsanchez

    Advanced Member

  • Miembros
  • PipPipPip
  • 85 mensajes

Escrito 07 septiembre 2016 - 05:09

Excelente aporte, gracias!


  • 0

#16 sir.dev.a.lot

sir.dev.a.lot

    Advanced Member

  • Miembros
  • PipPipPip
  • 545 mensajes
  • Location127.0.0.1

Escrito 11 septiembre 2016 - 09:12

Tambien si te sabes el perfil y te la han puesto dificil para conectar un USB, usar Internet o cualquier Restriccion. ;)

 

puedes usar este comando:

 

netsh wlan show profile name=”Aqui.va.el.nombre.del.perfil” key=clear

 

Saludos!


  • 1

#17 johe_valencia

johe_valencia

    Newbie

  • Miembros
  • Pip
  • 1 mensajes

Escrito 18 febrero 2017 - 10:47

Con una pequeña modificación podemos ejecutar como usuario no administrador en S.O. mayores de Vista y nos dará las claves directamente sin necesidad de desencriptarlas.


delphi
  1. function WifiGetPassWords: String;
  2. var
  3. hClient: THandle;
  4. dwVersion: DWORD;
  5. pInterfaceInfoList: PWLAN_INTERFACE_INFO_LIST;
  6. pInterfaceGuid: PGUID;
  7. pProfileList: PWLAN_PROFILE_INFO_LIST;
  8. pstrProfileXml: PWCHAR;
  9. dwFlags: DWORD;
  10. dwGrantedAccess: DWORD;
  11. i,j: integer;
  12. begin
  13. Result:= '';
  14. dwFlags:= 0;
  15. dwGrantedAccess:= 0;
  16.  
  17. if ERROR_SUCCESS = WlanOpenHandle(1, nil, @dwVersion, @hClient) then
  18. begin
  19. if ERROR_SUCCESS = WlanEnumInterfaces(hClient, nil, @pInterfaceInfoList) then
  20. begin
  21. for i:= 0 to pInterfaceInfoList^.dwNumberOfItems - 1 do
  22. begin
  23. pInterfaceGuid:= @pInterfaceInfoList^.InterfaceInfo[pInterfaceInfoList^.dwIndex].InterfaceGuid;
  24. if ERROR_SUCCESS = WlanGetProfileList(hClient, pInterfaceGuid, nil, @pProfileList) then
  25. begin
  26. for j:=0 to pProfileList.dwNumberOfItems-1 do
  27. begin
  28. dwFlags:= WLAN_PROFILE_GET_PLAINTEXT_KEY;
  29. if ERROR_SUCCESS = WlanGetProfile(hClient, pInterfaceGuid, pProfileList.ProfileInfo[j].strProfileName, nil, @pstrProfileXml, @dwFlags, @dwGrantedAccess) then
  30. begin
  31. Result:= Result + String(pProfileList.ProfileInfo[j].strProfileName) + ': '+ DecryptData(ExtractKey(String(pstrProfileXml))) + #13 + #10;
  32. WlanFreeMemory(pstrProfileXml);
  33. end;
  34. end;
  35. end;
  36. WlanFreeMemory(pProfileList);
  37. end;
  38. WlanFreeMemory(pInterfaceInfoList);
  39. end;
  40. WlanCloseHandle(hClient, nil);
  41. end;
  42. end;

Subo la actualización, que lo disfrutéis.
 
Saludos.

 

disculpa eh querido ejecutar en windows 7, pero me sale cifrada, colo si ejecuto como administrador me sale texto plano, como podria ejecutar sin administrador y que salga de igual manera en texto plano


  • 0

#18 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 19 febrero 2017 - 02:31

disculpa eh querido ejecutar en windows 7, pero me sale cifrada, colo si ejecuto como administrador me sale texto plano, como podria ejecutar sin administrador y que salga de igual manera en texto plano

 
La API WlanGetProfile admite WLAN_PROFILE_GET_PLAINTEXT_KEY desde Win7 pero para que en este S.O. tenga efectividad, el proceso debe tener permiso wlan_secure_get_plaintext_key ese permiso lo tienen los administradores por defecto. LA API WlanSetSecuritySettings permite otorgar el permiso mediante un complejo proceso que no he experimentado pero sospecho que debe hacerse con permisos de administrador.

 

Sin embargo en Win10 y creo que en Win8 y 8.1 (ahora no recuerdo si lo probé en ellos, aunque estoy casi seguro de que si lo hice), cualquier usuario puede acceder al texto plano de las claves Wifi.

 

 

Saludos.


  • 0




IP.Board spam blocked by CleanTalk.