(Lord of SQLInjection) red_dragon 문제입니다.
제공되는 코드를 살펴보면
id는 최대길이가 6까지 가능하며 넘어갈시 too long string 를 출력하고 있습니다.
길이가 짧은 만큼 no 부분을 활용하라는 문제같은데
no는 is_numeric()라는 함수로 숫자만을 입력받고 숫자가 아니라면 1을 출력하고 있습니다.
다음으로 query를 자세히 살펴보면 GET['id] 를 싱글쿼터 ' ' 로 감싸고 있으며 no는 감싸고 있지 않습니다.
우리의 목표는 한줄건너띈 부분을 보면 id가 admin인 값의 no값을 정확히 맞춘다면
solve("red_dragon") 문제가 해결된다고 합니다.
그럼 먼저 admin을 출력하는 것이 관건인데 이는 이전 문제에서 많이 사용했던
주석처리를 이용할 수 있습니다.
현재 query는 id = ' GET['id'] ' and no={$no} 이므로
id 부분에 싱글쿼터를 넣고 ' 1=1#을 넣어본다면
Hello admin의 출력이 가능합니다.
여기서 length() 나 substr() 같은 함수를 사용시 길이제한에 걸리므로 많은 고민이 필요했습니다.
지인의 도움으로 이전 서큐버스 문제등 일부주석이라는 힌트를 받아 해결했습니다.
현재 쿼리는 id = ' GET['id'] ' and no={$no} 상태입니다.
각 부분에 입력할 값을 빨간색으로 표시했으며
# 한줄주석으로 줄바꿈인 %0a으로 원하는 부분 까지만 주석처리를 시도했습니다.
id = ' '||no>#' and no=%a010
이렇게 입력한 쿼리를 정리하면 id = ' ' || no>10이 되며
Hello admin을 출력하면 True False를 확인하여 SQL 인젝션 공격이 가능해집니다.
또한 id부분에 값을 입력하는 것이 아닌 no에 값을 입력하기에 이는 id의 6글자 제한에도 걸리지 않게 됩니다.
값을 문제사이트에 전달해보면 Hello admin이 출력되며 원하는대로 실행되는데
아래 실행query를 자세히 보면 no= 10 으로 띄어쓰기 상태입니다.
이는 %0a로 줄바꿈이 되어 한줄주석처리인 #의 영향을 받지 않게 된것을 확인 할 수 있습니다.
True만 되면 admin이 되는 것을 확인했으니 이를 활용해 no의 값이 몇인지 확인하면 되는데
is_numeric()함수가 있기에 숫자로 1 10 100등 확인해보는데
1억보다 크며 10억보다 낮은 수라고 합니다....
이건 도저히 순차탐색으로는 불가능 할것 같아 이진탐색을 공부 후에
예시코드들을 참조해 코드를 구성했습니다.
먼저 10억자리에서 Hello admin이 출력되지 않았으니
0부터 최대 값을 10억으로 잡고 이진탐색을 시도 하면
값이 점점 줄어가며 586482014에서 멈추며 no의 값을 찾았습니다.
찾은 no의 값을 문제사이트에 전달해보면
문제가 해결되었습니다!
'Wargame(Web) > Lord of SQLInjection' 카테고리의 다른 글
(Lord of SQLInjection) frankenstein 문제 (0) | 2022.11.17 |
---|---|
(Lord of SQLInjection) blue_dragon 문제 (0) | 2022.11.17 |
(Lord of SQLInjection) green_dragon 문제 (0) | 2022.10.28 |
(Lord of SQLInjection) evil_wizard 문제 (0) | 2022.10.09 |
(Lord of SQLInjection) hell_fire 문제 (0) | 2022.10.09 |