-
UNION SQL Injection [6주차]모의해킹스터디5기(feat.Normaltic) 2023. 12. 8. 10:42
이전에 SQL Injection에 대해 간단히 알아봤는데,
이번에는 조금 더 심화된 내용이라 할 수 있는 UNION SQL Injection에 대해 알아본다.
UNION
UNION은 SQL문을 합쳐주는 집합 연산자이다. 정확히는 SQL문의 결과를 합쳐서 보여주는 역할이다.
예를 들어 다음과 같은 데이터베이스에서
1. DB member 아래의 SQL문을 입력하면
SELECT * FROM member WHERE id = 'doldol'
UNION
SELECT * FROM member WHERE pass = '1234'위의 결과와 아래의 결과를 합쳐서 보여준다.
아래의 이미지가 각각의 SQL문 결과를 나타낸 건데
2. SQL결과(왼쪽이 위 SELECT문/ 오른쪽이 아래 SELECT문) 아래의 이미지는 UNION의 결과다.
3. SQL 결과(UNION) UNION의 특징은 중복된 결과를 알아서 제거해주는 점이다.
또 하나는 UNION을 하기 위해선 두 SELECT문의 컬럼 수가 같아야 한다는 것이다.
위의 두 결과는 id와 pass 두 개의 컬럼으로 같기 때문에 합칠 수가 있는 것이다.
UNION SQL Injection을 사용하는 경우
먼저 당연히 DB를 사용하는 곳이어야 한다.
DBMS의 종류는 다양하겠지만 SQL문을 사용해야 SQL Injection을 삽입할 수 있으니.
그리고 SQL문의 결과가 화면에 나타나는 곳이어야 한다.
게시판이나 마이페이지가 이런 조건에 맞는 곳이다.
반대로 로그인 페이지 같은 곳은 SQL문의 결과를 확인할 수 없으니
UNION SQL Injection을 사용하기에 적합한 곳은 아니다.
종합하자면 UNION SQL Injection은 웹페이지에 데이터가 보여지는 곳에서 데이터를 추출하는 공격 기법이다.
UNION SQL Injection의 과정
1. SQL Injection 포인트 찾기
- SQL문이 적용되는 곳인지 확인한다.
- 이전에 알아봤던 # 이나 ' AND '1'='1 을 사용해서 정상적으로 작동을 한다면 SQL Injection이 가능한 곳이다.
2. COLUMN 개수 찾기
- 여기서 활용할 수 있는 게 ORDER BY 절이다.
- ORDER BY는 뒤에 오는 컬럼들을 기준으로 정렬을 해서 보여주는 기능이다.
SELECT * FROM member ORDER BY id, pass
위의 SQL문은 member 테이블에서 모든 정보를 가져오는데, 먼저 id를 기준으로 정렬을 하고, id가 같다면 pass를 기준으로 정렬을 해서 보여달라는 뜻이다.
- ORDER BY는 컬럼 대신 숫자를 넣을 수도 있다. 이것을 사용해서 컬럼 개수를 구할 수 있다.
SELECT * FROM member ORDER BY 1, 2
id, pass 로 정렬하는 것과 1, 2 로 정렬하는 것은 같은 결과를 가져온다. 테이블 안에서 id와 pass의 컬럼의 순서가 첫번째(1), 두번째(2)이기 때문이다.
4. member 테이블 - 말이 길어졌는데, 결론을 말하자면 ORDER BY 뒤에 1, 2, 3, 4, ... 숫자를 계속해서 넣어서 입력해보는 것이다. 계속해서 넣다보면 오류가 생기는데 오류가 생기기 전까지가 그 테이블이 가지고 있는 컬럼의 개수인 것을 알 수 있다.
5. ORDER BY 오류 3. 출력되는 COLUMN의 위치 찾기
- 알고 있어야 하는 게 SELECT문을 통해 테이블의 모든 컬럼이 추출되는 것이 아니고, 또 모든 컬럼이 화면에 나오는 것이 아니다.
- 지금 화면에 나오는 결과가 몇 번째 컬럼인지 파악하는 게 중요하다. 이 때 UNION 연산자를 사용한다.
- 컬럼의 개수는 파악했으니 개수에 맞게 합치면 된다. 예를 들어 컬럼이 4개라면 ' UNION SELECT 1, 2, 3, 4 # 을 사용해서 화면에 어떤 숫자가 뜨는지를 보면 알 수 있다.
6. column 위치 찾기 위의 이미지를 보면 Info에서만 SQL의 결과를 확인할 수 있어서 이 위치를 찾는 것이 정보를 알아내는 데 중요하다. Info 컬럼에 6 이라는 숫자가 나오는 것을 통해 Info 컬럼이 6번째인 것을 알 수 있다.
4. DB 이름 확인
- 이제 이 위치를 통해 DB 이름을 알 수 있다. 다시 위의 SELECT문을 예를 들면 6번째에 DB 이름을 나타내는 함수를 넣어 주면 된다. 그 역할을 하는 것이 database() 이다.
normaltic' UNION SELECT 1, 2, 3, 4, 5, database() LIMIT 1, 1 #
5. Table 이름 확인
- 다음으로 테이블의 이름을 알아낸다. 이건 정해진 문구가 있으니 외워두는 것도 좋을 것 같다.
normaltic' UNION SELECT 1, 2, 3, 4, 5, table_name FROM information_schema.tables WHERE
table_schema = 'DB 이름' LIMIT 1, 1 #- 보통 테이블이 여러 개가 있는 경우가 많다. 게시판처럼 전부 보여주는 곳이 아니라면 LIMIT으로 한 행씩 확인하면서 테이블을 확인해야 한다. (LIMIT A, B : A번 행부터 B개까지 보이기로 제한)
6. Column 이름 확인
- 테이블 구할 때와 비슷한 방법으로 컬럼 이름을 알아낸다. 이것도 알아두자.
normaltic' UNION SELECT 1, 2, 3, 4, 5, column_name FROM information_schema.columns WHERE
table_name = '테이블 이름' LIMIT 1, 1 #- 컬럼도 LIMIT을 잘 활용해서 전체적으로 확인한다.
7. Data 추출
- 테이블과 컬럼의 이름들을 알아냈으니 이제 원하는 정보를 UNION으로 합쳐서 내보내면 된다.
normaltic' UNION SELECT '컬럼' FROM '테이블'
'모의해킹스터디5기(feat.Normaltic)' 카테고리의 다른 글
SQL Injection 마무리 [8주차] (0) 2023.12.19 Error Based SQLi / Blind SQLi [7주차] (0) 2023.12.08 SQL Injection [5주차] (0) 2023.12.07 Burp Suite [4주차] (0) 2023.11.27 로그인 로직 [3주차] (0) 2023.11.21