[KDT_AISEC] 6주차 - 웹 보안 및 웹 해킹 실습

Gloomy·2024년 1월 25일
0

KDT_AISEC

목록 보기
15/25

OWASP


OWASP(Open Web Application Security Project)

WAS에서 발생할 수 있는 위험들에 대해 연구하는 오픈 소스 프로젝트로서 3~4년 마다 OWASP Top 10이라는 웹 애플리케이션 10대 주요 취약점을 발표한다.

OWASP Top 10 List

PROXY


원격 프록시

클라이언트 외부에 프록시 서버가 존재하는 것을 의미한다. 클라이언트의 IP주소를 숨길 수 있다.

로컬 프록시

클라이언트 PC내에 설치하는 프록시이다. 클라이언트-서버 통신간에 HTTP통신을 분석 및 변조하는 데 사용할 수 있다.
대표적인 도구로는 BurpSuite, Zed Attack Proxy(ZAP)등이 있다.

웹 해킹 실습에 이용할 예정이다.

취약점의 이해


취약점이 발생하는 이유


위 그림에서 버그는 프로그래머의 의도와 달리 설계상의 오류가 발생하는 부분을 의미하고 취약점은 버그 중에서도 정보보안의 3요소(기밀성, 무결성, 가용성)을 위협하는 부분을 의미한다. 모든 프로그래머가 프로그램을 설게할 때 완벽하게 설계할 수 없기 때문에 취약점은 항상 발생할 수밖에 없다.

SQL Injection

SQL Injection은 데이터베이스와 연동된 애플리케이션에서 입력된 데이터에 대한 유효성 검증을 하지 않을 경우, 공격자가 입력 데이터에 SQL Query를 삽입하여 데이터베이스로부터 정보를 열람하거나 조작할 수 있는 보안 취약점이다.

SQL Injection 원리

SQL Injection의 공격 쿼리문들은 보통 논리적 오류를 발생시키는 쿼리문들이다.

SQL Injection 실습

실습 환경은 이전 네트워크 공격 실습에 활용했던 VROOM환경을 그대로 이용한다. OWASP에서 개발한 OWASP Top 10취약점에 대한 웹해킹 실습을 할 수 있는 WebGoat7을 기반으로 진행한다.


위 문제는 모든 지역의 날씨 데이터를 가져오는 문제이다. 따로 입력할 수 있는 텍스트 박스가 없고 Go!버튼을 눌러 데이터를 전송하는 형식인 것 같으니, 우선 BurpSuite를 켜서 데이터가 어떻게 전송되는지 확인해보자. BurpSuite에서 Intercept옵션을 활성화한 뒤 Go!버튼을 눌러보았다.

POST /WebGoat/attack?Screen=101829144&menu=1100 HTTP/1.1
Host: webgoat7.com
Content-Length: 22
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.93 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://webgoat7.com
Referer: http://webgoat7.com/WebGoat/start.mvc
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: JSESSIONID=538A37330CE5AB846B3EFA27B44CE7F9
Connection: close

station=101&SUBMIT=Go!

맨 아래 station=101&SUBMIT=Go!가 데이터를 전송하는 부분임을 알 수 있다. station파라미터에 임의의 값(1234)을 넣어보자.

SELECT * FROM weather_data WHERE station = 1234

문제 하단에 표시되는 SQL구문 힌트가 1234로 업데이트 됨을 볼 수 있다. 그렇다면 삽입할 SQL쿼리도 해당 부분에 삽입됨을 알 수 있다. '' or 1=1쿼리를 삽입해보자.

weather_data의 모든 데이터가 불러와진 것을 확인할 수 있다. String SQL Injection문제도 풀어보자.

이 문제의 목적은 모든 사용자의 카드번호를 불러오는 것이다. 이전 문제와 입력창이 존재하고, 입력값을 전송했을 때 입력값의 양 옆에 따옴표가 붙는 것을 알 수 있다. 이것을 잘 이용해서 쿼리문을 넣어보자. 입력값 양 옆에 안 보이는 따옴표가 있다고 생각하고 ' or '1'='1이라는 쿼리를 넣어보도록 하겠다.

깔끔하게 잘 풀린 것을 볼 수 있다. 조금 더 어려운 문제들로 넘어가보자.

우선 아까와 마찬가지로 입력창이 존재하는데, 아무 값이나 넣은 후 BurpSuite에서 확인해보자.

employee_id=101&password=1234&action=Login

의 형태로 데이터를 전송하게 되는데, employee_id가 사용자의 번호인 것 같고 password에 내가 입력한 데이터가 들어간다. 따라서 password에 무언가 '참'을 만들 수 있는 쿼리를 넣어본다면? 이라는 생각이 든다.

사용자를 Neville로 바꾼 후, 이전 문제와 동일한 쿼리를 BurpSuite를 이용해 날려보았다.

employee_id=101&password=' or '1'='1&action=Login


Neville의 계정으로 접속이 잘 된 모습을 확인할 수 있다.

이 문제는 Larry로 접속해서 보스인 Neville의 정보를 조회하는 것이 목표이다. 우선 방금 전과 같은 방법으로 로그인해보자.

이러한 화면이 보이게 되는데, 우리가 보아야 할 곳은 ViewProfile인 것 같다. BurpSuite로 인터셉트를 잡고 눌러보자.

employee_id=101&action=ViewProfile

의 형식으로 데이터가 날아가는데, 조작할만한 부분은 employee_id=101인 것 같다. 우선 이전의 문제를 푸는 과정에서 Nevilleemployee_id가 112번인 것을 확인할 수 있다. 먼저 그냥 112를 넣어보자.

에러가 발생하는 것을 보니 단순 값 변경으로는 불가한 것 같다. 쿼리를 넣어야 하는데, 이번에는 다른 문제들처럼 쿼리문이 주어져 있지 않아서 쿼리문을 예측을 해야한다.
쿼리문을 예측하려면 우선 테이블 이름부터 알아야 하는데, employee_id라는 파라미터에서 추측해볼 수 있는 테이블명은 employee정도가 될 수 있을 것 같다. 쿼리문의 형태를 예측해보자면 employee_id를 입력 받아서 해당 직원의 프로필을 보여주는 것이므로 select * from employee where employee_id = ?의 형태가 될 것 같다. 보스인 Neville의 id를 가장 하단에서 선택할 수 있는 것으로 유추해보아 아마 데이터가 가장 하단에 위치할 확률이 높다. 따라서 employee_id를 기준으로 내림차순 정렬을 해보자. 삽입할 쿼리문은 101 or 1=1 order by employee_id desc이다.

Neville의 프로필이 잘 보이는 것을 확인할 수 있다. 이 외에도 Blind SQL Injection에 관한 내용도 있지만 다룰 부분이 많아 다음 글에서 다루도록 하겠다.

Command Injection

Command Injection은 말 그대로 명령어를 삽입하는 공격이다. 사용자의 입력 값이 운영체제 명령어로 실행되는 경우 의도치 않은 시스템 명령어가 실행돼 부적절하게 권한이 변경되거나 시스템 동작 및 운영에 악영향을 줄 수 있다. 일반적으로 명령어 라인의 파라미터나 스트림 입력 등 외부 입력을 사용하여 시스템 명령어를 생성하는 프로그램에서 발생한다.

Command Injection 실습


우선 입력창이 없으니 기본적으로 BurpSuite 프록시로 데이터가 전송되는 모양을 살펴보자.

HelpFile=AccessControlMatrix.help&SUBMIT=View

데이터는 위와 같은 모양으로 전송된다. 결과를 살펴보자.

ExecResults for '[/bin/sh, -c, cat "/home/webgoat/.extract/webapps/WebGoat/plugin_extracted/plugin/CommandInjection/resources/AccessControlMatrix.html"]'
Output...

결과를 보면 AccessControlMatrix.help라는 데이터가 전송되면 AccessControlMatrix.htmlcat명령어로 보여주는 식의 동작 방식인 것 같다.
리눅스에서는 세미 콜론(;)을 사용하면 이전 명령어의 실행 여부와 관계없이 뒤에 위치한 명령어를 실행할 수 있다. 이 정보를 이용해서 알맞은 명령어 구문을 날려보자. 우선 ;ls 구문을 날려보자.

ExecResults for '[/bin/sh, -c, cat "/home/webgoat/.extract/webapps/WebGoat/plugin_extracted/plugin/CommandInjection/resources/AccessControlMatrix.html;ls"]'
Returncode: 1
Bad return code (expected 0)

모양을 살펴보니 ;ls뒤에 큰 따옴표가 하나 붙어있다. 그렇다면 큰 따옴표를 신경써서 ";"ls라는 명령어를 날려보자.

Command Injection이 성공적으로 진행되었다.

Log Spoofing 실습

Log Spoofing은 말 그대로 로그를 변조하는 공격이다.

admin이 로그인 했던 것처럼 로그를 변조하는것이 목표인 문제이다. 우선 그냥 admin으로 로그인해보자.

로그인이 실패했다는 로그가 남았다. 그렇다면 입력창 내부에서 개행을 한 후 똑같은 문자열을 입력해주면 되지 않을까? 입력창 내부 개행은 %0d%0a로 진행해준다.
admin%0d%0aLogin successed for username: admin를 입력해보자

성공적으로 admin이 로그인 했다는 허위 로그를 남길 수 있었다.

쿠키(Cookie)

쿠키는 사용자의 웹 브라우저에 저장되는 작은 기록 정보 파일이다. 중요한 점은 웹 브라우저에 저장된다는 점이다. 저장된 정보를 다른 사람이 확인 가능하며, 유효시간이 지나면 사라진다. 쿠키를 사용하는 목적은 우선 세션 관리의 관점이 있고, 브라우저 개인 맞춤화, 트래킹 등의 목적이 있다.


사용자는 webgoat/webgoat, aspect/aspect로 로그인할 수 있고, alice의 쿠키를 알아내어 계정을 전환하는것이 목표이다.

우선 각 계정의 쿠키값을 알아보자.

webgoat의 쿠키값은 65432ubphcfx이다.

aspect의 쿠키값은 65432udfqtb이다.

이 둘 사이에서의 규칙을 찾은 후 alice의 쿠키값을 유추하는 문제로 보인다.
webgoat:65432ubphcfx
aspect:65432udfqtb
alice:?

webgoataspect의 공통점은 둘 다 t로 끝난다는 것이고, 각각의 쿠키값의 공통점은 65432로 시작하고u로 시작한다는 점이다. 이러한 규칙으로 유추할 수 있는 부분은 각각의 문자를 알파벳 순서상 다음 문자로 변환한 후 반전시켰다는 것이다. 이러한 규칙으로 미루어보아 alice의 쿠키는 65432fdjmb로 유추할 수 있다. 개발자 도구를 이용해 쿠키값을 변경한 후 새로고침해보자.

로그인에 성공했다.

세션(Session)

HTTP Session ID를 식별자로 구별하여 데이터를 사용자의 브라우저에 쿠키형태로 저장하는 것이 아닌 접속한 서버 DB에 저장한다. 세션 ID만 웹 브라우저에 저장되고 다른 정보들은 서버에 저장된다.

하지만 쿠키가 탈취되는 것 처럼 세션 ID도 탈취당하면 공격자가 해당 세션으로 접속할 수 있다. 하지만 사용자가 해당 웹 서버에서 로그아웃하게되면 세션 ID를 탈취한 공격자의 브라우저에서도 로그아웃된다.

크로스 사이트 스크립팅(Cross Site Scripting, XSS)

웹 페이지에 악의적인 스크립트를 삽입하여 피해자의 브라우저에서 실행되게 유도하는 공격 기법이다.

  • Reflect XSS
    공격자가 피해자의 이메일로 피싱 URL을 전달하고 피해자가 해당 링크를 클릭하게 되면 악성 스크립트가 담긴 응답 메시지를 서버로부터 받게된다. 공격자의 서버에서 피해자의 PC로 공격 스크립트가 전달되는 방식이고, 서버에 로그가 남지 않는 것이 특징이다.

  • Stored XSS
    공격자가 서버에 스크립트가 담긴 게시글 등을 등록한 후 피해자가 해당 게시글을 열람하게 되면 악성 스크립트가 실행되는 방식이다. 무작위 공격에는 편하지만 서버에 로그가 남는 것이 특징이다.

XSS 실습

  • Stored XSS

    입력창에 스크립트를 삽입하여 alert을 뛰워보자.

  • Reflect XSS

    비슷한 방식으로 모든 입력창에 스크립트를 삽입한다.

    UpdateCart버튼을 누르면 스크립트가 실행된다.

크로스사이트 요청 위조(Cross Site Request Forgery,CSRF)

불특정 다수를 대상으로 로그인 된 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록, 송금 등)를 하게 만드는 공격이다.

  • CSRF 토큰
    CSRF 토큰이란 서버에 들어온 요청이 실제 서버에서 허용한 요청이 맞는지 확인하기 위한 토큰이다. 서버에서는 클라이언트가 어떤 요청을 하면 해당 요청에 대한 응답 안에 숨겨진 태그로 CSRF 토큰을 같이 넘겨준다. 클라이언트가 특정 작업 수행 후 다시 해당 작업에 대한 요청과 CSRF 토큰을 보내면 서버에서는 해당 토큰을 검증한 이후 삭제한다. 이처럼 클라이언트가 어떤 작업을 수행하기 위해 서버에 요청했을 때, 서버에서 보낸 요청에 대한 알맞은 클라이언트의 응답인지 검증하기 위한 토큰이라고 할 수 있다.

    출처: https://codevang.tistory.com/282
profile
𝙋𝙤𝙨𝙨𝙤 𝙁𝙖𝙧𝙚!

0개의 댓글