Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

seteuid inefficace?

7 réponses
Avatar
Kevin Denis
Bonjour,

j'ai un programme tout simple:
#include <stdio.h>
#include <stdlib.h>
int main(){
seteuid(1002);
system("/bin/sh");
return 0;
}
dont les droits sont:
-rws--x--x 1002 1001

Lorsque je l'exécute en tant qu'utilisateur 1001, je devrais avoir un
shell en uid 1002, mais ce n'est pas le cas, pourquoi?
un ps auxf me montre bien que le programme tourne bien en 1002 mais
le shell est en 1001 (?)

Une idée sur la raison?

Merci
--
Kevin

7 réponses

Avatar
Éric Lévénez
Le 19/03/12 11:03, Kevin Denis a écrit :
Bonjour,

j'ai un programme tout simple:
#include<stdio.h>
#include<stdlib.h>
int main(){
seteuid(1002);
system("/bin/sh");
return 0;
}



Il manque l'include unistd.
Il manque un void à main.
Il manque le test des codes de retour des fonctions.

dont les droits sont:
-rws--x--x 1002 1001

Lorsque je l'exécute en tant qu'utilisateur 1001, je devrais avoir un
shell en uid 1002, mais ce n'est pas le cas, pourquoi?



Parce qu'il faut utiliser setuid au lieu de seteuid.

un ps auxf me montre bien que le programme tourne bien en 1002 mais
le shell est en 1001 (?)

Une idée sur la raison?



Mauvaise lecture des man.

--
Éric Lévénez
FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Avatar
Kevin Denis
Le 19-03-2012, Éric Lévénez a écrit :
j'ai un programme tout simple:
#include<stdio.h>
#include<stdlib.h>
int main(){
seteuid(1002);
system("/bin/sh");
return 0;
}



Il manque l'include unistd.
Il manque un void à main.
Il manque le test des codes de retour des fonctions.



mon code est un peu plus long, j'ai voulu réduire. Le fait est que
j'observe bien ce comportement avec celui-ci.

Lorsque je l'exécute en tant qu'utilisateur 1001, je devrais avoir un
shell en uid 1002, mais ce n'est pas le cas, pourquoi?



Parce qu'il faut utiliser setuid au lieu de seteuid.



Been there, done that. Même punition, je reste avec un shell id 1001:
:/source# cat prog.c
#include <stdio.h>
#include <stdlib.h>
int main(){
setuid(1002);
system("/bin/sh");
return 0;
}
:/source# gcc -o prog prog.c
:/source# chown 1002.1001 prog
:/source# chmod u+s prog
:/source# su user1
:/source$ ls -l prog
-rwsr-xr-x 1 user2 user1 5700 Mar 19 11:29 prog
:/source$ ./prog
sh-4.1$ id
uid01(user1) gid01(user1) groups01(user1)
sh-4.1$

Je suis quasi sûr que le programme d'origine fonctionnait, mais là
je reste perplexe.
--
Kevin
Avatar
espie
In article ,
Kevin Denis wrote:
Le 19-03-2012, Éric Lévénez a écrit :
j'ai un programme tout simple:
#include<stdio.h>
#include<stdlib.h>
int main(){
seteuid(1002);
system("/bin/sh");
return 0;
}



Il manque l'include unistd.
Il manque un void à main.
Il manque le test des codes de retour des fonctions.



mon code est un peu plus long, j'ai voulu réduire. Le fait est que
j'observe bien ce comportement avec celui-ci.

Lorsque je l'exécute en tant qu'utilisateur 1001, je devrais avoir un
shell en uid 1002, mais ce n'est pas le cas, pourquoi?



Parce qu'il faut utiliser setuid au lieu de seteuid.



Been there, done that. Même punition, je reste avec un shell id 1001:
:/source# cat prog.c
#include <stdio.h>
#include <stdlib.h>
int main(){
setuid(1002);
system("/bin/sh");
return 0;
}



Ben deja, setuid, c'est un appel systeme. Tu ne verifies MEME PAS s'il
fonctionne. Faudrait peut-etre commencer par ca: t'assurer que ton
setuid() renvoie bien 0, et sinon faire un perror().

**************************************************************************
*
* C'est le BA-ba de la programmation systeme. Le premier truc que j'essaie
* de rentrer dans la tete a mes etudiants: si vous avez un appel qui PEUT
* echouer, TOUJOURS TOUJOURS verifier le resultat. MEME sur les programmes
* de test, SURTOUT sur les programmes de test. Pourquoi s'obliger a
* reflechir quand la machine peut faire ca a notre place ?
*
**************************************************************************

Ensuite, tu ne nous dis absolument pas dans quel contexte tu te places.
Au pif, je dirais une slackware, mais tu n'as rien dit.

Si ca se trouve, tu as un systeme d'ACL en place qui fait que tu ne
peux pas faire ce que tu veux quand tu veux au niveau uid...
Avatar
Kevin Denis
Le 19-03-2012, Marc Espie a écrit :
Ben deja, setuid, c'est un appel systeme. Tu ne verifies MEME PAS s'il
fonctionne. Faudrait peut-etre commencer par ca: t'assurer que ton
setuid() renvoie bien 0, et sinon faire un perror().



Ok, je fais un programme plus long, cf plus bas.

Machine et système utilisé:

:/tmp# uname -a
Linux slack 2.6.37.6-smp #2 SMP Sat Apr 9 23:39:07 CDT 2011 i686 QEMU
Virtual CPU version 0.12.5 GenuineIntel GNU/Linux
:/tmp# cat /etc/slackware-version
Slackware 13.37.0
:/tmp#

slackware 13.37, installée dans un KVM, tout par défaut.

Si ca se trouve, tu as un systeme d'ACL en place qui fait que tu ne
peux pas faire ce que tu veux quand tu veux au niveau uid...



:/tmp# cat prog.c
#include <stdio.h>
#include <stdlib.h>
int main(){
int r;
fopen("/tmp/out","w+");
r = seteuid(1002);
printf("valeur retour %dn", r);
system("/bin/sh");
return 0;
}
:/tmp# gcc -o prog prog.c ; chown 1002.1001 prog ; chmod u+s prog
:/tmp# su user1
:/tmp$ ./prog
valeur retour 0
sh-4.1$ ls -l
total 12
-rw-r--r-- 1 user2 user1 0 Mar 19 12:36 out
-rwsr-xr-x 1 user2 user1 5968 Mar 19 12:36 prog
-rw-r--r-- 1 user1 user1 192 Mar 19 12:29 prog.c
sh-4.1$ id
uid01(user1) gid01(user1) groups01(user1)
sh-4.1$

Je vérifie que la valeur retour est bonne, que le programme tourne
bien en 1002 (bit s) mais le shell s'obstine à être en 1001. Je
mattends à observer:
uid01(user1) euid02(user2) gid01(user1) groups01(user1)

(et j'ai testé avec setuid au lieu de seteuid, mais le résultat est
le même)
--
Kevin
Avatar
Bruno Ducrot
Le 19-03-2012, Kevin Denis a écrit :
Le 19-03-2012, Marc Espie a écrit :
Ben deja, setuid, c'est un appel systeme. Tu ne verifies MEME PAS s'il
fonctionne. Faudrait peut-etre commencer par ca: t'assurer que ton
setuid() renvoie bien 0, et sinon faire un perror().



Ok, je fais un programme plus long, cf plus bas.

Machine et système utilisé:

:/tmp# uname -a
Linux slack 2.6.37.6-smp #2 SMP Sat Apr 9 23:39:07 CDT 2011 i686 QEMU
Virtual CPU version 0.12.5 GenuineIntel GNU/Linux
:/tmp# cat /etc/slackware-version
Slackware 13.37.0
:/tmp#

slackware 13.37, installée dans un KVM, tout par défaut.

Si ca se trouve, tu as un systeme d'ACL en place qui fait que tu ne
peux pas faire ce que tu veux quand tu veux au niveau uid...



:/tmp# cat prog.c
#include <stdio.h>
#include <stdlib.h>
int main(){
int r;
fopen("/tmp/out","w+");
r = seteuid(1002);
printf("valeur retour %dn", r);
system("/bin/sh");
return 0;
}
:/tmp# gcc -o prog prog.c ; chown 1002.1001 prog ; chmod u+s prog
:/tmp# su user1
:/tmp$ ./prog
valeur retour 0
sh-4.1$ ls -l
total 12
-rw-r--r-- 1 user2 user1 0 Mar 19 12:36 out
-rwsr-xr-x 1 user2 user1 5968 Mar 19 12:36 prog
-rw-r--r-- 1 user1 user1 192 Mar 19 12:29 prog.c
sh-4.1$ id
uid01(user1) gid01(user1) groups01(user1)
sh-4.1$

Je vérifie que la valeur retour est bonne, que le programme tourne
bien en 1002 (bit s) mais le shell s'obstine à être en 1001. Je
mattends à observer:
uid01(user1) euid02(user2) gid01(user1) groups01(user1)

(et j'ai testé avec setuid au lieu de seteuid, mais le résultat est
le même)



J'arrive a reproduire ton probleme sur un Ubuntu, a condition de remplacer :

system("/bin/sh");

par :
system("/bin/bash");


S'il y a toujours un /bin/ash sur ta Slack, tu devrais tester avec, pour voir
ce que ca donne.

A plus,

--
Bruno Ducrot

A quoi ca sert que Ducrot hisse des carcasses ?
Avatar
Kevin Denis
Le 19-03-2012, Bruno Ducrot a écrit :
J'arrive a reproduire ton probleme sur un Ubuntu, a condition de remplacer :

system("/bin/sh");

par :
system("/bin/bash");


S'il y a toujours un /bin/ash sur ta Slack, tu devrais tester avec, pour voir
ce que ca donne.



Identique. Par contre, le même programme sur une debian 6.0.4 fonctionne (?!).

:~/tmp$ ./prog
valeur retour 0
uid00(kdenis) gid00(kdenis) euide534(nobody) (snip le reste)
$ id
uid00(kdenis) gid00(kdenis) euide534(nobody) (snip..)
$ cat prog.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
int r;
fopen("/tmp/out","w+");
r = seteuid(65534);
printf("valeur retour %dn", r);
system("/usr/bin/id");
system("/bin/sh");
return 0;
}
$

Chez debian le /bin/sh pointe vers dash, mais si j'utilise /bin/bash
:~/tmp$ cat prog.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
int r;
fopen("/tmp/out","w+");
r = seteuid(65534);
printf("valeur retour %dn", r);
system("/usr/bin/id");
system("/bin/bash");
return 0;
}
:~/tmp$ ./prog
valeur retour 0
uid00(kdenis) gid00(kdenis) euide534(nobody) (snip le reste)
bash-4.1$ id
uid00(kdenis) gid00(kdenis) groupes00(kdenis) (snip)

De nouveau je pers mon euid. Ca semble lié au shell en fait, même si
sous slackware ma commande /bin/id n'affiche jamais mon euid.

Je vais lire les man du shell plutôt.
--
Kevin
Avatar
Bruno Ducrot
Le 19-03-2012, Kevin Denis a écrit :
Le 19-03-2012, Bruno Ducrot a écrit :
J'arrive a reproduire ton probleme sur un Ubuntu, a condition de remplacer :

system("/bin/sh");

par :
system("/bin/bash");


S'il y a toujours un /bin/ash sur ta Slack, tu devrais tester avec, pour voir
ce que ca donne.



Identique. Par contre, le même programme sur une debian 6.0.4 fonctionne (?!).



D'apres la page man de system(), toujours sur une Ubuntu :

Do not use system() from a program with set-user-ID or set-group-ID
privileges, because strange values for some environment variables might
be used to subvert system integrity. Use the exec(3) family of func‐
tions instead, but not execlp(3) or execvp(3). system() will not, in
fact, work properly from programs with set-user-ID or set-group-ID
privileges on systems on which /bin/sh is bash version 2, since bash 2
drops privileges on startup. (Debian uses a modified bash which does
not do this when invoked as sh.)


Du coup, si tu n'as pas le bon patch de bash pour la slack, ca risque de
ne pas bien marcher si j'ai bien compris.

BTW, ca se trouve ici, apres un apt-get source bash :

cat bash-4.1/debian/patches/privmode.dpatch


...

diff -urb bash.orig/shell.c bash/shell.c
--- bash.orig/shell.c 2003-06-03 19:50:35.000000000 +0200
+++ bash/shell.c 2003-09-28 00:26:28.000000000 +0200
@@ -447,7 +447,7 @@
if (dump_translatable_strings)
read_but_dont_execute = 1;

- if (running_setuid && privileged_mode == 0)
+ if (running_setuid && privileged_mode == 0 && act_like_sh == 0)
disable_priv_mode ();

/* Need to get the argument to a -c option processed in the


Je ne sais pas vraiment si tu compiles bash pour la slack, mais si c'est
le cas, tu devrais pouvoir integrer ce patch assez facilement.

A plus,

--
Bruno Ducrot

A quoi ca sert que Ducrot hisse des carcasses ?