Burp suite 사용하기 - Repeater 사용 및 매개변수 조작 실습

2018. 12. 5. 17:30 해킹과 보안/보안 관련

버프슈트를 이용해서 현재 요청을 가로채서 매개변수를 변경하여 봅니다. 이것은 화면에서 자바스크립트등으로 입력값의 길이를 제한해 두었다던가, 숫자등으로 입력값의 타입을 제한 하는등의 노력을 무력화 시킬 수 있습니다. 실제로 코딩에서는 서버측에서도 동일한 체크를 반드시 수행해야만 합니다.

 

"스프링 프레임웍에서 MyBatis, Oracle 사용하기" 에서 사용한 샘플에 테스트 데이터를 추가하고, 글번호를 파라미터로 넘겨서 글 내용을 보는 페이지는 추가하여 테스트 해 봅니다. 보안관련 테스트를 허가받지 않은 사이트에 하면 절대 안됩니다.

 


1. 샘플 데이터를 입력합니다. sqldeveloper 에서 입력 쿼리를 작성하고, 스크립트 실행 버튼(단축키 F5)을 눌러 실행합니다. sqldeveloper 는 기본적으로 자동 커밋이 아니기 때문에 입력 쿼리 실행후 커밋 버튼(단축키 F11)을 누르거나, commit; 명령을 직접 실행해서 커밋 해야만 데이터베이스에 완전히 반영이 됩니다. rollback 하게 되면 앞의 입력이 취소 됩니다.

 


 

 

2. Tb_Board_SQL.xml 파일에 입력 쿼리를 추가합니다.

 <select id="selectBoardView" resultType="boardVO">
        SELECT NUM
       , NAME
       , TITLE
       , CONTENT
       , READ_COUNT
       , WRITE_DATE
       FROM TB_BOARD
      WHERE NUM = #{num}
 </select>

 

#{num} 부분에 파라미터로 넘어올 글 번호가 넘어갑니다. MyBatis 에서 #{param} 은 실제 실행될 때 PreparedStatement 로 실행됩니다.  SQL Injection  공격을 막기 위해서는 모든 쿼리에서 PreparedStatement 를 사용하도록 합니다.

 

3. BoardDAO.java 파일에 위 SQL 파일의  id 에 대응하는 메소드를 추가합니다.

 

BoardVO selectBoardView(@Param(value = "num") Integer num) throws Exception;

 

여기에서 @Param(value = "num") 아노테이션은 뒤의 변수가  SQL 파일의 매개변수 #{num} 을 사용할 수 있도록 해 주는 부분 입니다.

 

4. BoardService.java 파일에 메소드를 추가합니다.

 

BoardVO selectBoardView(Integer num) throws Exception;

 

5. BoardServiceImpl.java 파일에 메소드 구현을 추가 합니다.

@Override
@Transactional
public BoardVO selectBoardView(Integer num) throws Exception {
    return boardMapper.selectBoardView(num);
}

 

6. HomeController.java 파일에서 요청에 대응 되는 메소드를 작성합니다. @RequestParam 아노테이션은 뒤에 나오는 변수에 요청으로 부터 넘어온 파라미터를 맵핑 하도록 합니다. 서비스를 호출하여 글번호에 해당하는 데이터를 BoardVO 형태로 받아 모델 객체에 추가해주면 뷰에서 사용할 수 있습니다.

@RequestMapping(value = "/boardView.do")
public String boardView(@RequestParam Integer num,  Model model) throws Exception {
    BoardVO vo = boardService.selectBoardView(num);
    model.addAttribute("vo", vo);
    return "boardView";
}

 

7. boardView.jsp 뷰 파일을 작성합니다.

<%@ page contentType="text/html; charset=euc-kr" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<!DOCTYPE html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=euc-kr"/>
    <title>Home</title>
</head>

<h1>Board View</h1>
<table border="1">
<tbody>
    <tr>
        <th>번호</th><td>${vo.num}</td>
        <th>작성자</th><td>${vo.name}</td>
        <th>작성일</th><td>${vo.writeDate}</td>
    </tr>
    <tr>
        <th>제목</th><td colspan="3">${vo.title}</td>
        <th>조회수</th><td>${vo.readCount}</td>
    </tr>
    <tr>
        <th>내용</th><td colspan="5">${vo.content}</td>
    </tr>
</tbody>
</table>

 8. 이제 Burp suite 를 실행합니다. 여기서 한가지 문제가 있는데, Burp Suite 는 프록시로 8080 포트를 사용합니다. 그런데 우리의 샘플 프로젝트도 Tomcat 의 8080 포트를 사용합니다. 그래서 둘 중의 하나의 포트를 바꿔줘야 합니다. Bur Suite 의 포트를 8090 으로 바꾸고 실행해 봅니다.

 

Proxy 탭을 선택하고 아래의 Options 탭을 선택합니다. Proxy Listeners 를 설정하는 곳이 있습니다. 현재 8080으로 되어 있는것을 선택하고, Edit 버튼을 누르면 창이 떠서 포트를 변경할 수 있습니다. 8090으로 변경합니다.

 


 

9. 이제 브라우저의 LAN 설정에서 프록시를 사용하도록 설정을 변경합니다. 도구->인터넷옵션 창에서 연결 탭을 누르면 하단에 LAN 설정이 있습니다. 프록시 서버를 체크하고, 포트를 8090으로 입력합니다. 확인 버튼을 누르면 적용이 됩니다.

 


 

10. 준비가 길었네요. 이제 실제 테스트를 해봅시다. 먼저 해볼 것은 요청을 가로채서 매개변수를 변경한 후 전송하는 것입니다. 그전에 먼저 하나 알아 둘 것이 있습니다. 버프슈트를 local에 사용할 때는 브라우저가 프록시를 통하지 않고 그냥 처리 해버립니다.

 

로컬 주소에 프록시 서버 사용 안 함을 체크하지 않더라도 프록시가 사용되지 않습니다. 이때는 브라우저의 주소표시줄에 주소를 입력할때 끝에 마침표(.) 를 붙이면 됩니다. http://localhost.:8080/pentode/boardList.do 이렇게 localhost 뒤에 마침표를 붙입니다.

 

Interceptor is on 상태에서 목록에 num=9번에 클릭합니다. 버프슈트가 요청을 가로채서 서버로 전송을 하지 않고 있는 상태이기 때문에 제목표시줄에 localhost. 대기 중이고, 아직 데이터를 서버로 보내지 않은 상태입니다.

 


 

11. 버퍼 슈트 화면에는 현재의 요청 정보를 보여줍니다. GET /pentode/boardView.do?num=9 가 요청한 URL 이라는 것을 알 수 가 있습니다. 그 외의 브라우저가 서버로 보내는 헤더 정보들도 확인할 수 있습니다.

 


 

12. Params 탭을 클릭해서 봅니다. value 부분을 더블 클릭해서 값을 8로 변경한 후  Forward 버튼을 누르면 이제야 데이터가 서버로 전송이 됩니다.

 


 

13. 실행된 브라우저 화면 입니다. 실제로 브라우저에서 9번을 클릭했지만 중간에 프록시에서 값을 8로 변경했기 때문에 8번 게시물이 보여집니다.

 



 

14. 이번에는 인터셉터 탭에서 Intercept is off 로 두고, HTTP History 탭을 클릭한 후 웹 페이지를 여기저기 클릭해보면 브라우저와 서버가 주고 받는 모든 정보를 확인해 볼 수 있습니다. 프로그램이 어떤 파라미터로 어떤 타입의 값들을 주고 받고 있는지 확인할 수 있습니다.

 

 

15. 이제 이 히스토리 중에 하나를 repeater에 등록하여 요청을 보내는 것을 해보겠습니다. 리피터는 히스토리상의 요청을 저장해 두었다가 다시 보낼 수 있도록 해줍니다. 파라미터를 변경해가면서 같은 요청을 여러번 보낼 수 있습니다.

 

이러한 특성때문에 결과가 브라우저에 나오는것이 아니라, 리피터 하단의 결과 창에서 보여집니다. History 중 하나에 마우스 오른쪽 키를 눌러 팝업창에서 Send to Repeater 를 클릭합니다. 해당 요청이 리피터에 등록됩니다.

 

 

16. 상단의 리피터 탭을 선택합니다. 좌측 하단의 Params 탭을  선택해서 전송된 파라미터를 변경할 수 있습니다. 2번으로 변경한후 Go 버튼을 누르면 서버로 요청이 가고, 우측 Response 창에 결과가 보여집니다.

 

 

버퍼슈트를 사용해서 매개변수를 조작하는 것을 해보았습니다. 또한 리피터에 등록하여 요청을 반복적으로 보내는 것도 해보았습니다. 이것은 프로그램을 제작하면서 시큐어코딩이 잘 되었는지 여부를 확인하는데도 좋은 방법이 됩니다. 물론 테스트케이스를 만드는 것이 더 편하겠죠.



출처: https://offbyone.tistory.com/19 [쉬고 싶은 개발자]