execve() vs system()
글쓴이: declspec / 작성시간: 목, 2012/03/29 - 3:12오전
리눅스에서
execve 와 system 함수의 차이는 먼저
system 함수의 경우 작업이 끝날때까지 호출한 프로세스가 대기하다가 계속 수행하고
execve 는 호출 프로세스가 바뀌어버린다는 점이 있습니다.
그런데 setuid 가 걸린 프로그램에 대해서도 차이가 있는거같은데 누가 설명좀 해주세요.
먼저 a 라는 프로그램이 root setuid 가 걸려있다고 칩시다.
이때 a라는 프로그램에서 system("id") 를 호출한 결과랑
system 대신 execve 를 호출해서 id 를 수행한 결과는 같습니다.
그런데 같은 상황에서 system("/bin/cat /bin/shadow") 를 하는것과
이것을 execve 로 하는건 다른결과가 나타납니다. 왜이런가요?
system 으로 했을때는 shadow 가 보이는데 execve 로하면 퍼미션 에러납니다
왜그런지 설명좀 부탁드려요~
Forums:
음 ..
system 은 결국 fork & exec 조합인데, 바로 프로그램 이미지를 로드하는게 아니라 쉘(/bin/sh -c) 을 통해 실행시킵니다.
(이게 setuid/setgid 걸린 프로그램을 실행하지 말 것을 권고하는 이유이기도 합니다.)
cat 으로 /etc/shadow 를 열었다면, cat 이나 그 실행 파일에 root 소유로 setuid 를 걸었다는 것 같은데..
그렇다면 어쨌든 결과적으로 둘 다 실행 결과는 동일해야 할 것 같은데.. 좀 이상하네요. 음..
일단 execve 는 명시적으로 nosuid 로 mount 된 파일 시스템에서는 EPERM 을 리턴한다고 언급되어 있긴 합니다.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
음...
sh 도 fork 한다음 cat의 이미지를 읽어오는데... execve 도 fork 하신다음 콜하셨을 테고...
이상하네요..
execve 에서 환경변수도 같이 넘겨주신거죠? 아마 환경변수에 user가 누구인지 나타내는 변수도 있었던 걸로 생각됩니다.
그렇지 않다면... 답변은 다음분에게 패스 ㅋ
언제나 시작
저는 잘 됩니다.
전 system 이나 execve나 둘다 permission denied 없이 잘 되는군요.
$ echo ' int main(int argc, char** argv) { system("/bin/cat /etc/shadow"); const char* args[] = {"/bin/cat", "/etc/shadow", 0}; const char* env[] = {0}; execve("/bin/cat", args, env); return 0; }' >> main.c $ gcc main.c && sudo chown root a.out && sudo chmod u+s a.out $ ./a.out
혹시 코드를 볼 수 있을까요?
아래문제입니다
setuid 관련 문서들을 보다가 어느 대학의 시험지 내용같은걸 찾았는데요
아래문제의 b 항목이 제가 질문한 것입니다.
아래의 소스코드 그대로 테스트해보니
system 을 이용했을때는 shadow 가 보이는데
execve 를 이용할때는 안보이더군요
OS 마다 다른걸까요?;
제가 테스트해본 OS 는 데비안 리눅스입니다 커널버전이 정확히 몇인지는 기억이...
5. (15 points) The difference between system() and execve().
(a) Write a program that simply calls system("/bin/cat /etc/shadow"), and make it a
set-root-uid program. Run it using a regular user account in both Minix and Linux. Describe
and explain your observation. For example, if you get a “permission denied” message, you need
to explain why it is denied.
(b) Still use the same program, but replace system() with execve() (see the following code).
Run the program using a regular user account in both Minix and Linux. Describe and explain
your observation. If the observation is different from that of the previous program, you need to
explain what causes such a difference, and which call is more secure.
int main()
{
char *argv[3];
argv[0] = "/bin/cat";
argv[1] = "/etc/shadow";
argv[2] = 0;
/* system("/bin/cat /etc/shadow"); */
execve("/bin/cat", argv, 0);
return 0;
}
자기실력이 좋다고 느껴지는건 공부를 안하고 있다는 신호.
이 코드도 여전히 잘되네요.
정상적으로 shadow 파일이 출력됩니다.
오히려 system으로 했을 때 출력이 안될 가능성은 있는데... 버전 2 bash 를 사용하는 경우엔 set-root-uid 가 무시되기 때문입니다.
혹시 selinux 를 사용하시는 건 아니죠?
댓글 달기