UNION SQL INJECTION PROCESS
DATE : 2023/11/30
Last updated
DATE : 2023/11/30
Last updated
UNION SQL INJECTION을 위한 재료가 모두 갖추어 졌다!!
이제우리의 목표였던 사용자 계정 정보 추출을 위해 SQL injection을 실행해볼 것이다.
다만 문제가 있다면,
(1) 사용자 계정 정보가 어떤 table에 들어있는 지 모른다.
(2) 그 table이 어느 DB에 들어있는 지도 모른다..
(3) table을 찾는다 한들, 어떤 column이 있는 지 모른다...
(4) 화면에 출력 되는 데이터가 어떤column의 값인지 모른다....!
(5) column의 총 개수도 모른다...!!
(6) SQL injection 취약점이 있는 지도 모른다!!!
즉 아는 게 없다!!! 총체적 난국이다.
그렇기 때문에 사실, 공격을 수행하기 위해서는 기본적으로 정보 수집이 필수이다.
따라서 우리에게 필요한 정보를 얻어가면서
SQL Injection에 성공할 수 있는 프로세스를 따라가 보도록 하자!
[1] SQL injection POINT를 찾아내라!
SQL injection을 수행하기 위해서는 당연히, 이 공격을 수행할 수 있을지 확인해 봐야 한다.
게임 검색 기능을 제공하는 사이트에서 "over "라고 입력했더니 overwatch 라는 게임이
결과로 나온 걸 볼 수 있다.
우리는 이 사이트에 SQL injection을 수행할 수 있는 지가 궁금하기 때문에
이라는 Query를 넣어볼 것이다.
그전에 잠깐! 확인할 부분이 있다면 지금 "over"를 입력했는데 "overwatch"가 결과로 나왔기 때문에
like %%가 사용된 가능성이 있음을 예측해볼 수 있다.
(watch, over, overw도 입력해봤다. 결과는 모두 동일!)
Query를 확인해봤더니 예상한 대로 like %__% 형태의 구문이 사용되고 있었다.
그렇다는 건
을 입력하면 이 값이 %% 사이로 들어가기 때문에
맨 앞과 뒤에 따옴표와 % 기호가 있는 걸 감안해야 한다.
따라서 ___에 입력한 값이 들어갔을 때, and '1'='1 과 같은 기능을 수행하도록 만들기 위해서는
이와 같이 값을 입력해야 함을 알 수 있다.
Query를 넣고 결과를 확인해보면!
이 말은 즉, Query를 넣었음에도 불구하고 정상적으로 결과를 얻을 수 있다는 뜻이기 때문에
SQL injection을 실행할 수 있다는 의미가 된다.
[2] column 개수 파악하기
SQL injection의 가능성을 확인했으니 이젠 본격적으로 우리가 원하는 table에 접근해 나갈 것이다.
그러기 위해서 union 연산자를 사용할 것이고,
union을 사용하기 위해 column 개수부터 파악할 필요가 있다.
맨 뒤에 남는 %' 를 제거하기 위해서 주석을 포함한 Query를 작성해보았다.
order by 1부터 실행해보면 결과가 아주 잘 나온다!
order by 2도 해보고, 3, 4.. 해보던 와중에!
order by 5를 딱 입력하는 순간..!
에러가 발생했다. 이는 곧 column의 개수가 4개임을 의미한다.
[3] 출력 되는 column의 위치 알아내기
column의 개수를 알아냈으니 몇 번째 column이 어느 위치에 출력 되고 있는 지 확인해보자.
이번에 사용할 Query는 위와 같다. 총 column의 개수가 4개 라는 건
UNION 앞 작성된 SELECT 문의 결과가 총 4개의 COLUMN을 포함한다는 뜻이다.
따라서 총 4개의 숫자를 달리해서 union으로 결과를 합쳐주면
화면과 같이 4개의 숫자 중 보이지 않는 숫자가 어떤 것인지 알 수 있기 때문에 ( 위에서는 1 )
해당 숫자를 넣은 위치의 column이 출력 되지 않는다는 점과( 위에서는 첫 번째 column )
출력된 column의 순번을 알 수 있다. (name = 2번째, score = 3번째, production = 4번째)
[4] DB name 알아내기
[1] ~ [3]번 과정을 통해 현재 WAS에 작성되어 있는 Query는 4개의 column을 꺼내온다는 점과
그 중 첫 번째 column은 화면에 나타나지 않는다는 점을 알아냈다.
이제는 첫 번째 column을 제외하고 화면 상에 데이터를 출력하는 2,3,4번째 column 중 하나를 골라서
알아내야 하는 DB, Table, column 정보를 하나씩 추출해볼 것이다.
그 중에서도 제일 먼저 알아내야 하는 정보는 바로 DB!
어떤 DB가 존재하는 지 알아야 그 안에 들어있는 Table 정보를 얻을 수 있다.
DB 이름을 알아내기 위해 사용할 수 있는 Query는 다음과 같다.
문제는 이 Query를 UNION으로 어떻게 연결해줄 것이냐는 점이다. 생각보다 그리 어렵지 않다!
우선, [3]에서 알아낸 바와 같이 첫 번째 column 값은 화면에 출력 되지 않기 때문에 제외해야 한다.
그럼 2,3,4번째 column 중에 아무 곳에나 database()를 넣어주면 끝!
결과를 확인해보면 3번 째 column 위치에 database() 값이 들어가 있는 걸 볼 수 있다.
[5] Table 이름 알아내기
앞에서 어떤 DB가 있는 지 알아냈으니 이제는, 그 DB 안에 어떤 Table이 들어있는 지 확인해보자
이때 사용할 Query는 아래와 같으며 이는,
어떤 Table이 들어있는 지에 대한 정보를 가지고 있는 DB information_schema에게
TABLE tables에서 내가 요청한 DB가 가지고 있는 Table 정보를 알려줘! 라고 Query를 날리는 구문이다.
말이 조금 헷갈릴 수 있는데, 여기서 informaiton_schema란
DB에 대한 정보를 저장하는 DB로 흔히 말하는 meta data를 저장하고 있는 Data Base이다.
그 안에서도 굉장히 많은 Table이 존재하는 와중에
어떤 DB가 무슨 table을 가지고 있다! 라는 정보를 넣어둔 Table인 tables에서
WHERE table_schema로 주어진 DB에 어떤 table이 들어있는 지 알려 달라는 요청인 셈이다.
따라서 우리는 segfault_sql이라는 DB가 있는 걸 확인했으니 이 DB에 어떤 table이 들어있는 지
알아내기 위해서는 :
이와 같은 Query를 작성해볼 수 있을 것이다.
그렇다면 이 Query도 3번째 column 위치에 넣어서 SQL injection을 실행해보자!
결과를 확인해보면~
총 4개의 table(game, member, secret, secret_member)가 들어있는 걸 확인할 수 있다!!
[6] column 이름 알아내기
현재 시점에서 알아낸 정보는 DB segfault_sql 안에
총 4개의 table(game, member, secret, secret_member)이 들어있다는 것이다.
그렇다면 다음으로 궁금한 정보는 각 table에 어떤 column이 들어있느냐 것!!
column name을 알아내기 위한 Query는 다음과 같다.
[5]와 동일하게 information_schema에게 물어보는 데
이때 접근하는 테이블은 COLUMN에 대한 정보를 가지고 있는 TABLE columns 이다.
따라서 WHERE table_name으로 요청된 테이블의 column 정보를 알려 달라는 Query 되시겠다.
사용자 계정을 알아내는 것이 우리의 목표였기 때문에 member table 정보를 살펴보면!
TABLE member에는 총 8개의 COLUMN이 들어있다는 사실을 알아낼 수 있게 되는 것이다!!
(+) 나머지 TABLE(secret, secret_member)
[7] 데이터 추출하기
[1] ~ [6] 과정을 통해 DB, Table, Column 이름까지 우리가 필요한 재료를 모두 수집할 수 있었다.
마지막으로 원하는 데이터를 추출하기 위해 Table에서 column을 지정해 SELECT 하기만 하면 끝!
Table secret 내용이 궁금해서
제일 먼저 실행해보았다.
UNION으로 TABLE secret의 정보를 출력해보면 Flag를 얻을 수 있다!
(+) Table secret_member 데이터 추출하기
이렇게 해서 Query의 결과가 화면에 제공되는 경우,
데이터 추출을 어떤 단계에 걸쳐 수행할 수 있을 지 대해 살펴보았다!
전반적인 과정이나 사용한 Query를 외울 필요는 없지만
Query가 뜻하는 바가 무엇이고, 그 과정에서 사용된 information_schema와 같은 개념 정도는
알아두는 게 좋을 듯하다!
아무런 이상 없이 "over"를 입력했을 때와 동일한 결과가 나온 걸 볼 수 있다!!
UNION & ORDER BY에서 알아본 내용을 여기서 활용해보자
이로써 DB segfault_sql이 있다는 점이 알아냈다!