묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결버그헌팅과 시나리오 모의해킹 전문가 되기
[공유]섹션6.Kioptrix_level_2 SQL Injection을 이용한 MySQL 버전 정보 획득
안내1) 해당 정보는 섹션6의 MySQL 버전 정보 획득 방법을 공유하기 위함입니다.안내2) 해당 내용은 강의 내용에 포함되지 않은 사항이므로 섹션6 강의를 모두 들으신 후 참고하시길 추천합니다.안내3) 해당 정보는 SQL Injection과 Burp Suite에 대한 지식이 있는 상태에서 봐야 더욱 이해하기 쉽습니다.안내4) 잘못된 내용이 있을 수 있으니 잘못 표기 된 내용은 댓글로 지적해 주시면 감사하겠습니다.[SQL Injection이 가능한 ID/PW 입력 창]-> ID/PW 입력 창에 SQL Injection이 가능함을 알 수 있습니다.-> 해당 부분에 SQL Injection 기능을 이용해서 MySQL의 버전 정보를 알아낼 것 입니다. ㅁ 사용할 SQL Injection 종류 선정Error Based SQL Injection(불가) : ID/PW 입력 창에 싱글쿼터만 입력하면서 Error 발생을 시켜서 DBMS 에러 메시지가 나오는지 확인했으나 나오지 않으므로 Error Based Injection은 불가Union Based SQL Injection(불가) : 입력에 대한 DB의 응답 값이 표현 된 부분이 없는 것 같아서 Union Based SQL Injection 도 사용 불가Blind SQL Injection(사용) : 입력 SQL Injection 구문이 False인 경우 ID/PW 입력 창(index.php), 입력 SQL Injection 구문이 True 일 경우 pingit.php 가 나오므로 Blind SQL Injection으로 MySQL 버전 정보를 얻기로 결정들어가기에 앞서. MySQL의 버전 정보를 담은 함수는 version() 입니다.[MySQL 버전 정보 획득 과정]1. MySQL 버전 정보 글자 길이 확인1). Burp Suite를 키고 브라우져에 Proxy 서버를(127.0.0.1:8080) 설정하여 Burp suite를 통해 Kali와 Kioptrix_level_2 웹 서버와 통신하게 구성합니다.2) ID/PW 입력창에 ' or 0<length((version()))# 입력하고 Login 버튼을 클릭하면 Burp Suite에 아래와 같이 쿼리문이 잡힙니다. -> 해당 쿼리문을 설명하면 MySQL 버전 정보를 담은 version()의 글자 길이가 0보다 큰지 질의 하고 있습니다.(당연히 version 정보는 3.X.XX 또는 5.X.XX 이런식으로 구성됬기 때문에 글자 길이가 0보다는 클 것 입니다.)Tip. '(싱글쿼터)가 웹 인코딩이 되면 %27 : 따라서 burp suite에서 %27로 표시됨#(샵)도 웹 인코딩 되면 %23 : 따라서 burp suite에서 %23으로 표시됨-> or의 오른쪽 0<length((version()))#가 참(True) 이므로 쿼리문이 참 그래서 Response에 이렇게 결과를 확인 할 수 있습니다.-> pingit.php가 결과로 들어옴을 확인 할 수 있습니다.그래서 ?=length((version()))# 쿼리에서 ?의 숫자들을 1부터 2,3,4 .... 높여가다 보니 6일 때 6=length((version()))# 가 True로 반환되어 Response에 pingit.php가 나옴을 확인 할 수 있습니다.[Request에서 6=length((version()))#로 쿼리문 구성][Response 결과]결론 : MySQL 버전 정보 길이는 6글자 이다. 2. MySQL 버전 정보 획득이제 MySQL 버전 정보 글자 길이가 6글자 임을 알아 냈으니 버전 정보가 어떤 글자들인지 알아내야 합니다.쿼리문을 아래와 같이 ascii와 substring 구문을 이용해서 구성하였습니다.[MySQL 버전 정보 얻는 SQL 쿼리문]해설1) ascii : ascii()하면 괄호안의 값을 ascii 코드 값으로 변경하는 함수 입니다.해설2) substring((version()),1,1) : version의 첫번째글자에서 1개의 글자(즉, 첫번째 글자 한개)를 가져오는 함수 입니다.해설3) 52=ascii(substring((version()),1,1))# 은 substring을 통해서 version의 첫번째글자에서 1개의 글자를 가져온 값이 ascii 코드 값으로 52가 맞는지 묻는 쿼리문 입니다.ascii 코드표를 보면 ascii 코드 값 52는 '4' 입니다.결론은 해당 쿼리문 결과가 참이므로 Response에 pingit.php를확인 할 수 있습니다. 그런데 ascii 코드 값은 굉장히 많으므로 Burpsuite에 intruder 기능을 이용해서 나머지 5글자를 찾아보겠습니다.-> intruder에 접속해서 positions 메뉴에서 payload positions 아래에 쿼리문에서 52=ascii(...)부분에서 52를 드래그 선택하고 오른쪽에 add$를 클릭합니다.(예시)그리고 위쪽의 Payloads 메뉴를 선택합니다.-> payload set: 1은 $로 감싼 52부분을 뜻합니다.-> payload type을 ascii코드값을 순차적으로 탐색할 것 이므로 Numbers로 바꿔주고-> 아래 payload options에서 From 33, To 126, Step 1로 설정합니다.From 33, To 126 인 이유 ascii코드값 33~126이 모든 숫자,영문 대소문자, 특수문자 값이므로[version()) 2,1 즉 version의 2번째 글자][intruder를 통한 2번째 글자 확인] ascii 코드값 46일 때 True, pingit.php 확인, ascii코드값 46은 온점('.')version()의 2번째 글자 : '.'(온점) [version()) 3,1 즉 version의 3번째 글자][intruder를 통한 3번째 글자 확인]ascii 코드값 49일 때 True, pingit.php 확인, ascii코드값 49는 '1'version()의 3번째 글자 : '1'(숫자 1) [version()) 4,1 즉 version의 4번째 글자][intruder를 통한 4번째 글자 확인]ascii 코드값 46일 때 True, pingit.php 확인, ascii코드값 46은 온점('.')version()의 4번째 글자 : '.'(온점) [version()) 5,1 즉 version의 5,6번째 글자][intruder를 통한 5,6번째 글자 확인]ascii 코드값 50일 때 True, pingit.php 확인, ascii코드값 50은 숫자2('2')참고로 6번째 글자도 5번째 글자와 동일한 결과 회신지금까지 나온걸 모두 합치면 4.1.22 결론 : MySQL의 버전은 4.1.22 후기.혹시 MySQL 4.1.22 버전에 맞는 공격코드가 있는지 검색했지만 Integer Overflow는 DoS공격, Privilege Escalation은 .txt이다. (따라서 공격을 진행할 수 없다)
-
해결됨모의해킹 실무자가 알려주는, SQL Injection 공격 기법과 시큐어 코딩 : PART 1
[실습 7-4, 7-5, 7-6] MySQL, MSSQL, Oracle union based 공격 실습 강의 이후 상세보기에서 순차적 데이터 호출 실습 질문
1) 실습 7-4 MySQL에서 상세보기 메뉴에서 순차적으로 데이터를 호출하기 위해 limit 절을 활용하였습니다.[실습 쿼리문]http://localhost/board/mysql/view.php?idx=7 and 1=2 union select null,schema_name,null,null,null,null,null from information_schema.schemata limit 2,1%23[쿼리문 실행 결과]1. 상세보기 page의 Title 컬럼에 login_example 을 확인 할 수 있었습니다.2. limit 3,1을 하면 상세보기 page의 Title 컬럼에 mysql을 확인 할 수 있었습니다.2) 실습 7-5 MSSQL에서 상세보기 메뉴에서 순차적으로 데이터를 호출하기 위해 not in과 서브쿼리문을 이용하였습니다.[실습쿼리문]http://localhost/board/mssql/view.php?idx=6 and 1=2 union all select null,name,null,null,null,null,null from master.sys.databases where name not in(select top 0 name from sysdatabases)--[쿼리문 실행 결과]1. 상세보기 page의 Title 컬럼에 master 를 확인 할 수 있었습니다.2. 서브쿼리의 top 0 대신 top 1으로 숫자를 올리면 tempdb라는 2번째 데이터베이스 이름을 확인 할 수 있었습니다.3) 실습 7-6 Oracle에서 상세보기 메뉴에서 순차적으로 데이터를 호출하기 위해 rownum과 서브쿼리 기능을 이용했습니다.[실습쿼리문]http://localhost/board/oracle/view.php?idx=61 and 1=2 union all select null,table_name,null,null,null,null,null from(select rownum r, table_name from all_tables)tb where tb.r=2--[쿼리문 실행결과]1. 상세보기 page의 Title 컬럼에 SYSTEM_PRIVILEGE_MAP 두번재 table이름이 나온 것을 확인 할 수 있습니다.질문1)강의 종료 후 제가 제대로 과제를 수행한건지 궁금합니다. 추가적으로 더 확인해 봐야 할 것이 있을 까요? 질문2) MSSQL에서 order by 정렬 기능이나 row_number()함수를 이용해서 순차적으로 출력하는 쿼리문을 만들 수 있을까요?(섹션 4에서 MSSQL에서 순차정렬이 가능한 여러 방법의 내용 처럼)--> 저는 아무리 생각해도 적절한 쿼리문이 떠오르지 않아서 질문드립니다.
-
해결됨모의해킹 실무자가 알려주는, SQL Injection 공격 기법과 시큐어 코딩 : PART 1
[실습6-1]MSSQL ERROR-BASED 공격 실습 관련 질문 내용
안녕하세요. 크리핵티브님 MSSQL에 대한 Error-based 공격 실습 관련 질문 사항이 발생해서 질문 드리게 되었습니다.Injection 공격 검증을 할 때 사용하는 쿼리문 내용 중 test%' and '%'=' 구문이 있는데 이런 구문이 있는 이유가 index.php 의 내용을 보면 아래와 같은 코드로 만들어져서 있는 것으로 알고 있습니다.[index.php의 일부 코드](생략) $query = "select * from {$tb_name}"; } else { if($search_type == "all") { $query = "select * from {$tb_name} where title like '%{$keyword}%' or writer like '%{$keyword}%' or content like '%{$keyword}%'"; } else { $query = "select * from {$tb_name} where {$search_type} like '%{$keyword}%'"; }--> 즉 우리가 입력한 test%' and '%'=' 은 if문 안에 들어가서 $query의 '%{$keyword}%'에 들어가게 되어서 최종적으로는 $query = "select * from board..tb_board where '%test%' and '%'='%'"; 이 되어서 test 이름이 들어간 모든 게시물을 보여주는 것으로 알고 있습니다. 공격 검증에 사용되는 test%' and '%'=' 구문은 현재 우리가 index.php의 $query의 내용을 알고 있어서 이렇게 test%' and '%'=' 작성 할 수 있지만 실제 실무에서도 이게 활용이 가능한지 궁금합니다.혹시 대부분의 실무 환경도 $query = "select * from {$tb_name} where {$search_type} like '%{$keyword}%'"; 같은 구조로 개발이 되어서 대부분의 실무 환경에도 test%' and '%'=' 구문을 공격 검증 페이로드로 사용할 수 있는지 여부가 궁금합니다.
-
미해결모의해킹 실무자가 알려주는, SQL Injection 공격 기법과 시큐어 코딩 : PART 1
데이터타입이 문자형인 경우의 Inline-Query에서
데이터 타입이 문자형인 경우 iN-LINE QUERY에서 SELECT * FROM member WHERE user_id='hacker' and 1=1 and '1'='1' 반드시 1=1이 들어가야 한다고 하셨는데, SELECT * FROM member WHERE user_id='hacker' and '1'='1' 이렇게 페이로드를 작성하면 안되나요?!