문제 화면 및 소스 코드입니다.
4개의 조건문을 통과해야 하는 상황입니다.
조건문에 따라 쿼리 결과가 admin이거나 admin이 아니어야(!admin) 합니다.
즉, 쿼리의 결과가 admin, !admin, !admin, admin 순으로 결과가 나와야 합니다.
부분 주석을 통해 첫 번째 if를 통과했습니다.
하지만 한 번 실행할 때 2개의 결과(admin, !admin)을 동시에 내야
쿼리1에 대한 if를 넘어갈 수 있기 때문에
추가적인 장치가 필요합니다.
(이 부분을 고민하다가 포기하고 라업을 보면서 풀었습니다)
여기서 사용할 수 있는 게 now()와 sleep()입니다.
현재 시간을 나타내는 now()를 2로 나머지 연산(%) 해주면 0 또는 1이 됩니다.
substr()의 두 번째 인자인 오프셋에 0을 설정하게 되면
세 번째 인자와 관계없이 아무 값을 반환하지 않습니다.
sleep()을 사용하면 쿼리를 지정한 초 만큼 정지시킬 수 있으므로 now()의 결과가 변합니다.
이는 첫 번째 if와 두 번째 if에서 실행하는 쿼리의 결과 값이 서로 다르게 될 수 있음을 의미합니다.
위 내용을 토대로 페이로드를 작성해 나가면 됩니다.
이제 초가 바뀔 때 마다 결과가 달라집니다.
(홀수 초이면 admin, 짝수 초이면 !admin)
쿼리 1의 두 번째 if까지 통과하기 위해 sleep과 union을 더해줍니다.
새로고침을 계속 해주면 두 개를 통과해서 소스 코드가 나오는 경우가 생깁니다.
쿼리 2를 사용하는 3번째 if 까지 통과했음을 알 수 있습니다.
(현재 쿼리 2의 no는 싱글쿼터(')로 감싸져 있어 무조건 false 입니다)
이후 라업을 보고 이해하고 페이로드를 적용시켜 보았습니다.
첫 번째 쿼리에서 #' 이후로 문자열로 취급되겠지만 sleep은 실행됩니다.
홀수 초에서 시작해야 문제가 풀리기 때문에 홀수 초에서 시작한다고 가정하면
첫 번째 if 실행 (홀수 초)
1초 지연 (짝수 초)
두 번째 if 실행 (짝수 초)
1초 지연 (홀수 초)
세 번째 if를 실행하기 전 홀수 초로 마무리됩니다.
다음으로 두 번째 쿼리는 #' 이전은 문자열로 취급되며 이후 쿼리가 실행됩니다.
현재 홀수 초이므로
세 번째 if 실행 (홀수 초) - now()%2+1로 2로 만들어버림
1초 지연(짝수 초)
네 번째 if 실행 (짝수 초) - now%2+1로 1로 만들어버림
//클리어//
(만약 +1 대신 -1로하면 1과 2가 아닌 -1과 0이 되기 때문에 결과가 나오지 않는다)
레퍼런스
https://aidencom.tistory.com/327
'write-up(web) > LOS' 카테고리의 다른 글
[Lord of SQLInjection] death write-up (0) | 2022.11.04 |
---|---|
[Lord of SQLInjection] cthulhu write-up (0) | 2022.11.04 |
[Lord of SQLInjection] zombie write-up (0) | 2022.10.05 |
[Lord of SQLInjection] ouroboros write-up (0) | 2022.10.02 |
[Lord of SQLInjection] phantom write-up (0) | 2022.09.21 |