Back to writing
미분류 1 min read HYEONG HWAN, MUN

[PHP] 웹상에서 setuid 를 이용하여 시스템명령 사용하기

 

테스트 환경(Demonstration Environment) : Ubuntu Server 14.04 LTS

 

반복적인 단순한 쉘 작업을 함수로 만들어서 웹에서 관리하고 싶어졌다.

작업은 사용자의 추가, 삭제, 비밀번호 변경이다.

 

여러 시행 착오 끝에 잘 되는 경우를 발견하였고 이곳에 공유해 본다.

 

원하는 명령어는 root의 권한으로 실행되어야 하는데, Apache에 root permission 을 줄 수도 없는 노릇이고..

방법을 찾아보다가 setuid 를 발견하였다.

 

이것은 리눅스의 특정 플래그 인데, 이 파일을 실행할 때 소유자의 권한으로 실행하라는 bit flag 이다.

 

먼저

test.php 작성

[code title="test.php" language="php"]
system("whoami");
[/code]

 

결과화면은 www-data 이었다.

pv103

 

이번엔 쉘실행파일로 작성해 보았다.

test.sh

[code title="test.sh" language="bash"]
#!/bin/bash
whoami
[/code]

 

이것 실행 역시 www-data 이었다.

 

setUID를 주고서 해보았다.

소유자변경과 setuid 비트 2가지를 주어야한다.

결과 변화가 없음.

 

test2.php 생성

[code title="test2.php" language="php"]
system("./test.sh");
system("./test.php");
[/code]

 

즉 test2.php 에서 호출하도록 해서 작성해보았는데 역시 결과는 변화가 없었다.

이론상으로는 owner 로 등록된 유저명이 나와야 하는데..

 

마지막으로 gcc를 이용해 보았다.

 

test.c 생성

[code title="test.c" language="c"]
void main(){
system("whoami");
}
[/code]

 

#gcc test.c -o test.o
#chmod 4755 test.o
#chown root test.o

 

라고 하고 test3.php 를 다음과 같이 짰더니

[code title="test3.php" language="php"]
system("./test.o");
[/code]

root 권한이 되었다.

pv104

 

쉘스크립트나 PHP스크립트는 setuid 비트가 동작하지 않고 C 언어로 바이너리 컴파일을 해야 동작하더라.
실제 적용은 argv[] 를 받는 c 소스를 짠 후에 php 에서 파라미터로 넘겨서 실행하도록 짰다.

Filed under