2009-06-26 5 views
11

누군가를 위해 더러운 리눅스 해킹을해야만했기 때문에 루트가 아닌 사용자 인 동안 cupsenable printername 쉘 명령으로 프린터를 시작할 수있었습니다. 나는 그들이 cupsenable 문법의 전체를 루트로서 사용할 수 있기를 원하지 않았기 때문에, 나는 방금 argv[1]에 입력을 위생 처리하고 system("cupsenable sanitizedprintername")을 호출하는 C 래퍼를 썼다.system()으로 관리 프로그램을 호출하는 setuid-root C 프로그램에서 setuid (0)가 필요한 이유는 무엇입니까?

나는 setuid 루트 프로그램을 만들었지 만, 심지어 cupsenable은 "permission denied"로 실패했습니다. 그런 다음 system() 전에 setuid(0) 전화를 걸었습니다.

사용자가 프린터를 제어 할 수있는 더 나은 방법이 있다는 문제는 무시하십시오. 아마 더 좋은 방법이있을 것입니다. 내가 흥미를 느낀 이유는 chmod u+ssetuid(0)system()의 복잡한 점입니다. 왜 그렇게 행동 했나요? man system에서

답변

17

: 몇몇 환경 변수들을위한 이상한 값들이 시스템 무결성을 파괴하는 데 사용될 수 있기 때문에

는, 설정 - 사용자 ID 또는 설정 그룹 ID 권한으로 프로그램에서 system()을 사용하지 마십시오. 대신 exec(3) 패밀리를 사용하고 execlp(3) 또는 execvp(3)은 사용할 수 없습니다. system()은 실제로는 /bin/sh이 bash 버전 2 인 시스템에서 set-user-ID 또는 set-group-ID 권한이있는 프로그램에서 제대로 작동하지 않습니다. bash 2는 시작시 권한을 삭제하기 때문입니다.

그리고 man bash에서

: 쉘이 실제 사용자 (그룹) ID 및 -p 옵션과 동일하지 유효 사용자 (그룹) ID로 시작되는 경우

, 아니 시작을 공급하지됩니다 파일이 읽혀지고 셸 함수가 환경에서 상속되지 않으면 변수가 환경에 나타나면 변수 SHELLOPTS이 무시되고 유효 사용자 ID는 실제 사용자 ID로 설정됩니다.

귀하의 setuid(0) 전화가 해당 보호를 우회 한 것처럼 보입니다.

+2

우와. 글쎄, 내가 더러 웠다고 했어. 내가 한 일은 system()에 의해 산란 된 bash 프로세스를 설득하여 실제로, 정말로, 솔직히 뿌리를 내리고, 하나님 께 맹세 한 것 같습니다. 일부 리팩토링이 순서대로있는 것 같습니다. – JCCyC