WD My Cloud et ses secrets II
Des secrets, mais pas trop
Dans l'article précédent, on a pu voir que le NAS se rendait visible sur Internet sans nous demander notre avis. Et que fait-il d'autre ce NAS. Et bien il met en place une sorte de DNS Dynamique (DynDNS) en s'appuyant sur le serveur de WD présent à l'adresse 129.253.8.107. Pour réussir ce travail, il doit informer le serveur de sa présence sur Internet. C'est-à-dire, qu'il doit dire à WD qui il est et où (adresse ip s'entend) il est. Pour réussir à voir cet échange d'information, il faut faire un déchiffrage SSL. En effet, tous les échanges fait entre le NAS et le site de WD sont chiffrés. Le problème c'est que le NAS n'utilise pas un navigateur web comme Firefox pour faire son travail. Il va donc falloir creuser un peu plus...
Dans cet article, on va voir :
- Quel programme envoie les informations
- Comment il les envoie
- La mise en place d'outils de cross compilation
- Le tuning du programme chargé d'envoyer les informations pour en permettre le déchiffrage
Quel programme envoi les informations
Par une méthode un peu archaïque :), je détermine que le programme qui envoi les informations de mon NAS chez www.wd2go.com est le programme communicationma
root@nas:~# netstat -paon | grep 198.107.148.110
PID/prg -> communicationma
Et
root@nas:~# ps faux | grep communicationma
root 24786 0.0 2.0 21184 4800 ? SNs 11:00 0:02 /usr/local/orion/communicationmanager/communicationmanager -f 120 -l 5
Les paramètres -f et -l correspondent à
-f nnn (seconds) or -check_frequency nnn (seconds)
-l or -enable_log nnn (log severity level)
Plus précisément
Quel partie du programme envoi ces informations et comment.
- Il faut déjà avoir téléchargé le firmware depuis le site de WD
- En extraire le fichier rootfs.img
- Et monter le système de fichier rootfs.img dans /mnt
ubuntu@bidouille:/mnt$ strings usr/local/orion/communicationmanager/communicationmanager
blablabla
OrionClient::getRestUrl - baseSSLServerUrl %s.
OrionClient::getRestUrl - Invalid http type %d. Use only the input urn.
OrionClient::getRestUrl - restURL %s.
OrionClient:httpGet - empty url
OrionClient::httpGet Error: [%s]
** OrionClient::httpGet - Throw exception error. **
OrionClient::initialize() - failed to read DEVICEID, DEVICEAUTH from dynamic config file
OrionClient::initialize() - CURL initialization failed.
disabled
OrionClient::getInstance() - initialize() returned false, set Comm Status to [disabled]
OrionClient::pollServerForSleepTime - central server already polled. Sleep time is %d secs.
blablabla
Bon, on est pas mal là. Reste à savoir comment le programme fait une requête GET. Reste plus qu'à dé-assembler le binaire...
On peut traduire le code assembleur ci-dessus par le code C suivant (environ)
#include <stdio.h>
#include <curl/curl.h>
function(void *, size_t, size_t, void *)
{
return 0;
}
int main(int argc, char **argv)
{
/****************************
*Le reste du programme
****************************/
CURL *curl;
int var = 0;
char url[] = "www.wd2go.com";
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 30000);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, function);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &var);
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
/****************************
* Le reste du programme
****************************/
return 0;
}
Pour connaître les valeurs échangées entre mon NAS et le site web, il faudra donc faire un peu de « tuning » du programme cURL :)
Cross-compilation
Pour compiler un programme pour le NAS, il serait simple d'installer toutes les librairies nécessaires avec le traditionnel apt-get install. Malheureusement c'est pas possible! Le NAS est un mélange d'une version debian wheezy et d'une debian jessie. De plus, la compilation des paquets a été réalisée avec un compilateur gcc-linearo patché par WD pour être aligné sur des pages mémoires de 64k.
Il va donc falloir suivre la méthode WD
Mise en place des outils
Il faut commencer par créer une machine virtuelle Ubuntu x86 Desktop 10.04 et la démarrer. Ensuite, depuis la machine virtuelle, télécharger cette archive et extraire son contenu. Dans le contenu extrait, il faut se rendre dans packages/build_tools/compilers/ et à nouveau extraire le contenu de gcc-linaro-arm-linux-gnueabihf-4.7-64k-2013.01-20130116_linux.tar.bz2.
Voilà, on est prêt pour le build du compilateur. On va utiliser le script fournit par WD après avoir fait une mise-à-jour du système.
ubuntu@virtuelle:~$ sudo apt-get update
ubuntu@virtuelle:~$ sudo apt-get dist-upgrade
# reboot nécessaire car nouveau noyau
ubuntu@virtuelle:~$ cd Téléchargement/packages/build_tools/compilers/src/
ubuntu@virtuelle:~/Téléchargement/packages/build_tools/compilers/src/$ sudo ./build.sh
#blablabla
[EXTRA] Extracting 'gcc-linaro-4.7-2013.01'
[EXTRA] Patching 'gcc-linaro-4.7-2013.01'
[EXTRA] Extracting 'precise-sysroot-armhf-1+bzr2433'
[EXTRA] Patching 'prebuilt-precise-sysroot-armhf-1+bzr2433'
[EXTRA] Extracting 'gdb-linaro-7.5-2012.12'
[EXTRA] Patching 'gdb-linaro-7.5-2012.12'
# Ça semble bien se préparer :)
[INFO ] Installing final compiler
[EXTRA] Configuring final compiler
[EXTRA] Building final compiler
[EXTRA] Installing final compiler
[EXTRA] Building the GCC manuals
[EXTRA] Installing the GCC manuals
# Et quelques bières plus tard... On y croit ...
bzip2 -fk9 builds/arm-linux-gnueabihf-linux/gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130116_linux.tar
xz -fk9 builds/arm-linux-gnueabihf-linux/gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130116_linux.tar
#voyons ça
ubuntu@virtuelle:~/Téléchargements/packages/build_tools/compilers/src$ ls bin
gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130116_linux.tar.bz2
ubuntu@virtuelle:~/Téléchargements/packages/build_tools/compilers/src$ cd bin
ubuntu@virtuelle:~/Téléchargements/packages/build_tools/compilers/src/bin$ tar xvf gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130116_linux.tar.bz2
ubuntu@virtuelle:~/Téléchargements/packages/build_tools/compilers/src/bin$ ls gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130116_linux/bin/
arm-linux-gnueabihf-addr2line arm-linux-gnueabihf-g++ arm-linux-gnueabihf-gfortran arm-linux-gnueabihf-objdump
arm-linux-gnueabihf-ar arm-linux-gnueabihf-gcc arm-linux-gnueabihf-gprof arm-linux-gnueabihf-pkg-config
arm-linux-gnueabihf-as arm-linux-gnueabihf-gcc-4.7.3 arm-linux-gnueabihf-ld arm-linux-gnueabihf-pkg-config-real
arm-linux-gnueabihf-c++ arm-linux-gnueabihf-gcc-ar arm-linux-gnueabihf-ld.bfd arm-linux-gnueabihf-ranlib
arm-linux-gnueabihf-c++filt arm-linux-gnueabihf-gcc-nm arm-linux-gnueabihf-ldd arm-linux-gnueabihf-readelf
arm-linux-gnueabihf-cpp arm-linux-gnueabihf-gcc-ranlib arm-linux-gnueabihf-ld.gold arm-linux-gnueabihf-size
arm-linux-gnueabihf-ct-ng.config arm-linux-gnueabihf-gcov arm-linux-gnueabihf-nm arm-linux-gnueabihf-strings
arm-linux-gnueabihf-elfedit arm-linux-gnueabihf-gdb arm-linux-gnueabihf-objcopy arm-linux-gnueabihf-strip
Yes! On a le compilateur :)
Quelques variables d'environnement pour la compilation
Il faut commencer par mettre à jour la variable PATH pour que le système trouve le compilateur fraîchement crée. ATTENTION à adapter ce chemin à votre installation!
ubuntu@virtuelle:~$ export PATH=$HOME/Bureau/WDMyCloud/toolchain/bin:$PATH
On crée ensuite une variable indiquant où on souhaite placer les fichiers crées (résultats des différentes compilations).
ubuntu@virtuelle:~$ export PREFIX=$HOME/Bureau/WDMyCloud/usr/local
Pour terminer, on crée deux variables utilisées comme paramètre pour les compilations. La première précise la cible (ARM) et la seconde combinée à la première, donne le nom du compilateur.
ubuntu@virtuelle:~$ export HOST=arm-linux-gnueabihf
ubuntu@virtuelle:~$ export CC=${HOST}-gcc
En résumé:
ubuntu@virtuelle:~$ echo $PATH
/home/ubuntu/Bureau/WDMyCloud/toolchain/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
ubuntu@virtuelle:~$ echo $PREFIX
/home/ubuntu/Bureau/WDMyCloud/usr/local
ubuntu@virtuelle:~$ echo $HOST
arm-linux-gnueabihf
ubuntu@virtuelle:~$ echo $CC
arm-linux-gnueabihf-gcc
Création du répertoire correspondant à $PREFIX et copie de l'archive crée à la compilation (packages/build_tools/compilers/src/bin/gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130116_linux.tar.bz2).
ubuntu@virtuelle:~$ mkdir -p $HOME/Bureau/WDMyCloud/src
ubuntu@virtuelle:~$ cd $HOME/Bureau/WDMyCloud
ubuntu@virtuelle:~/Bureau/WDMyCloud$ mkdir toolchain
ubuntu@virtuelle:~/Bureau/WDMyCloud$ cp ~/Téléchargements/packages/build_tools/compilers/src/bin/gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130116_linux.tar.bz2/ ./src
On peut maintenant aller chercher les sources nécessaires à la compilation de cURL et de ses libraires (en tout cas une partie, zlib et openssl).
ubuntu@virtuelle:~$ cd Bureau/WDMyCloud/src
ubuntu@virtuelle:~/Bureau/WDMyCloud/src$ sudo -s
root@virtuelle:~/Bureau/WDMyCloud/src# mv /etc/apt/sources.list /etc/apt/sources.list.orig
root@virtuelle:~/Bureau/WDMyCloud/src# echo ''deb http://ch.archive.ubuntu.com/ubuntu/ trusty main restricted universe
> deb-src http://ch.archive.ubuntu.com/ubuntu/ trusty main restricted universe'' > /etc/apt/sources.list
root@virtuelle:~/Bureau/WDMyCloud/src# cat /etc/apt/sources.list
deb http://ch.archive.ubuntu.com/ubuntu/ trusty main restricted universe
deb-src http://ch.archive.ubuntu.com/ubuntu/ trusty main restricted universe
root@virtuelle:~/Bureau/WDMyCloud/src# exit
exit
ubuntu@virtuelle:~/Bureau/WDMyCloud/src$ sudo apt-get update
ubuntu@virtuelle:~/Bureau/WDMyCloud/src$ apt-get -d source zlib openssl ssh curl
Lecture des listes de paquets... Fait
Construction de l''arbre des dépendances
Lecture des informations d''état... Fait
Choix de « openssh » comme paquet source à la place de « ssh »
Note : la maintenance du paquet de « openssh » est réalisée dans le système de suivi de versions « Git » à l''adresse :
git://anonscm.debian.org/pkg-ssh/openssh.git
Note : la maintenance du paquet de « curl » est réalisée dans le système de suivi de versions « Git » à l''adresse :
git://anonscm.debian.org/collab-maint/curl.git
Nécessité de prendre 10.0Mo dans les sources.
Réception de : 1 http://ch.archive.ubuntu.com/ubuntu/ trusty/main zlib 1:1.2.8.dfsg-1ubuntu1 (dsc) [2''543B]
Réception de : 2 http://ch.archive.ubuntu.com/ubuntu/ trusty/main zlib 1:1.2.8.dfsg-1ubuntu1 (tar) [362kB]
Réception de : 3 http://ch.archive.ubuntu.com/ubuntu/ trusty/main zlib 1:1.2.8.dfsg-1ubuntu1 (diff) [17.4kB]
Réception de : 4 http://ch.archive.ubuntu.com/ubuntu/ trusty/main openssl 1.0.1f-1ubuntu2 (dsc) [2''358B]
Réception de : 5 http://ch.archive.ubuntu.com/ubuntu/ trusty/main openssl 1.0.1f-1ubuntu2 (tar) [4''509kB]
Réception de : 6 http://ch.archive.ubuntu.com/ubuntu/ trusty/main openssl 1.0.1f-1ubuntu2 (diff) [113kB]
Réception de : 7 http://ch.archive.ubuntu.com/ubuntu/ trusty/main openssh 1:6.6p1-2ubuntu1 (dsc) [2''665B]
Réception de : 8 http://ch.archive.ubuntu.com/ubuntu/ trusty/main openssh 1:6.6p1-2ubuntu1 (tar) [1''283kB]
Réception de : 9 http://ch.archive.ubuntu.com/ubuntu/ trusty/main openssh 1:6.6p1-2ubuntu1 (diff) [142kB]
Réception de : 10 http://ch.archive.ubuntu.com/ubuntu/ trusty/main curl 7.35.0-1ubuntu2 (dsc) [2''729B]
Réception de : 11 http://ch.archive.ubuntu.com/ubuntu/ trusty/main curl 7.35.0-1ubuntu2 (tar) [3''544kB]
Réception de : 12 http://ch.archive.ubuntu.com/ubuntu/ trusty/main curl 7.35.0-1ubuntu2 (diff) [36.4kB]
10.0Mo réceptionnés en 8s (1''237ko/s)
Téléchargement achevé et dans le mode téléchargement uniquement
ubuntu@virtuelle:~/Bureau/WDMyCloud/src$ ls
curl-7.35.0 openssh_6.6p1-2ubuntu1.debian.tar.xz openssl_1.0.1f.orig.tar.gz
curl_7.35.0-1ubuntu2.debian.tar.gz openssh_6.6p1-2ubuntu1.dsc zlib-1.2.8
curl_7.35.0-1ubuntu2.dsc openssh_6.6p1.orig.tar.gz zlib_1.2.8.dfsg-1ubuntu1.debian.tar.gz
curl_7.35.0.orig.tar.gz openssl-1.0.1f zlib_1.2.8.dfsg-1ubuntu1.dsc
gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130116_linux.tar.bz2 openssl_1.0.1f-1ubuntu2.debian.tar.gz zlib_1.2.8.dfsg.orig.tar.gz
openssh-6.6p1 openssl_1.0.1f-1ubuntu2.dsc
ubuntu@virtuelle:~/Bureau/WDMyCloud/src$ for i in `ls *.tar.*|grep -v debian`;do tar xf $i;done;
ubuntu@virtuelle:~/Bureau/WDMyCloud/src$ mv -f gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130116_linux/* ../toolchain/
ubuntu@virtuelle:~/Bureau/WDMyCloud/src$ ls ../toolchain/
arm-linux-gnueabihf bin lib libexec share
ubuntu@virtuelle:~/Bureau/WDMyCloud/src$ sudo mv /etc/apt/sources.list.orig /etc/apt/sources.list
ubuntu@virtuelle:~/Bureau/WDMyCloud/src$ sudo apt-get update
Voilà! On peut commencer les compilations:
cURL « tuné » sur le NAS
Maintenant que notre cURL « tuné » est prêt, il faut le mettre sur le NAS. Pour ce faire, il suffit de se connecter en SSH sur le NAS et remplacer les fichiers :- libcurl.so.4.3.0
- libcurl.so -> libcurl.so.4.3.0
- libcurl.so.4 -> libcurl.so.4.3.0
- curl
Une fois le travail de remplacement effectué, quand on demande la version de cURL dans le shell du NAS:
Nous voilà prêt à déchiffrer les informations transitant entre le NAS et le site de WD. On verra tout ça dans un prochain article.