회사의 워드프레스 웹사이트 중 일부는 다운로드한 플러그인에 악성코드가 포함되어 있었고, 이로 인해 서버 전체의 모든 웹사이트의 PHP 파일에 악성코드가 존재하게 되었기 때문에 이를 제거하기 위한 간단한 스크립트를 작성했습니다.
- !#]y3d]51]y35]256]y76]72 ]y3d]51]y35]274]y4:]82]y3:]621:|:*mmvo:>:iuhofm%x5c%x7825:-5ppde:4:|:**#ppde#)tutjyfx25yy>#] D6]281L1#%x5c%x782f#M5]DgP5]D6#3j%x5c%x7825!*72!%x5c%x7827!hmg%x-t.98]K4]65]D8]86]y31]278]y3f]5c%x7860sfqmbdf)% x5c%x7825%x5c%x7824-%x5c%x7%x5c%x7822)gj!|!*nbsbq%x5c%x7825)323ldfidk!~!
复代码
- /**
- * 파일명 : delUnwantedCode.php
- * 기능 : FTP에서 악성코드 삭제
- * 사용방법 :
- * 악성코드를 제거할 디렉토리에 해당 파일을 업로드 하신 후, 그런 다음 CLI나 브라우저를 사용하여 접속하기만 하면 감염된 원본 파일이 자동으로 백업됩니다
- */
- $path = dirname(__FILE__); 처리됨
- $bak_path = $path.DIRECTORY_SEPARATOR.basename(__FILE__,'.php') # 소스 파일 백업 디렉터리를 정의합니다. 프로그램이 악성 코드를 필터링하기 전에 먼저 원본 경로에 따라 이 디렉터리에 문서를 백업합니다.
- $fileType = array('php'); #처리할 파일 형식(접미사 이름)을 소문자로 정의합니다.
- $search = array('@@si') #필터링이 필요한 악성 코드 규칙 정의
- $search_count = array(
- 'all_file'=>array(), #모든 파일
- 'search_file0'=>array(), #악성코드가 포함된 파일 없음
- 'search_file1'=>array() #악성코드가 포함된 파일
- ) ;
-
-
- $filelist = listDir($path,$fileType,false) #디렉토리에 있는 정규화된 파일 목록 읽기
- if(!empty ($filelist)){
- foreach ($filelist를 $file로){
- $file = (isset($file['name'])?$file['name']:$file);
- $search_count['all_file'][] = $file;
- $fileContent = file_get_contents($file);
- $compile_fileContent = preg_replace($search, '', $fileContent);
- if(strlen ($fileContent) != strlen($compile_fileContent ) && str_replace($bak_path, '', $file)==$file){
- #필터링 후 파일 길이가 일치하지 않으면 악성 코드가 포함되어 있다는 의미입니다( 백업 파일이 있는 디렉터리는 필터링되지 않습니다)
- $search_count['search_file1 '][] = $file;
-
- ############원본 백업 시작 file#############
- $ bakFile = str_replace($path, $bak_path, $file);
- @make_dir(dirname($bakFile));
- @ file_put_contents($bakFile, $fileContent);
- ####### #####원본파일 백업 종료#############
-
- #필터링된 내용을 원본 PHP 파일에 다시 작성
- @file_put_contents ($file, $compile_fileContent);
- }else{
- $search_count['search_file0'][] = $file;
- }
- }
- }
-
- #print_r ($search_count);die;
- echo sprintf('총 %s개의 적합한 파일이 %s에서 검색되었으며, 그 중 %s에 악성 코드가 포함되어 있습니다. 처리가 종료되었습니다',$path,count($search_count[ 'all_file']), count($search_count['search_file1']));die;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ######## ###############
- ## 보조 기능
- ######### ##############
-
- /**
- * 대상 폴더가 있는지 확인하고 없으면 자동으로 디렉터리를 생성합니다.
- *
- * @access public
- * @param string 폴더 디렉터리 경로입니다. 웹사이트 루트에 상대적인 URL은 사용할 수 없습니다.
- *
- * @return bool
- */
- function make_dir($folder){
- $reval = false;
- if (!file_exists($folder)){
- #if 디렉토리가 없으면 생성해 보세요
- @umask(0);
-
- #디렉토리 경로를 배열로 분할
- preg_match_all('/([^/]*)/?/i' , $folder, $atmp);
-
- #첫 번째 문자가 /이면 물리적 경로로 처리됩니다
- $base = ($atmp[0][0] == '/') ? '/' : '';
-
- #경로 정보가 포함된 배열 탐색
- foreach ($atmp[1] AS $val){
- if ('' != $val){
- $base .= $val;
- if ('..' == $val || '.' == $val ){
- #디렉토리가 . 또는 ..이면 다음 루프에 직접 추가/계속합니다.
- $base .= '/';
- continue;
- }
- }else{
- continue;
- }
-
- $base .= '/';
-
- if (!file_exists($base)){
- #디렉토리를 생성해 보세요, if 생성이 실패하면 루프를 계속합니다
- if (@mkdir(rtrim($base, '/'), 0777) ){
- @chmod($base, 0777);
- $reval = true;
- }
- }
- }
- }else{
- #경로가 이미 존재합니다.경로가 디렉터리인지 여부 반환
- $reval = is_dir($folder);
- }
-
- clearstatcache();
-
- return $reval;
- }
-
-
- ########하위 디렉터리의 시작 부분을 포함하여 디렉터리의 모든 파일 가져오기###############
- 함수 listDir($path ,$ fileType=array(),$fileInfo=true){
- $path = str_replace(array('/','\'), DIRECTORY_SEPARATOR, $path);
- if(!file_exists($path) || !is_dir($path)){
- return '';
- }
- if(substr($path, -1,1)==DIRECTORY_SEPARATOR){
- $path = substr($ 경로, 0,-1);
- }
- $dirList=array();
- $dir=opendir($path);
- while($file=readdir($dir)){
- #$fileType이 정의되어 있고 파일 형식이 $fileType 범위에 속하지 않거나 파일이 디렉터리인 경우
- if($file!=='.'&&$file!=='..를 건너뜁니다. '){
- $file = $path.DIRECTORY_SEPARATOR.$file;
- if(is_dir($file)){
- if(empty($fileType)){
- $dirList[] = ( $fileInfo== true?array('name'=>$file,'isDir'=>intval(is_dir($file))):$file);
- }
- $dirList = array_merge($ dirList,listDir( $file,$fileType));
- }elseif(!empty($fileType) && (in_array(pathinfo($file, PATHINFO_EXTENSION), $fileType))){
- $dirList[] = ($fileInfo= =true?array('name'=>$file,'isDir'=>intval(is_dir($file)),'md5_file'=>md5_file($file),'filesize'=> ;filesize($ file),'filemtime'=>filemtime($file)):$file);
- }
- };
- };
- closeir($dir);
- return $dirList;
- }
- ########하위 디렉터리의 끝을 포함하여 디렉터리의 모든 파일 가져오기##############
-
코드 복사
- /**
- * 파일명 : delAllUnwantedCode.php
- * 기능 : FTP 내 악성코드 삭제 (무제한 파일 처리 지원)
- * 사용방법 :
- * 악성코드가 있는 디렉토리에 파일을 업로드해주세요. 코드는 디렉터리를 제거한 다음 CLI 또는 브라우저를 통해 액세스해야 합니다. 감염된 원본 파일은 자동으로 백업됩니다
- */
- set_time_limit(0);ignore_user_abort(true);
- $path = dirname (__FILE__); # 처리해야 할 디렉터리를 정의합니다.
- $bak_path = $path.DIRECTORY_SEPARATOR.basename(__FILE__,'.php') # 프로그램이 악성 코드를 필터링하기 전에 먼저 소스 파일 백업 디렉터리를 정의합니다. 원래 경로를 누르십시오. 이 디렉토리에 문서를 백업하십시오.
- $fileType = array('php') #처리할 파일 유형(접미사 이름)을 소문자로 정의하십시오.
- $search = array('@ phps*if(!isset ($GLOBALS["\x61\156\x75\156\x61"])).*$bssaiikhvn=$jtgibaqypx-1;s*?>@si') #악성코드 규칙 정의 필터링이 필요한 파일
- $file_count = array(
- 'all_file'=>0, #모든 파일
- 'filter_file'=>0 #악성코드가 포함된 파일
- );
-
- replaceUnwantedCode($path) ; #필터링 실행
-
- #print_r($search_count);die;
- echo sprintf('총 %s개의 적격한 파일이 %s에서 검색되었습니다. 그 중 % 악성 코드가 포함되어 있어 치료되었으며 원본 파일은 %s',$path, ($file_count['all_file']), ($file_count['filter_file']), $bak_path);die;
-
-
- 함수 replacementUnwantedCode($path){
- global $bak_path,$fileType,$search,$file_count;
- $path = str_replace(array('/','\' ), DIRECTORY_SEPARATOR, $path);
- if(!file_exists($path)||!is_dir($path)){
- return '';
- }
- if(substr($path, -1,1)==DIRECTORY_SEPARATOR){
- $path = substr($path, 0,-1);
- }
- $dir=opendir($path);
- while($file =readdir($dir)){
- #$fileType이 정의되어 있고 파일 형식이 $fileType 범위 내에 있지 않거나 파일이 디렉터리인 경우
- 건너뜁니다. if($file!=='.' &&$file!=='..'){
- $file = $path.DIRECTORY_SEPARATOR.$file;
- if(is_dir($file)){
- replacementUnwantedCode($file);
- }elseif(!empty($fileType) && (in_array (pathinfo($file, PATHINFO_EXTENSION), $fileType))){
- ################### ###########
- @$file_count['all_file'] ;
- $fileContent = file_get_contents($file) #파일 원본 코드
- $compile_fileContent = preg_replace($search, '', $fileContent); #필터링된 콘텐츠
- if(strlen($fileContent) != strlen($compile_fileContent) && str_replace($bak_path, '', $file)==$file){
- #If 필터링된 파일의 길이가 일치하지 않습니다. 이는 악성 콘텐츠가 포함되어 있음을 의미합니다. 코드(백업 파일이 있는 디렉터리는 필터링되지 않음)
- $file_count['filter_file'] ;
-
- #### ########원본 파일 백업 시작####### ########
- $bakFile = str_replace($path, $bak_path, $file);
- @make_dir(dirname($bakFile));
- @file_put_contents($bakFile, $fileContent );
- ############원본파일 백업 끝##### #########
-
- #필터링된 콘텐츠를 원본 PHP 파일에 다시 작성
- @file_put_contents($file, $compile_fileContent);
- }
- ##### ################# #########
- unset($fileContent,$compile_fileContent);
- }
- };
- };
- closeir($dir);
- true 반환
- }
-
-
-
-
- ######### #############
- # # 보조 기능
- #####################
-
- /**
- * 대상 폴더가 있는지 확인하고 없으면 자동으로 디렉터리를 생성합니다.
- *
- * @access public
- * @param string 폴더 디렉터리 경로입니다. 웹사이트 루트에 상대적인 URL은 사용할 수 없습니다.
- *
- * @return bool
- */
- function make_dir( $folder){
- $reval = false;
- if (!file_exists($folder)){
- #디렉토리가 그렇지 않은 경우 존재한다면 생성해 보세요
- @umask(0);
-
- #디렉토리 경로를 배열로 분할
- preg_match_all('/([^/]*)/?/i', $ 폴더, $atmp);
-
- #첫 번째 문자가 /이면 물리적 경로로 처리됩니다.
- $base = ($atmp[0][0] == '/' ) ? '/' : '';
-
- # 경로 정보가 포함된 배열 탐색
- foreach ($atmp[1] AS $val){
- if ('' != $val){
- $base .= $val;
- if ('..' == $ val || '.' == $val){
- #디렉토리가 ..이면 직접 추가/ 다음 주기 계속
- $base .= '/';
- continue;
- }
- }else{
- continue;
- }
-
- $base .= ' /';
-
- if (!file_exists($base)){
- # 디렉토리 생성을 시도하고 생성이 실패하면 계속 반복합니다
- if (@mkdir(rtrim($base, '/ '), 0777)){
- @chmod($base, 0777);
- $reval = true;
- }
- }
- }
- }else{
- #The 경로가 이미 존재합니다. 경로가 디렉터리인지 여부 반환
- $reval = is_dir($folder);
- }
-
- clearstatcache();
-
- return $reval;
- }
-
-
-
코드 복사
|
악성코드, 워드프레스, PHP