[WriteUp]/[Lord Of SQLInjection] golem

2025. 3. 5. 20:30Hacking/WebHacking Wargame Writeup

#7번째 줄
$query = "select id from prob_golem where id='guest' and pw='{$_GET[pw]}'";

#15번째 줄
if(($result['pw']) &&($result['pw'] == $_GET['pw'])) solve("golem");

→ 이 두 줄을 해석해보면 id는 guest로 고정되어있고, pw는 입력 받은 값을 처리하는 것인데, 입력받은 pw랑 결과 값이랑 일치해야 클리어 값이 나오는 것 같다.

#5-6번째 줄
if(preg_match('/prob|_|\\.|\\(\\)/i', $_GET[pw])) exit(No Hack ~_~");
if(preg_match('/or|and|substr\\(|-/i', $_GET[pw])) exit("HeHe");

→ 필터링이 된 방식은 코드의 5-6번째 줄에서 확인 가능하다.

→ substr을 사용하지 않으면서 pw를 알아내는 방식을 사용해야하는데, 이때는 sql에서 자주 사용하는 like 연산자를 사용하면 좋다.

→ 해당 문제는 약간 trial and error? 방식으로 풀어야한다.

풀이

[도메인값]?pw=0'||id like 'admin'%26%26'1' like '1'%23

→ 첫번째로 이 쿼리를 집어 넣는다.

→ 이 쿼리를 해석하면,

SELECT * FROM users WHERE pw = '0' OR id like 'admin' AND '1' like '1' #';

→ Hello admin 창이 나타난다.

[도메인값]?pw=0'||id like 'admin'%26%26'1' like '2'%23

→ 두번째로 이 쿼리를 집어 넣는다.

→ 1 like 1을 1 like 2 로 변경 ⇒ 다음 화면과 같이 Hello admin이라는 글자가 표시되지 않는다.

→ 이러한 특징을 이용해 이 문제에서는 Blind Injection을 사용할 것이다.

Blind Injection의 특징

→ 공격자는 접속한 데이터베이스로부터 명시적인 정보를 받지 못함

→ 대신, 애플리케이션의 응답 변화를 분석하여 데이터를 추출한다.

→ 보통 참/거짓 값을 기반으로 데이터를 하나씩 추출

  • pw의 길이를 알아보기 위해 다시 한 번 시도를 한다. 이때는 length함수를 사용한다.
    • 길이를 8로 설정했을때 hello admin 문장이 다시 출력되는 것을 볼 수 있다.

 

→ pw 값을 알아보기 위해 인코딩을 일일이 맞춰준다. ‘1%’ , ‘2%’ … 이렇게 맞추다보면 ‘7%’에서 걸리는 것을 볼 수 있다.

→ pw 값은 7로 시작되는 것을 알 수 있다.

→ 같은 방법으로 두 번째 자리도 유추하다보면 두번째자리도 7인 것을 알 수 있다.

→ 77로 시작되는 8자리인것을 확인 가능

→ 77d로 시작되는 비밀번호인 것을 알 수 있다.

→ 77d6로 시작되는 것을 확인 가능하다.

→ 77d62로 시작되는 것을 확인 가능하다.

→ 77d629로 시작되는 것을 확인 가능하다.

→ 77d6290로 시작된다는 것을 알 수 있다.(노가다…)

이렇게 마지막까지 가다보면

→ pw가 77d6290b이다.