OWASP(The Open Web Application Security Project)는 오픈소스 웹 애플리케이션 보안 프로젝트이다. 주로 웹에 관한 정보노출, 악성 파일 및 스크립트, 보안 취약점 등을 연구하며, 10대 웹 애플리케이션의 취약점 (OWASP TOP 10)을 발표했다.

OWASP TOP 10은 웹 애플리케이션 취약점 중에서 빈도가 많이 발생하고, 보안상 영향을 크게 줄 수 있는 것들 10가지를 선정하여 2004년, 2007년, 2010년, 2013년, 2017년을 기준으로 발표되었고, 문서가 공개되었다.

(위키피디아 설명)

 

1. WebGoat를 다운 받자

https://github.com/webgoat/webgoat/releases

 

WebGoat/WebGoat

WebGoat 8.0. Contribute to WebGoat/WebGoat development by creating an account on GitHub.

github.com

JDK 8.0 이하를 권장. JDK 8.0을 사용중이면 'webgoat-server-8.0.0.M14.jar'를, JDK 11 LTS를 사용중이면 'webgoat-server-8.0.0.M26.jar'를 다운받는다.

(JDK 설치된 버전 확인 방법 : 터미널에 'java -version'을 입력한다.)

주의 : WebGoat 역시 8080포트를 사용한다. Burp Suite 기본 포트도 8080이기 때문에 포트를 바꾸거나 Burp Suite를 종료하고 실행해야한다.

실행 :
1. 해당 .jar 파일이 있는 위치로 이동한다.
2. java -jar webgoat-server-8.0.0.M26.jar --server.port=8080 (만약 8080이 사용중이면 다른 포트로 실행한다. 파일 이름은 복붙하면 된다.)
3. URL에 'http://localhost:8090/WebGoat'로 접속한다. (반드시 WebGoat로 입력해야한다. webgoat로 입력하면 안 된다. 대소문자를 구분하는 것 같음.)

 

등록 버튼을 누른다.

내부 서버니 적당히 입력한다. (아이디 비번 같아도 상관 없음.)

 

2. SQL Injection을 공부하자

각 영역별로 나뉘어 있다. 회색은 설명, 빨간색은 문제.

정답을 풀면 다음과 같이 내가 입력한 쿼리와 결과 그리고 설명이 나온다.

이에 대해 설명하자면, 문제에 나온 쿼리가 DBA가 의도한 쿼리다.

"SELECT * FROM user_data WHERE first_name = 'John' AND last_name = '" + lastName + "'";
user_data 테이블에서 모든것을 출력하라. 조건(WHERE)은 first_name은 'John'이고, last_name은 'lastName'인 것들에 대해서.
i.e. lastName이 '홍'인 경우라면 다음과 같다.
SELECT * FROM user_data WHERE first_name = 'John' AND last_name = '홍';

즉, 우리가 공부할 것은  lastName이 들어가야 할 자리에 어떤 쿼리를 넣으면 보안 문제가 발생하는가를 풀어내는 것이다.
(= 해커가 되어 보안을 뚫어보자)

정답은 맞추면 내가 푼 답안을 보여준다.
SELECT * FROM user_data WHERE first_name = 'John' and last_name = '' or '1' = '1'

이를 해석해보겠습니다. 조건(WHERE)절은 다음과 같이 되어버린다.
SELECT * FROM user_data WHERE first_name = 'John' and last_name = '' or TRUE

이게 왜 문제일까? 다시 한 번 자세히 살펴보자.
SELECT * FROM user_data WHERE first_name = 'John' and last_name = '' or TRUE

WHERE 조건절이 이렇게 변해버린다.
(조건 1) firt_name이 'John'이면서 last_name이 ''
(또는)
(조건 2) TRUE

즉, (조건 1)이 뭐가 되든 상관 없다. (조건 1) or TRUE 에 의해 이 WHERE 조건절은 그냥 무조건 TRUE인거다.

따라서 이를 줄여보면 다음과 같다.
SELECT * FROM user_data WHERE TRUE

=> 따라서 user_data 테이블의 모든 데이터를 출력해낸다.

 

다음 문제로 넘어가봅니다.

원래 의도는 Login_Count에 로그인 횟수를 조회할 숫자를 입력하고,

User_Id에 101, 202 같은 ID 정보를 입력하면 해당 ID에 대한 정보만 조회하는것이다.

해커의 마음으로 생각해보자.

Login_Count의 자료형은 숫자다. 따라서 아무 숫자나 입력한다.(어떤 숫자를 넣던 상관 없다. 문자가 아닌 숫자이기만 하면 된다.)

마찬가지로 User_Id도 자료형이 숫자니까 아무 숫자나 입력한다. 그리고 뒤에 or TRUE를 붙여준다.

 

즉, SQL Injection을 이용해 WHERE 조건을 무조건적인 TRUE로 만들겠다 것이 핵심이다.

WHERE 뭐가 되든 상관 없고 or TRUE

 

따라서 그냥 이렇게 아무렇게나 입력해도 된다.

or TRUE 앞의 조건은 뭐가 되든 관심이 없다. 그냥 형식에 맞기만 하면 된다. 어차피 or TRUE로 앞의 조건을 무시하고 무조건적인 TRUE로 만들거니까!!

 

다음 문제로 넘어가봅니다.

원래 의도한 바는 이렇게 조회를 하겠다는것이다.

하지만 이렇게 넣어주면

WHERE last_name = '" + name + "' AND auth_tan = '" + auth_tan + "'

에서 " + + " ' 은 값이 자료형이 문자열이라 이런 구조가 된 것으로 최종 식은 ''이라 보면 된다. " +     + " 이거를 지우고 최종 형태가 무엇인지를 생각하자.

WHERE last_name = 'Smith' AND auth_tan = ' '

이다.

따라서 WHERE 뭐가 되든 상관 없고 or TRUE를 만들면 되는것이다.

하지만 여기에서는 or TRUE를 입력할 수는 없다.

 

이제 개념을 조금 더 확장시켜보자.

위 2개 예제는 자료형이 숫자이기 때문에 아무 숫자 or 1=1 이나 or True나 같았다. 왜냐하면 숫자 자료형이기 때문에 
WHERE (조건 1) = (값 1) and (조건 2) = (값 2) or TRUE 로, (값2)에서 바로 (조건 2) = (값 2) 의 구문이 끝나고, 그 뒤에 or 새로운 조건이 붙는 것이다

하지만 (조건 2)의 자료형이 문자열인 경우는 (조건 2) = '값 2'의 형태로 그 '값 2'에 우리가 Injection을 하는 것이기 때문에 (조건 2) = ('값 2')의 구문이 or TRUE로는 끝나지 않는다. 즉, or TRUE는 (조건 2) = ('값 2')라는 조건이 끝난 다음에 와야하는데 그냥 '값 2'라는 문자열의 내에 존재해버리는 것이다.

 

!!! 정리하면 !!!

WHERE (조건 1)=(조건 1 자료형에 맞는 아무 값1) and (조건 2) = (값 2 or TRUE)를 만들어줘야하는데,

(조건 2)의 자료형이 숫자면 값2의 자료형에 맞는 아무 값이나 넣어주고, 이미 (조건 2) = (값 2) 구문이 끝났기 때문에 뒤에 아무렇게나 or TRUE만 만들어주면 된다. 즉,

0 or 1=1
0 or 'a'='a'
0 or TRUE

 

(조건 2)의 자료형이 문자열이면 값2의 자료형에 맞는 아무 값이나 넣어주고, 뒤에 or TRUE 조건을 만들어줘야하는데 뒤에 닫히지 않은 ' 를 고려해서 만들어주면 된다. 즉,

a' or 'a'='a

그러면 여기에 닫히지 않았던 뒤에 있는 '에 의해 or 'a'='a'라는 or TRUE 조건이 완성 된다. 즉, 이미 만들어진 형태를 파란색으로 표현하면

(조건 2) = 'a' or 'a'=a'

의 형태로써 Injection이 완성된다.

 

따라서 위 문제는 이렇게만 넣어주면 Injection이 성공한다.

 

 

 

+ Recent posts