문제에 접속하니 "done!" 라는 문구와 함께 소스가 주어져있다. 소스를 봐보도록 하자.
소스코드를 분석해보자.
1. 클라이언트의 브라우저, os 정보를 가져와 공백제거 후 $agent 변수에 저장(2번 줄)
2. 클라이언트의 ip 주소를 가져와서 $ip 변수에 저장(3번 줄)
3. $agent 변수에 "from"이 포함되어있으면 프로그램 종료(4~7번 줄)
4. chall8 테이블의 id 속성의 레코드 갯수를 가져온 후 $count_ck 변수에 저장 (10번 줄)
만약, $count_ck 값 즉, 카운팅 갯수가 70이상이면 chall8 테이블을 삭제 (브루트 포스 방지용 인 것 같다.) (11번 줄)
5. 클라이언트의 http_user_agent 정보를 가져와 그 정보에 해당하는 id 속성값을 가져와 최종적으로 $ck 변수에 저장한다.(13~14번 줄)
6. $ck 변수에 값이 존재할때, $ck[0] 값이 "admin" 이면 문제가 해결된다. 즉, id값이 "admin"인 데이터를 5번과정에서 가져오면 문제 해결 (16~21번 줄)
7. $ck 변수에 값이 존재하지 않는다면 chall8 테이블에 레코드를 생성하여 데이터를 넣는다. (24~27번 줄)
마지막 7번을 보면 chall8 테이블에 데이터를 insert 할 수 있다는 것을 알 수 있는데, 이 부분을 이용하여 insert sqli를 시도하면 id값이 "admin"인 데이터를 생성 할 수 있을 것이다.
이번 문제의 최종 목적은 13번 줄에서 id가 "admin"인 데이터를 select 하는 것이 최종목표이다.
따라서 위 내용과 연결하여 다음과 같은 공격시나리오를 생각해볼 수 있다.
☆ 공격 시나리오 ☆
1. 버프스위트를 이용하여 패킷의 user-agent 값을 조작하고 id가 "admin"인 데이터를 chall8 테이블에 삽입한다.
(버프스위트에 대해서 모르는 독자는 조사하고 오길 바란다.)
2. 삽입한 레코드의 agent값을 이용하여 id가 "admin"인 데이터를 추출한다.
이제 공격 시나리오 대로 공격을 진행해보자.
먼저, 패킷을 조작하기 전에 25번 줄에서 어떻게 insert sqli를 시도할지 먼저 생각해봐야겠다.
우리가 조작할 수 있는 값은 $agent 값이기 때문에 직접적인 방법으로 id값이 "admin"인 데이터를 생성할 수는 없다.
그렇다면 insert의 성질을 이용하여 id값이 "admin"인 데이터를 우회해서 생성해야 할 것이다.
위는 25번줄에서 insert 할때 내가 실행하고 싶은 sql 쿼리이다.
sql 에서 insert할때 , 를 이용하면 여러 개의 데이터를 동시에 넣을 수 있는데 이를 이용하여 agent 값이 "123"이면서 id가 "admin"인 데이터를 우회하여 테이블에 생성 할 수 있다.
이렇게 하면 $agent 값을 이용해 id가 "admin"인 데이터를 생성할 수 있다!
버프스위트를 이용하여 패킷을 잡고 user-agent 의 값을 우리가 삽입할 sqli payload 값으로 변경하여 패킷을 전송해보자.
(위 사진은 예제이며 실제 공격을 할때는 본인의 PC IP주소를 넣어줘야한다.)
이제 데이터가 테이블에 들어갔을테니 새로고침하여 새로운 패킷의 agent 값을 123으로 보내줘서 우리가 삽입한 id가 "admin"인 데이터를 추출해보자.
클리어!!