[그림 1] 문제


문제를 요약하면 miners.vuln.icec.tf 라는 곳에 들어가서 flag를 가져와야 하는데, DB에는 컬럼들이 하나도 없다도 합니다.

계정이 하나도 없다는 것은 ID, PW 등의 정보가 하나도 없다는 것이므로 컬럼이 없다고 볼 수 있습니다.


일반적으로 admin' or 1=1 -- 과 같은 방법으로 하면 Login Failed라는 문구와 함께 실패한 모습을 볼 수 있습니다.


[그림 2] php 소스


소스를 요약하면 쿼리문에서 username, password를 입력받아서 그것을 connect 할 곳(($con)에 보낸 후 응답하는 값 중 행의 숫자가 1이면 Flag를 뱉어내는 형식입니다.
그렇다면 우리는 어떻게 해서든 리턴되는 행의 수를 1개로 만들어야 합니다.

여기서 힌트는 컬럼이 하나도 없다는 것입니다.

소스를 분석하지 않고 바보같이 limit 방법으로 했다가 계속 풀리지 않았던 게 새록새록 떠오릅니다.

컬럼이 없다면 우리는 가짜 컬럼을 만들어줄 필요가 있습니다.

가짜로 컬럼을 만들기 위해서는 union으로 select문을 사용해야 합니다.

방법은 [그림 3]과 같습니다.

[그림 3] union과 select를 사용하여 가짜 리턴 컬럼을 만들어줌


' and 1=0, union select 1,2,3 #

과 같은 방법으로 했을 때, query에 들어가는 응답은 이렇게 됩니다.

SELECT *
FROM users
WHERE username='' and  1=0

union
SELECT
1,2,3 #' AND password=''

우리가 눈여겨 봐야 할 부분은 union 다음 부분부터 입니다.

먼저 username '' and 1=0 까지 하나의 select 문입니다.

그리고 union 다음의 select문은 그 다음의 select문이지요.


첫 번째 select문은 and 1=0이므로 무조건 아무것도 select하지 않게 됩니다.

두 번째 select문은 1,2,3을 리턴하고 ' AND pass...로 되어 있는 뒷 부분은 #으로 인해 주석처리가 됩니다.

즉, 1,2,3만 리턴하게 됩니다.


그렇게 하면 [그림 4]와 같이 풀이가 되는 것을 알 수 있습니다.

[그림 4] 문제 해결


문제가 해결됐음에도, 아직 찝찝한 기분입니다.

Miners는 동음이의어로 음을 표현하는 - 일 수 있고, 광부들이라는 표현도 있습니다.

SQL Injection이기 때문에 -- 주석이 더 생각납니다.

처음에는 %20-- 을 하면 주석인 줄 알고 아, 혹시 이 문제 잘못됐나...라고 생각했지만, 알고보니

%20--%20이 정확한 주석이었더군요.

그래서 [그림 5]와 같이 풀이를 할 수도 있습니다.

[그림 5] 또 다른 풀이


+ Recent posts