Vmware - Edit - Virtual Network Editor 로 들어가 DHCP 체크 설정 후 가상 OS 재부팅한다.
실습) 각 가상머신 로그인 계정
win-xp ⇒ administrator / p@ssw0rd
kali-linux ⇒ kali / kali
bee-box ⇒ bee / bug
WebGoat ⇒ webgoat / webgoat
openeg => test /test
웹 고트 (Web Goat)는 자바 기반 OWASP 다양한 웹 취약점 프레임워크
2.파일 다운로드 후 VMware Workstation machine 에서 bee-box 설치한다.
비박스는 bWAPP가 설치된 가상환경으로 OWASP Top 10을 기준으로 한 웹 취약점 프레임워크
bee-box 실행 완료.
eclipseIDE 설치가 진행된다.
Eclipse IDE의 worksapce 가 실행되었다. Tomcat 서버를 확인하면, WebGoat가 설치된 것을 확인 가능하다. 우측 실행 버튼을 눌러 실행시켜보자.
인터넷 브라우저에서 아래 주소로 openeg 웹 페이지에 접속해보자.
로그인이 확인
WebGoat도 실행되었었다. 해당 페이지도 접속해 보자
WebGoat 페이지가 나왔다. Start WebGoat를 눌러 시작해보자
페이지 접속 오류 발생 시, 아래 그림과 같이 Eclipse IDE workspace에서 서버 중지 후 clean, 재실행 및 재 접속.
WIN XP 설치
각 가상머신의 주소를 hosts 파일에 등록
HOST PC IPv4 : 192.168.0.9
WIN XP IPv4 : 192.168.10.131
Kali Linux IPv4 : 192.168.10.128
bee-box IPv4 :" 192.168.10.129
bee-box 에는 degit 설치되어 있다. 아래 명령어 바로 실행 가능
sudo gedit /etc/hosts
칼리 리눅스는 아래 명령어로 degit 설치 후 가상머신 주소 등록한다
sudo apt update
sudo apt install gedit -y
http://victim:8080/openeg ⇒ test / test
http://victim:8080/WebGoat/attack ⇒ webgoat / webgoat
http://beebox/bWAPP ⇒ bee / bug
WIN XP 에서 http://victim:8080/openeg 로 접속해보자
a / a 로 로그인을 시도하면, 아래와 같이 개발자 도구에서 소스 보기에서 확인 가능하다.
요청 파라미터로 전달된 값이 서버 내부에서 어떻게 사용되는지를 유추해보자.
⇒ 아마도 쿼리(SQL) 생성 시 사용될 것이다.
select * from users where id = 'a' and pw = 'b'
예상 쿼리의 구조, 테이블 또는 컬럼 이름은 확실하지 않음.
⇒ 쿼리 실행 결과가 있으면 로그인 성공 처리 OR 쿼리 실행 결과가 없으면 로그인 실패 처리
=> 따라서 임의의 SQL Injection 문장을 삽입해보자.
에러 페이지가 나왔다. 에러 메시지를 살펴보자.
회원가입 창에서 자주 사용하는 관리자 계정인 admin 으로 회원가입을 시도해 보자.
admin 계정 사용 확인, admin 아이디를 사용.
아래와 같이 SQL Injection 공격 시도
로그인이 성공했다.
결과 : 관리자로 로그인 하여 관리자 권한 획득.
시스템의 데이터 처리 과정에는 입력, 처리, 출력 존재.
안전한 시스템 데이터 처리 고려사항
예를 들어, 아래와 같은 서버측 소스코드에서
<input type="text" name="id" maxlength="8" />
특정 값을 입력 => 특정 값이 전송 => 특정 값이 사용된다.
이때, maxlength값이 8 이내의 다른 값으로 변조해 전달 가능하다면 이는 Exploit Hidden Fields (숨겨진 필드 활용 공격) 취약점이 존재한다.
WIN XP에서 WebGoat에 접속 후, start webgoat를 누른다.
Parameter Tampering 에서 Exploit Hidden Field로 들어간다.
아래 그림에서 제시된 문제의 조건을 확인해 보자.
2999.99불 판매가의 TV를 이보다 더 싸게 구매하는 방법을 질문하고 있다.
쿠폰을 사용하거나, 초당 10발 이상 사용하는 마법 지팡이를 사용해도 되지만 여기서는 숨겨진 필드를 탐색 및 사용하는 방법으로 접근해 보자.
웹 페이지에서 100대를 구매한다고 설정 후, 구매 버튼을 누르면 서버로 Request 전송이 될 것이다. 이를 Brup Suite Intercept 기능에서 확인해 보자.
Request를 살펴보면, 방금 내가 설정한 수량인 QTY가 100, Price가 2999.99로 나와있다. 즉, TV 주문 수량과 1대당 가격이 그대로 전송되는 것을 확인 가능하다.
여기서 Price 값을 수정해서 1불에 구매해보도록 하자.
전 : QTY가 100, Price가 2999.99
후 : QTY가 100, Price가 1
그리고 Forward로 해당 Request를 웹 서버로 전송해 보자.
결과 Response 확인
조작된 값으로 Request 전송 시, 이상이 없다.
결과값이 이상없이 왔다. Intercept를 off 시키고, 나머지 웹 서버로부터 응답을 받자. 그리고 웹 브라우저를 확인해 보자.
100대의 TV 가격인 2999999.0 불이 1불이 되는 기적을 확인할 수 있다.
결론
사용자 데이터가 웹 서버로 전송 되는 과정에서 해당 데이터의 변조를 검증하지 않아 웹 서버에서 잘못된 처리 발생.
따라서 데이터 변조 방지 목적으로 인증 토큰을 발생시켜, 데이터가 변조되면 해당 토큰을 확인해 데이터의 무결성을 확인해야 한다.
String SQL Injection 실습 페이지에서는 다양한 사용자와 직급이 존재한다. 이를 선택하고, 비밀번호를 입력해 로그인 하는 기능 확인.
로그인 과정을 Burp Suite의 Intercept 기능을 통해 확인해보자.
로그인 정보를 평문으로 전송 확인
해당 로그인 정보를 입력하는 곳은 password 뿐이다.
만약 쿼리를 사용하는 로직아 아래와 같은 쿼리문이라고 예측.
SELECT * FROM member WHERE id = '$employee' AND password = '$password';
만약 password 입력 폼에 ' or 'x'='x 라고 입력한다면 sql 쿼리문은 아래와 같을 것이다.
SELECT * FROM member WHERE id = '$employee' AND password = '' or 'x'='x';
따라서, 패스워드 부분은 참이 되어 로그인이 될 것이다. password 부분을 아래 그림과 같이 변조해 전송해 보자.
forward로 Request를 전송 후 Intercept on 으로 변경 후 확인
admin 계정으로 로그인이 되었다.
결론 : SQL Injection 취약점이 존재하는 로그인 기능이 존재한 웹 서버임을 확인 가능하다.
문제 해결 방법 제시
근본적인 방법 : 패스워드 입력 값을 필터링한다.
차선의 방법 : 서버 요청 파라미터 개수 확인(패스워드 입력 길이 제한)
SQL Injection 실습 에서 입력한 ' or 'x'='x 은 서버에서 SQL 쿼리를 구성하게 된다.
SQL Injection 취약점을 보호하기 위해서 사용자 입력값에 대한 검증이 필요하다.
검증 : 특정한 목적에 부합하는지 확인하는 절차
검증 방법 중, Escape(이하 이스케이프)존재.
Escape란? 메타문자를 문자로 사용하게 해주는 기능
메타문자란? 의미문자, 특수문자를 의미한다. 아래 예시가 존재한다.
http://www.example.com/path/file?company_name=Bandi & Luice
name에서 Bandi 와 Luice 동시에 전달하고자 한다.
웹서버는
& 메타문자를 '그리고 뒤에 나온것도 포함'
이라는 AND 의미로 해석하지 않는다. 문자 자체로 인식한다. 즉, Bandi만 name의 인자로 사용한다.
웹 서버 입장
Bandi 뒤 &를 문자로 인식하고, 한 번에 2개의 name을 받은 게 아닌, 한 번 Bandi 인식하고 끝난다
즉, &? 이건 뭐야. 에러! 또는 Bandi 까지만 인식
http://www.example.com/path/file?company_name=Bandi %26 Luice
만약 메타문자를 인식시켜주기 위해 &를 인코딩한 %26을 사용한다면, 웹 서버 입장에서
= >Bandi 인식, 그리고(&) Luice 인식!
결과 발생한다.
이스케이프 처리를 해준다면, 메타문자가 일반문자로 변경된다.
아래 예시를 확인해 보자.
name 컬럼으로 hong's junior 2 값 조회 시,
select * from users where name = 'hong's junior 2'
name 이 hong's junior 2 라는 입력값을 가지게 하고 싶다면, MySQL에서 지정한 규칙으로 아래처럼 사용해야 한다.
select * from users where name = 'hong''s junior 2'
MySQL에서
홑따옴표 ' 메타문자를
나타내기 위해
'' 로
사용해야 하기 때문이다. 그러나 이는 해당 쿼리문을 분리시키는 결과를 가져온다.
따라서 이스케이프 기능을 사용해 데이터를 아래와 같이 지정한다.
select * from users where name = 'hong\'s junior 2'
해당 SQL 문장에서는 name이 hong's junior 2 로 인식된다.
\' => ' // 문자열로써의 홑따옴표, 구분자 역할을 가지지 않는다.