SQL injection/lord of SQL

Lord Of SQL injection 28단계-frankenstein

ys.k 2022. 1. 22. 03:29

LOS 포스팅에 앞서 내용이 틀릴 수도 있으며, 해당 부분 지적은 감사히 받겠습니다.

28단계 소스코드이다.

pw에 prob, _,., (, ), union, 등의 문자열들이 필터링되고 있다.

소괄호가 필터링되어 여러 함수들을 사용할 수 없게 되었다.

ex) sleep(), substr()

문제 해결조건은 admin의 pw값을 입력하면 된다.

pw를 찾기 위해 함수를 우회할 방법부터 찾아보자.

1. if(조건) -> case when 조건 then 참, 거짓 end

ex) if(a>b,1,2) -> case when a>b then 1 else 2 end 

하지만 이번쿼리에서는 참과 거짓을 구분해야하는데 sleep(), benchmark(),union등을 사용할 수 없게되어 괄호없이 에러를 유발할 수 있는 방법을 찾아야한다.

인터넷 검색을 하던중 에러를 낼 수 있는 방법을 찾았다.

지수연산을 이용하여 범위초과에러를 내는 방법이다.

mysql에선 9e307 까지가 오류를 내지않고 표현할 수 있는 최대치이며 9e308부터는 오류가 난다.(이 문제에서 사용할 수 없는 오류)

따라서 9e307*2로 오버플로우를 내주면 된다.

또한 이번 문제에서는 소괄호가 들어간 함수가 필터링 되어 length()를 쓸 수 없다.

하지만 인젝터에서 like를 사용하면 pw의 자릿수를 몰라도 공격 할 수 있다.

쿼리로 작성한다. 

?pw='||id='admin' and case when pw like'N%'then 9e307*2 else 1 end--+-

N의 자리에 문자열을 비교하며 비밀번호의 값을 첫자리 부터 유효하지 않는 값이 나올 때 까지 찾으면 된다.

인젝터를 작성한다.

0dc4efbb까지 출력되고 이후값은 시간이 지나도 더이상 나오지 않는다.

따라서 pw값은 0dc4efbb로 추측된다.

문제 해결

시행착오

1. 역대급 시행착오 였는데, 문제를 다 풀어놓고도 해결을 못해 수시간을 지체 시킨 문제이다.

   바로 웹페이지에서 직접 쿼리를 주입했을 때 결과랑 인젝터로 돌릴 때의 결과가 다를 수 있다는 점이다..

1-1. ?pw=%27||id='admin'and case when pw like'{}%'then 9e307*2 else 0 end--+-

1-2. ?pw=%27||id='admin'and case when pw like'{}%25'then 9e307*2 else 0 end--+-

      처음 인젝터에서는 like'{}%'로 두고 실행했지만 출력되는 결과 값에 계속 문제가 생겼었다.

      나는 처음에 if구문에서 참과 거짓을 구분하는 인자가 잘못되었는줄 알았지만 문제는 url 인코딩에 있었다.

      웹페이지에서는 like'0%'로 실행했을 경우 정상적으로 결과가 반환되지만 인젝터에서는 다른결과를 보여줬다.

      그래서 인젝터 %를 url인코딩 값으로 바꿧더니 정상 실행 되었다. 문제를 해결했지만 굉장히 찝찝하다.. 추후에

      다른 문제점이 없었는지 더 찾아 봐야겠다.

2. 인젝터에서 참과 거짓을 구분하는 if구문에서 ex) if res.text.find("찾을값") 참과 거짓에서 표출되는 웹페이지의 큰          차이점을 잡을 수 없을경우 웹페이지 소스코드부분에서 조금더 디테일 하게 구분할 수 있다. 

    ex)1. 에러페이지

        2. 정상페이지

확실히 차이점이 보인다.