OVH Cloud OVH Cloud

Taguer les mails de la fonction mail()

9 réponses
Avatar
benji
Bonjour à tous,

après pas mal de recherches j'ai pas réussi à trouver une solution
satisfaisante, je me tourne donc vers vous.

Sur un serveur debian que j'administre (des pages perso d'étudiants)
j'ai des utilisateurs qui utilisent des scripts avec la fonction mail,
certains sont pas du tout sécurisés et sont exploités pour envoyer
du spam (et donc queue de qmail avec des milliers de mails...).
J'aimerais bien "taguer" les mails envoyés avec la fonction mail en
rajoutant une ligne contenant l'user qui execute le script ; puisque
sur le serveur les scripts sont éxécutés sous l'user du proprietaire
du compte. L'interet serait d'isoler tout de suite le compte d'origine
en repérant cette ligne dans la source des mails, pour ensuite
analyser le compte et arréter l'envoi de spam.
A priori il faut modifier les sources de php, mais j'ai pas trouvé de
pistes pour le moment, si quelqu'un à une idée (ou une meilleure
solution).

merci à tous,

Benjamin

9 réponses

Avatar
John GALLET
Bonjour,

j'ai des utilisateurs qui utilisent des scripts avec la fonction mail,
"L'ennemi, c'est l'utilisateur (tm)."


J'aimerais bien "taguer" les mails envoyés avec la fonction mail en
rajoutant une ligne contenant l'user qui execute le script ; puisque
sur le serveur les scripts sont éxécutés sous l'user du proprietaire
du compte. L'interet serait d'isoler tout de suite le compte d'origine
en repérant cette ligne dans la source des mails, pour ensuite
analyser le compte et arréter l'envoi de spam.


Soit. Il me semblait que par défaut sur unix c'était le cas justement,
et que sendmail met le compte unix du user apache/web dans le return path.

A priori il faut modifier les sources de php, mais j'ai pas trouvé de
pistes pour le moment, si quelqu'un à une idée (ou une meilleure
solution).
Ca ne marchera jamais étant donné que les gusses ont la main sur leur code.


Trois solutions à mon sens.

1) on met mail() dans la liste des disabled_functions de php.ini et fin
de la discussion. Fin aussi des fonctionnalités gérées par cet envoi,
s'il y en a de véritablement justifiées.

2) N'oublions pas que PHP est Open-source... on recompile PHP en
modifiant la fonction mail() pour en fournir une à votre propre sauce
locale. C'est fait chez beaucoup d'hébergeurs (et c'est passablement
casse-pieds, mais parfois efficace si fait intelligement). L'avantage
est de centraliser le code. Ca ajoute automatiquement tous les headers
que tu voudras. Il faut gérer les mises à jour de PHP, mais ce n'est pas
si compliqué.

3) On gère ça de manière encore plus centralisée avec des arguments
passés à sendmail. Par exemple :

<VirtualHost ip>
ServerName machin.tld
ServerAlias *.machin.tld
User trucnuche
Group lusers
ServerAdmin
DocumentRoot /home/truc/www/
php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f
"
</VirtualHost>

Tout ce qui sortira de ce virtualhost aura "" comme
return path (attention formattage newsgroup, c'est sur une seule ligne).

Au passage on compile php en safe_mode histoire de virer quelques
injections de headers dans mail() (mais pas nécessairement toutes, gain
mitigé).

Une quatrième solution plus préventive consiste à faire tourner tous les
jours une moulinette du genre :
find /wwwroot -type f -mtime -2 -print -exec grep -i mail {} ;
à piper dans un filtre un peu plus violent et de valider à l'avance avec
l'étudiant ses scripts. Ou de rappeler qu'en vertu de la Charte
d'utilisation des ressources informatiques qu'ils ont signé (n'est-ce
pas...) ils sont juridiquement responsables du spam envoyé par leurs
scripts et que toute utilisation d'un certain nombre de fonctions php
(dont mail()) n'est autorisée qu'après validation commune avec "ue
autorité compétente". Etc...

HTH
JG

Avatar
benji
Bonjour,

A priori il faut modifier les sources de php, mais j'ai pas trouvé de
pistes pour le moment, si quelqu'un à une idée (ou une meilleure
solution).
Ca ne marchera jamais étant donné que les gusses ont la main sur leur code.



en fait quand je disais les sources de php je pensais à php en lui
meme comme votre solution 2) le suggère. Puisqu'il n'est pas vraiment
possible de retirer cette fonction (elle sert pour des applications
légitimes) et une vérification manuelle prendrait trop de temps.
Si vous avez des pistes sur ce qu'il faut modifier en gros dans les
sources de php.


3) On gère ça de manière encore plus centralisée avec des arguments
passés à sendmail. Par exemple :

<VirtualHost ip>
ServerName machin.tld
ServerAlias *.machin.tld
User trucnuche
Group lusers
ServerAdmin
DocumentRoot /home/truc/www/
php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f
"
</VirtualHost>


c'est une version CGI de php, et il me semble qu'on peut pas utiliser
les "php_admin_value" dans cette forme, si je me trompe pas.

merci,

bonne journée,


Avatar
John GALLET
en fait quand je disais les sources de php je pensais à php en lui
meme comme votre solution 2) le suggère.
Ok donc quitte à recompiler, on peut peut-être ne plus être en cgi ?



Puisqu'il n'est pas vraiment
possible de retirer cette fonction (elle sert pour des applications
légitimes)
Selon la configuration on peut peut-être la désactiver selon les applis

à grands coups de directives apache (si c'est apache le serveur web,
bref, il nous faudrait qq informations de plus).


Si vous avez des pistes sur ce qu'il faut modifier en gros dans les
sources de php.
Concernant le fichier, on n'a pas beaucoup de candidats:


find php-5.1.4/ -name "*mail*c"
php-5.1.4/ext/standard/mail.c
php-5.1.4/win32/sendmail.c

En revanche, récupérer dans la fonction C mail() les informations
nécessaires sur le user unix qui exécute, c'est une autre affaire à
laquelle je n'ai jamais joué, mais il doit bien y avoir quelque part
dans php le code kivabien.

Allez au pif :
grep myuid php-5.1.4/ext/standard/*

php-5.1.4/ext/standard/pageinfo.c:/* {{{ proto int getmyuid(void)

Avec ça, à la grosse louche, on devrait avoir de quoi faire la modif.

c'est une version CGI de php, et il me semble qu'on peut pas utiliser
les "php_admin_value" dans cette forme, si je me trompe pas.


Je ne sais plus, il suffit d'essayer ça ira aussi vite que de
farfouiller la doc.

JG

Avatar
Calimero
John GALLET wrote:
en fait quand je disais les sources de php je pensais à php en lui
meme comme votre solution 2) le suggère.


Ok donc quitte à recompiler, on peut peut-être ne plus être en cgi ?


Y a peut-être du suPHP/suExec là dessous ?

--
@+
Calimero


Avatar
benji
Bonjour,


Y a peut-être du suPHP/suExec là dessous ?



effectivement

bonne journée,

Avatar
benji
Bonjour,

find php-5.1.4/ -name "*mail*c"
php-5.1.4/ext/standard/mail.c
php-5.1.4/win32/sendmail.c
[..]

Allez au pif :
grep myuid php-5.1.4/ext/standard/*

php-5.1.4/ext/standard/pageinfo.c:/* {{{ proto int getmyuid(void)


Dans la fonction php_mail de ext/standard/mail.c

j'ai rajouté :

long int tag;
tag = getmyuid();

Puis dans la section :

fprintf(sendmail, "To: %sn", to);
fprintf(sendmail, "Subject: %sn", subject);
if (headers != NULL) {
fprintf(sendmail, "%sn", headers);
}
fprintf(sendmail, "n%sn", message);
ret = pclose(sendmail);


j'ai rajouté fprintf(sendmail, "Id : %d n", tag);

le but étant de taguer l'email avec l'uid qui lance le script.

En statique (avec tag = 1234 par exemple donc sans utiliser getmyuid()
) ça fonctionne, le champ est bien rajouté au mail.
En utilisant getmyuid() j'ai une erreur de compilation : "mail.c:229:
undefined reference to `getmyuid'"
il ne connait pas getmyuid(), c'est ma première modification des
sources de php, mais normalement il devrait avoir accès aux fonctions
de ext/standard/pageinfo.c ?

si vous avez une idée,

merci pour vos infos,

Avatar
John GALLET
Bonjour,


Allez au pif :
grep myuid php-5.1.4/ext/standard/*

php-5.1.4/ext/standard/pageinfo.c:/* {{{ proto int getmyuid(void)


long int tag;
tag = getmyuid();


(C'est pas un long c'est un int tout court).

j'ai rajouté fprintf(sendmail, "Id : %d n", tag);
A vérifier si le champ "Id" ne va pas f.. le b... partout. Moi je

n'utiliserais certainement pas un nom aussi bateau pour une donnée qui
va traverser watt-milliards de serveurs sur la planète. Je sais pas moi,
soyons inventifs...X-[abbréviation de votre école]-Id ou -Src mais "Id"
tout court, si ça fout pas la m... aujourd'hui ou demain j'en veux des
cacahuètes. En plus, à grepper dans des logs, ça sera sacrément plus
facile, non (au lieu de se bouffer les Message-Id) ?

En utilisant getmyuid() j'ai une erreur de compilation : "mail.c:229:
undefined reference to `getmyuid'"
il ne connait pas getmyuid(), c'est ma première modification des
sources de php, mais normalement il devrait avoir accès aux fonctions
de ext/standard/pageinfo.c ?
"normalement" ? Qu'est-ce que la normalité dans la définition des

modules de compilation d'un programme C et leur découpage en headers ?

si vous avez une idée,
Vérifier dans quel header est définit getmyuid() (pageinfo.h ?) et

vérifier qu'il est bien inclut dans le fichier modifié. Je n'ai pas les
sources de PHP sous la main pour le faire.

On commence à sortir de la Charte, c'est un problème de compil de C
pure... Mon mail perso est public depuis bientôt 10 ans, vous pouvez
m'envoyer le fichier (et la version de php, plus les options du
./configure) si vous voulez, je jetterai un oeil.

JG


Avatar
m-e-
"John GALLET" a écrit dans le message
de news: 44e98127$0$19152$
[...]
2) N'oublions pas que PHP est Open-source... on recompile PHP
en
modifiant la fonction mail() pour en fournir une à votre
propre sauce
locale. C'est fait chez beaucoup d'hébergeurs (et c'est
passablement
casse-pieds, mais parfois efficace si fait intelligement).
L'avantage
est de centraliser le code. Ca ajoute automatiquement tous les
headers
que tu voudras. Il faut gérer les mises à jour de PHP, mais ce
n'est pas
si compliqué.
[...]


Et pourquoi ne pas écrire un script qui va faire l'interface
avec sendmail, et renseigner ce script dans le sendmail_path de
PHP ?

Avatar
John GALLET
Bonjour,

Et pourquoi ne pas écrire un script qui va faire l'interface
avec sendmail, et renseigner ce script dans le sendmail_path de
PHP ?


Si on dispose dans le shell des informations que l'on recherche (est-ce
que la commande shell id ou whoami ou équivalent renverra bien les
bonnes infos), oui c'est une solution tout à fait recevable.

JG