Section IV. 웹 취약점 분석도구의 활용 23. 개요 24. 파로스 소스 커스터마이징을 통한 취약점 분석 - 설치 및 구성 - 탐지항목(룰 종류) - 백업 파일 찾기 - 사설 IP 검색 로직 찾기 - 디렉토리 노출 찾기 - IIS 기본 파일 찾기 - 파라미터 변조 - SQL Injection Fingerprinting - 소스 컴파일 - SQL Injection 탐지 패턴 추가 - 주민등록번호 검색 기능 추가
학습 포인트 1. 파로스(웹 스캐너)의 구성요소에 대한 이해 2. 파로스의 룰 구현 원리에 대한 이해 3. 파로스 룰 확장(응용)
23. 개요 웹 사이트 개발 시 보안을 고려하지 않고 개발하는 경우 수정에 많은 비용 발생 버그 탐지 시점(개발 이후 운영단계) SDLC 개발공정상의 버그 수정비용
23. 개요 요구사항 수렴 요구사항 및 분석 그리고 개발자 교육 디자인/설계 개별 객체 모듈과 보안 모듈 연동 설계, 보안 체크 리스트 작성, 보안 개발 지침 작성 개발 보안체크 리스트와 보안개발 지침참조, 코드 리뷰 테스트 코드 리뷰(White Box Test), 체크 리스트 검증 * White Box Test : 소스 검사 운영 및 유지보수 코드 리뷰(Black Box Test), 보안 솔루션 운영, 보안 패치 * Black Box Test : 스캐너 검사
24. 파로스 소스 커스터마이징을 통한 취약점 분석 01. 설치(*src.zip 받고, 압축해제)
24. 파로스 소스 커스터마이징을 통한 취약점 분석 02. 구성 Crawl html 태그 정보를 통해 디렉토리 구조와 파일형태를 수집하는 모듈 Scan Crawl에서 수집된 정보를 이용하여 패턴을 조작하여 전송하는 모듈 (3) Report 결과를 출력하는 모듈 (4) Proxy 웹 브라우저와 스캐너를 Proxy로 연동시키는 모듈
24. 파로스 소스 커스터마이징을 통한 취약점 분석 02. 구성 - Crawl
24. 파로스 소스 커스터마이징을 통한 취약점 분석 02. 구성 - Scan ○ 패턴 삽입 : 확인된 디렉토리에 보유한 패턴 전송 / /admin.jsp , /manual.php, /menu.asp ○ 패턴 조합 : 수집된 파라미터 값 조작 및 전송 Crawl 단계에서 수집된 URL : /bbs/bbs.asp?id=1000 Scan 단계에서 전송되는 패턴 : /bbs/bbs.asp?id=1000'INJECTED_PARAM ○ 내부 데이터 검사 : Crawl 단계에서 수집된 정보만을 활용 /bbs.jsp, /bbs1.jsp, /bbs2.jsp
24. 파로스 소스 커스터마이징을 통한 취약점 분석 02. 구성 – Scan(내부 데이터 검사 사례) Response Header 원하는 문자열 포함 여부 확인 ( 사설 IP ) Response Data
24. 파로스 소스 커스터마이징을 통한 취약점 분석 03. 탐지항목 - UI 점검 항목 테스트 항목
Information gathering 24. 파로스 소스 커스터마이징을 통한 취약점 분석 03. 탐지항목 – 룰 분류 분류 항목 설명 Information gathering Obsolete file 백업 파일 찾기 Private IP Disclosure 사설 IP 찾기 Session ID in URL rewrite 세션 ID 재사용 Obsolete file extended check 확장형 백업 파일 찾기 Client Browser Password Autocomplete in browser 패스워드 완성 태그 찾기 Secure page broswer cache 웹 브라우저 데이터 저장 태그 찾기 Server security Directory browsing 디렉터리 리스팅 IIS default file IIS 기본 파일 찾기 Cold Fusion default file Cold Fusion 기본 파일 찾기 Macromedia JRun default file Macromedia Jrun기본 파일 찾기 Tomcat source file disclosure Tomcat 기본 파일 찾기 BEA Weblogic example files BEA Weblogic 기본 파일 찾기 IBM WebSphere default files IBM Websphere 기본 파일 찾기 Lotus Domino default files Lotus Domino기본 파일 찾기 Injections SQL Injection Fingerprinting 500번 에러 페이지 찾기 CRLF Injection CRLF 삽입 찾기 Server side include SSI 값 변조 Cross site scripting 크로스사이트스크립트 찾기 1 Cross site scripting without brackets 크로스사이트스크립트 찾기 2 Parameter tampering 크로스사이트스크립트 찾기 3 SQL Injection Blind SQL Injection 찾기 MS SQL Injection Enumeration MS SQL Injection 찾기
24. 파로스 소스 커스터마이징을 통한 취약점 분석 03. 탐지항목 항목 설명 점검 방식 Obsolete file 백업 파일 찾기 패턴 조합 방식 Private IP Disclosure 사설 IP 찾기 내부 데이터 검색 방식 Session ID in URL rewrite 세션 ID 재 사용 Obsolete file extended check 확장형 백업 파일 찾기 Password Autocomplete in browser 패스워드 완성 태그 찾기 Secure page broswer cache 웹 브라우저 데이터 저장 태그 찾기 Directory browsing 디렉터리 리스팅 신규 패턴 전송 방식 IIS default file IIS 기본 파일 찾기 Cold Fusion default file Cold Fusion 기본 파일 찾기 Macromedia JRun default file Macromedia Jrun기본 파일 찾기 Tomcat source file disclosure Tomcat 기본 파일 찾기 BEA Weblogic example files BEA Weblogic 기본 파일 찾기 IBM WebSphere default files IBM Websphere 기본 파일 찾기 Lotus Domino default files Lotus Domino기본 파일 찾기 SQL Injection Fingerprinting 500번 에러 페이지 찾기 CRLF Injection CRLF 삽입 찾기 Server side include SSI 값 변조 Cross site scripting 크로스사이트스크립트 1 Cross site scripting without brackets 크로스사이트스크립트 2 Parameter tampering 크로스사이트스크립트 3 SQL Injection Blind SQL Injection 찾기 MS SQL Injection Enumeration MS SQL Injection 찾기
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 ○ 소스 상단 : 함수 및 패턴 선언 ○ 소스 상단 : 함수 및 패턴 선언 ○ 소스 중간 : 리포트 내용(제목, 해결책 등) 및 패턴 전송 부분 선언 ○ 소스 하단 : 탐지근거 선언
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 소스 상단 부분
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 소스 중간 부분 리포트 내용 패턴 전송 로직
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 소스 하단 부분
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 백업 파일 찾기
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 백업 파일 찾기(계속) C:\paros-3.2.13-src\paros \src\org\parosproxy\paros\core\scanner\plugin\TestObsoleteFile.java package org.parosproxy.paros.core.scanner.plugin; // 소스의 위치 import java.io.IOException; // 입출력 관련 함수 import java.util.regex.Pattern; // 정규표현식 함수 import org.apache.commons.httpclient.URI; // URI표현 함수 import org.parosproxy.paros.core.scanner.AbstractAppPlugin; // 백업파일 찾기를 지원하는 클래스 정의 import org.parosproxy.paros.core.scanner.Alert; // 결과물에 대한 위험도 정의 import org.parosproxy.paros.network.HttpMessage; // HTTP Protocol 작성 함수
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 백업 파일 찾기(계속) 1 public class TestObsoleteFile extends AbstractAppPlugin { 2 private final static String[ ] staticSuffixList = { 3 ".old", 4 ".bak", 5 ".inc" 6 }; 7 private static final String[] staticAppendixList = { 8 "~" 9 };
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 백업 파일 찾기(계속) 자체적으로 작성한 에러 페이지 1 private static final Pattern patternNotFound = Pattern.compile("(\\bNot\\sfound\\b)|(\\b404\\b)", PATTERN_PARAM); 자체적으로 작성한 에러 페이지 기본 에러 페이지
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 백업 파일 찾기(계속) 1 public int getId() { return 00002; } 2 public String getName() { // 제목 return "Obsolete file"; 3 public String getDescription() { // 취약점 설명 return "Miscellenous include files, backup, unused or obsolete files exist as indicated. If these files contain program source, information such as server logic or ODBC/JDBC user ID and passwords may be revealed since these file extension may not be processed by the web server."; 4 public String getSolution() { // 취약점 해결책 return "Remove backup, unused or obsolete files. For include files, carefully choose the suffix to prevent information disclosure.";
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 백업 파일 찾기(계속) getdescription() getName() getsolution() getreference()
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 백업 파일 찾기(계속) public int getCategory() { return 0; } C:\paros-3.2.13-src\paros\src\org\parosproxy\paros\core\scanner\Category.java public class Category { 2 public static final int INFO_GATHER = 0; 3 public static final int BROWSER = 1; 4 public static final int SERVER = 2; 5 public static final int MISC = 3; 6 public static final int INJECTION = 4; 7 private static String[] names = { 8 "Information gathering", 9 "Client browser", 10 "Server security", 11 "Miscellenous", 12 "Injection"
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 백업 파일 찾기(계속) 1. public void scan() 함수 호출 public void scan() { for (int i=0; i<staticSuffixList.length; i++) { // for 반복문으로 백업패턴 처음부터 끝까지 카운트 try { testSuffix(staticSuffixList[i], false); testSuffix(staticSuffixList[i], true); // testSuffix() 함수 호출 인자값은 2개(staticSuffixList[i], false/true) 가 넘어감 2 public void testSuffix() 함수 호출 private void testSuffix(String suffix, boolean replaceSuffix) -------- --------------- 인자값1 인자값2
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 백업 파일 찾기(계속) private void testSuffix(String suffix, boolean replaceSuffix) throws IOException { HttpMessage msg = getNewMsg(); // 패턴 전송을 위한 http 생성 URI uri = msg.getRequestHeader().getURI(); // getURI()를 통해 Crawl단계에서 수집된 정보를 uri 변수에 저장 // getURI() http://www.xxx.com/bbs/bbs.asp?id=1 String path = uri.getPath(); // getPath()를 통해 디렉토리와 페이지 정보만 가져옴(파라미터 제외) // getPath() /bbs/bbs.asp if (path == null || path.equals("")) { // 정보가 없다면 skip return; }
// path = bbs/bbs.asp( 파일 백업 ) 24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 백업 파일 찾기(계속) testSuffix(staticSuffixList[i], false); testSuffix(staticSuffixList[i], true); private void testSuffix(String suffix, boolean replaceSuffix) throws IOException { { … if (replaceSuffix) { int pos = path.lastIndexOf("."); if (pos > -1) { path = path.substring(0, pos); // /bbs/bbs.asp일 경우 // path = /bbs/bbs까지만(디렉토리 백업) } path = path + suffix; true일 경우 False일경우 // path = bbs/bbs.asp( 파일 백업 )
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 백업 파일 찾기(계속) testSuffix(staticSuffixList[i], false); testSuffix(staticSuffixList[i], true); private void testSuffix(String suffix, boolean replaceSuffix) throws IOException { String path = uri.getPath(); /bbs/bbs.asp if (replaceSuffix) /bbs/bbs.asp path = path + suffix; /bbs/bbs.bak path = path + suffix; /bbs/bbs.asp.bak replaceSuffix = true replaceSuffix = False 디렉토리 혹은 파일이름에 백업 확장자 삽입 파일 확장자에 백업 확장자 삽입
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 백업 파일 찾기(계속) uri.setPath(path); // 백업 확장자 붙인 URI 세팅 msg.getRequestHeader().setURI(uri); // HTTP 프로토콜 생성(백업확장자 붙인 URI) sendAndReceive(msg); // HTTP 프로토콜 전송 및 수신 if (!isFileExist(msg)) { // 수신 헤더 값을 보아서 파일이 존재하는 경우 return; } bingo(Alert.RISK_LOW, Alert.WARNING, uri.toString(), "", "", msg); // bingo()함수 호출을 통해 리포트로 출력
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 사설 IP 검색 사설 IP주소는 왜 필요한가? - IPV4 주소의 고갈로 인해 할당해 줄 주소가 없다.
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 사설 IP 검색 소스: C:\paros-3.2.13-src\paros \src\org\parosproxy\paros\core\scanner\plugin\TestInfoPrivateAddressDisclosure.java
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 사설 IP 검색(계속) * 사설 IP 주소범위 public static final Pattern patternPrivateIP = Pattern.compile( "(10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3} | 172\\.\\d{2,2}\\.\\d{1,3}\\.\\d{1,3} | 192\\.168\\.\\d{1,3}\\.\\d{1,3})", PATTERN_PARAM); * 사설 IP 주소범위 10.0.0.0 - 10.255.255.255 (10/8 prefix) 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 사설 IP 검색(계속) public int getId() { return 00003; } public String getName() { return "Private IP disclosure"; public String[] getDependency() { return null; public String getDescription() { return "Private IP such as 10.x.x.x, 172.x.x.x, 192.168.x.x is found in the HTTP response body. This can be used in exploits on internal system."; public int getCategory() { return Category.INFO_GATHER; public class Category { 2 public static final int INFO_GATHER = 0; 3 public static final int BROWSER = 1; 4 public static final int SERVER = 2; 5 public static final int MISC = 3; 6 public static final int INJECTION = 4; 7 private static String[] names = { 8 "Information gathering", 9 "Client browser", 10 "Server security", 11 "Miscellenous", 12 "Injection"
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 사설 IP 검색(계속) public void scan() { HttpMessage msg = getBaseMsg(); // 기존 정보이용인 경우 // HttpMessage msg = getNewMsg(); 신규 프로토콜인 경우 String txtBody = msg.getResponseBody().toString(); // 수신정보중 body만 가져와 txtBody에 저장 String txtFound = null; // txtFound 변수 초기화 Matcher matcher = patternPrivateIP.matcher(txtBody); // 사설 IP 정의한 패턴과 비교 while (matcher.find()) { // 패턴 매치결과가 존재한다면 txtFound = matcher.group(); if (txtFound != null) { bingo(Alert.RISK_LOW, Alert.WARNING, null, null, txtFound, msg); }
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 디렉토리 노출 디렉토리 노출(Directory Browsing)인 경우 어떻게 분석할 수 있는가?
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 디렉토리 노출(계속) 소스: C:\paros-3.2.13-src\paros \src\org\parosproxy\paros\core\scanner\plugin\TestDirectoryBrowsing.java (패턴비교) 디렉토리 노출 검색 패턴 전송
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 디렉토리 노출(계속) public class TestDirectoryBrowsing extends AbstractAppPlugin { private final static Pattern patternIIS = Pattern.compile("Parent Directory", PATTERN_PARAM); private final static Pattern patternApache = Pattern.compile("\\bDirectory Listing\\b.*(Tomcat|Apache)", PATTERN_PARAM); private final static Pattern patternGeneralDir1 = Pattern.compile("\\bDirectory\\b", PATTERN_PARAM); private final static Pattern patternGeneralDir2 = Pattern.compile("[\\s<]+IMG\\s*=", PATTERN_PARAM); private final static Pattern patternGeneralParent = Pattern.compile("Parent directory", PATTERN_PARAM);
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 디렉토리 노출(계속) public class Category { 2 public static final int INFO_GATHER = 0; 3 public static final int BROWSER = 1; 4 public static final int SERVER = 2; 5 public static final int MISC = 3; 6 public static final int INJECTION = 4; 7 private static String[] names = { 8 "Information gathering", 9 "Client browser", 10 "Server security", 11 "Miscellenous", 12 "Injection" public int getId() { return 00001; } public String getName() { return "Directory browsing"; public String getDescription() { return "It is possible to view the direc"; public int getCategory() { return Category.SERVER; public String getSolution() { return "Disable directory browsing not induce risks."; public String getReference() { String ref = "For IIS, turn off directory browsing.\r\n" + "For Apache, use the 'Options -Indexes“;
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 디렉토리 노출(계속) private void checkIfDirectory(HttpMessage msg) throws URIException { URI uri = msg.getRequestHeader().getURI(); // crawl 데이터 가져오기 http://www.xxx.com/bbs/bbs.asp?id=1 uri.setQuery(null); // 불필요한 파라미터 값 제거 http://www.xxx.com/bbs/bbs.asp String sUri = uri.toString(); // uri 가져오기 if (!sUri.endsWith("/")) { // 가져온 값 끝이 / 로 끝나지 않는 경우 sUri = sUri + "/"; // / 를 강제로 붙임 } msg.getRequestHeader().setURI(new URI(sUri, true)); // / 를 붙인 url 헤더 값을 만들어 다시 넣음
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 디렉토리 노출(계속) checkIfDirectory() /bbs/ /bbs/bbs.asp/ /dir1/ public void scan() { boolean result = false; // result 변수에 false로 선언(값 없음으로 시작 HttpMessage msg = getNewMsg(); // 신규 http 프로토콜 생성 int reliability = Alert.WARNING; // 취약점 결과 수준을 warning 으로 초기화 try { checkIfDirectory(msg); // checkIfDirectory()함수 호출 writeProgress(msg.getRequestHeader().getURI().toString()); // 만든 header를 다시 불러오기 sendAndReceive(msg); // 데이터 전송 및 수신
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 디렉토리 노출(계속) if (msg.getResponseHeader().getStatusCode() != HttpStatusCode.OK) { return; } if (matchBodyPattern(msg, patternIIS, null)) { result = true; } else if (matchBodyPattern(msg, patternApache, null)) { } else if (matchBodyPattern(msg, patternGeneralParent, null)) { reliability = Alert.SUSPICIOUS; 수신된 URL의 응답코드 OK = 200번 수신된 URL의 Body 정의된 IIS 디렉토리 노출 패턴 동일한 패턴이 있다면 Result()함수 호출 if (result) { bingo(Alert.RISK_MEDIUM, reliability, msg.getRequestHeader().getURI().toString(), "", "", msg); }
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – IIS 기본 파일 찾기 소스: C:\paros-3.2.13-src\paros \src\org\parosproxy\paros\core\scanner\plugin\TestDefaultFileIIS.java
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – IIS 기본 파일 찾기(계속) 일반 룰 패턴 정의 리포트 출력 정의 패턴 송, 수신 정의 판단 근거 정의 기본 파일 찾기 룰 패턴 정의 리포트 출력 정의 다른 파일에서 송,수신 및 판단근거 public class TestDefaultFileIIS extends AbstractDefaultFilePlugin {
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – IIS 기본 파일 찾기(계속) public class TestDefaultFileIIS extends AbstractDefaultFilePlugin { 일반 룰 IIS 기본패턴 찾기 룰 등
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – IIS 기본 파일 찾기(계속) public int getId() { return 20000; } public String getName() { return "IIS default file"; public String getDescription() { return "Microsoft IIS 4.0, 5.0 or 6.0 default files are found."; public int getCategory() { return Category.SERVER; public String getSolution() { return "Remove default files and virtual directories."; public class Category { 2 public static final int INFO_GATHER = 0; 3 public static final int BROWSER = 1; 4 public static final int SERVER = 2; 5 public static final int MISC = 3; 6 public static final int INJECTION = 4; 7 private static String[] names = { 8 "Information gathering", 9 "Client browser", 10 "Server security", 11 "Miscellenous", 12 "Injection"
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – IIS 기본 파일 찾기(계속) public void init() { super.init(); // 슈퍼 클래스 createURI(); } C:\paros-3.2.13-src\paros\src\org\parosproxy\paros\core\scanner \AbstractDefaultFilePlugin.java 에서 처리 즉 다른 소스 내용(AbstractDefaultFilePlugin.java)을 호출하기 위해서는 super class(슈퍼 클래스)를 선언
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – IIS 기본 파일 찾기(계속) private void createURI() { // 패턴 선언 addTest("/","iisstart.asp,postinfo.html,_vti_inf.html"); addTest("msadc","msadcs.dll"); addTest("_vti_bin", "fpcount.exe,shtml.dll"); addTest("_vti_bin/_vti_adm", "admin.dll"); addTest("_vti_bin/_vti_aut", "author.dll");
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 파라미터 변조 로직 소스: C:\paros-3.2.13-src\paros \src\org\parosproxy\paros\core\scanner\plugin\TestParameterTamper.java
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 파라미터 변조 로직(계속) private static String[] PARAM_LIST = {"", "", "@", "+", AbstractPlugin.getURLDecode("%00") , "|"};
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 파라미터 변조 로직(계속) * 에러 문자열 정의( 패턴 전송 후 에러 발생 여부를 확인하기 위한 에러 문자열 ) private static Pattern patternErrorJava1 = Pattern.compile("javax\\.servlet\\.\\S+", PATTERN_PARAM); private static Pattern patternErrorJava2 = Pattern.compile("invoke.+exception|exception.+invoke", PATTERN_PARAM); private static Pattern patternErrorVBScript = Pattern.compile("Microsoft(\\s+| )*VBScript(\\s+| )+error", PATTERN_PARAM); private static Pattern patternErrorODBC1 = Pattern.compile("Microsoft OLE DB Provider for ODBC Drivers.*error", PATTERN_PARAM); private static
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 파라미터 변조 로직(계속) public class Category { 2 public static final int INFO_GATHER = 0; 3 public static final int BROWSER = 1; 4 public static final int SERVER = 2; 5 public static final int MISC = 3; 6 public static final int INJECTION = 4; 7 private static String[] names = { 8 "Information gathering", 9 "Client browser", 10 "Server security", 11 "Miscellenous", 12 "Injection" public int getId() { return 40010; } public String getName() { return "Parameter tampering"; public String getDescription() { String msg = "Certain parameter caused error page or Java stacktrace to be displayed. further exploit."; return msg; public int getCategory() { return Category.INJECTION;
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 파라미터 변조 로직(계속) public void scan(HttpMessage msg, String param, String value) { String bingoQuery = null; // 초기화 HttpMessage normalMsg = getNewMsg(); // 저장된 URL 정보 불러오기 try { sendAndReceive(normalMsg); // 변조없이 저장된 URL 정보 전송 및 수신 } catch (Exception e) { return; } if (normalMsg.getResponseHeader().getStatusCode() != HttpStatusCode.OK) { /bbs/bbs.asp?id=1 - Param : id - Value : 1 200번이 아닌 경우
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 파라미터 변조 로직(계속) private static String[] PARAM_LIST = {"", "", "@", "+", AbstractPlugin.getURLDecode("%00") , "|"}; for (int i=0; i<PARAM_LIST.length; i++) { msg = getNewMsg(); // 저장된 URL 정보 불러오기 if (i==0) { // 변조할 패턴이 없다면 bingoQuery = setParameter(msg, null, null); } else { // 변조할 패턴이 존재한다면 bingoQuery = setParameter(msg, param, PARAM_LIST[i]); try { /bbs/bbs.asp?id=1 - Param : id - Value : @, +
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 파라미터 변조 로직(계속) 변조된 파라미터 setParameter(msg, param, PARAM_LIST[i]); 변조된 파라미터 ( id=@ ) sendAndReceive(normalMsg); 원래의 url 파라미터 ( id=1 ) 같다면 변화가 없다. sendAndReceive(msg); if (checkResult(msg, bingoQuery, normalMsg.getResponseBody().toString())) { return;
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 파라미터 변조 로직(계속) private boolean checkResult(HttpMessage msg, String query, String normalHTTPResponse) { StringBuffer sb = new StringBuffer(); // 공간 할당(수신된 body정보 담을 공간) if (msg.getResponseHeader().getStatusCode() != HttpStatusCode.OK && !HttpStatusCode.isServerError(msg.getResponseHeader().getStatusCode())) { // 200번이 아니거나, 500번이 아닌 경우 ( 에러 문자열이 발생하는 조건 ) return false; } if (msg.getResponseBody().toString().equals(normalHTTPResponse)) { // 변조된 파라미터를 던지거나, 정상적인 파라미터를 던지거나 동일한 body가 수신
24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – 파라미터 변조 로직(계속) if (matchBodyPattern(msg, patternErrorJava1, sb) && matchBodyPattern(msg, patternErrorJava2, null)) { // 패턴이 있다면 bingo(Alert.RISK_MEDIUM, Alert.WARNING, null, (query == null || query.length() == 0)? "nil" : query, sb.toString(), msg); // 리포트 출력 return true; } else if (matchBodyPattern(msg, patternErrorVBScript, sb) || matchBodyPattern(msg, patternErrorODBC1, sb) // 기타 정의된 패턴이 있다면
04. 로직분석 – SQL Injection 탐지 로직 24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – SQL Injection 탐지 로직 소스: C:\paros-3.2.13-src\paros \src\org\parosproxy\paros\core\scanner\plugin\ TestInjectionSQLFingerprint.java
04. 로직분석 – SQL Injection 탐지 로직(계속) 24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – SQL Injection 탐지 로직(계속) * 삽입할 공격 패턴 정의 private static final String MSSQL_DELAY_1 = "';waitfor delay '0:0:15';--"; private static final String MSSQL_DELAY_2 = ";waitfor delay '0:0:15';--"; private static final String SQL_BLIND_MS_INSERT = ");waitfor delay '0:0:15';--"; private static final String SQL_BLIND_INSERT = ");--"; private static final String SQL_CHECK_ERR = "'INJECTED_PARAM"; * 탐지할 에러 문자열 정의 private static final Pattern patternErrorODBC1 = Pattern.compile("Microsoft OLE DB Provider for ODBC Drivers.*error", PATTERN_PARAM); private static final Pattern patternErrorODBC2 = Pattern.compile("ODBC.*Drivers.*error", PATTERN_PARAM);
04. 로직분석 – SQL Injection 탐지 로직(계속) 24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – SQL Injection 탐지 로직(계속) public class Category { 2 public static final int INFO_GATHER = 0; 3 public static final int BROWSER = 1; 4 public static final int SERVER = 2; 5 public static final int MISC = 3; 6 public static final int INJECTION = 4; 7 private static String[] names = { 8 "Information gathering", 9 "Client browser", 10 "Server security", 11 "Miscellenous", 12 "Injection" public String getDescription() { String msg = "SQL injection may be possible."; return msg; } public int getCategory() { return Category.INJECTION;
04. 로직분석 – SQL Injection 탐지 로직(계속) 24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – SQL Injection 탐지 로직(계속) public void scan(HttpMessage baseMsg, String param, String value) { try { scanMSSQL(baseMsg, param, value); // scanMSSQL 함수 호출 } catch (Exception e) { e.printStackTrace(); }
04. 로직분석 – SQL Injection 탐지 로직(계속) 24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – SQL Injection 탐지 로직(계속) scanMSSQL(baseMsg, param, value); // scanMSSQL 함수 호출 public void scanMSSQL(HttpMessage baseMsg, String param, String value) throws HttpException, IOException { HttpMessage msg = getNewMsg(); // crawl된 url 가져오기 newQuery = setParameter(msg, param, value+SQL_CHECK_ERR); // bbs.asp?id=1을 bbs.asp?id=1'INJECTED_PARAM lastTime = System.currentTimeMillis(); // 현재 시스템 시간 저장 sendAndReceive(msg); // 전송 및 수신 defaultTimeUsed = System.currentTimeMillis() - lastTime; // 현재 시스템 시간 저장 mResBodyError = msg.getResponseBody().toString(); // body정보 저장 if (checkResult(msg, newQuery)) { // 수신 body를 통해 SQL Injection 여부를 판단 return; }
04. 로직분석 – SQL Injection 탐지 로직(계속) 24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – SQL Injection 탐지 로직(계속) newQuery = setParameter(msg, param, value + MSSQL_DELAY_1); // bbs.asp?id=';waitfor delay '0:0:15';-- lastTime = System.currentTimeMillis(); // 현재 시스템 시간 저장 sendAndReceive(msg); // 전송 및 수신 timeUsed = System.currentTimeMillis() - lastTime; // 현재 시스템 시간 저장 if (checkMSTimeResult(msg, newQuery, defaultTimeUsed, timeUsed)) { // 시간 차이를 통해 sql injection여부 판단 return; } newQuery = setParameter(msg, param, value + MSSQL_DELAY_2); …중간 생략 if (checkMSTimeResult(msg, newQuery, defaultTimeUsed, timeUsed)) { // 시간 차이를 통해 sql injection여부 판단
04. 로직분석 – SQL Injection 탐지 로직(계속) 24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – SQL Injection 탐지 로직(계속) testMSBlindINSERT(msg, param, value); // testMSBlindINSERT()함수 호출 private void testMSBlindINSERT(HttpMessage msg, String param, String value) throws HttpException, IOException { int TRY_COUNT = 5; sbInsertValue = new StringBuffer(); for (int i=0; i<TRY_COUNT; i++) { if (i>0) { sbInsertValue.append(",'0'"); } newQuery = setParameter(msg, param, value + "'" + sbInsertValue.toString() + SQL_BLIND_MS_INSERT); sendAndReceive(msg); 원본 : id=1 변조 : id=1);waitfor delay '0:0:15';-- 변조 : id=1,'0',);waitfor delay '0:0:15';-- 변조 : id=1,'0','0');waitfor delay '0:0:15';-- 변조 : id=1,'0','0','0');waitfor delay '0:0:15';-- 변조 : id=1,'0','0','0','0');waitfor delay '0:0:15';--
04. 로직분석 – SQL Injection 탐지 로직(계속) 24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – SQL Injection 탐지 로직(계속) sendAndReceive(msg); 전송 및 수신 if (checkMSTimeResult(msg, newQuery, defaultTimeUsed, msg.getTimeElapsedMillis())) // 탐지 근거 검사 { return; }
04. 로직분석 – SQL Injection 탐지 로직(계속) 24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – SQL Injection 탐지 로직(계속) private boolean checkResult(HttpMessage msg, String query) { StringBuffer sb = new StringBuffer(); // 수신 body 저장할 버퍼 할당 boolean isSqlError = false; // false 값으로 초기화 if (msg.getResponseHeader().getStatusCode() != HttpStatusCode.OK && !HttpStatusCode.isServerError(msg.getResponseHeader().getStatusCode())) { // 200번이 아니며 500번이 아니면 sql injection이 아니라고 판단 return false; } if (matchBodyPattern(msg, patternErrorODBC1, sb) // 수신 body에 에러 문자열이 있다면 || matchBodyPattern(msg, patternErrorODBC2, sb)) { isSqlError = true;
04. 로직분석 – SQL Injection 탐지 로직(계속) 24. 파로스 소스 커스터마이징을 통한 취약점 분석 04. 로직분석 – SQL Injection 탐지 로직(계속) private boolean checkMSTimeResult(HttpMessage msg, String query, long defaultTimeUsed, long timeUsed) { if (timeUsed > defaultTimeUsed + TIME_SPREAD - 500) { getKb().add(msg.getRequestHeader().getURI(), "sql/mssql", new Boolean(true)); return true; } return false; 15초 사전 정의 패턴삽입후 수신된 시스템 시간 패턴삽입전 시스템 시간 결국 가장 이상적인 취약점 상황이 발생될 경우, 대략 다음과 같은 값을 가져 SQL Injection 취약점으로 판단할 수 있을 것이다. if (timeUsed(16초) > defaultTimeUsed(0.5초) + TIME_SPREAD(15초) – 0.5) if ( 16000 > 500 + 15000 – 500 )
24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일 ANT(자바 소스 파일 컴파일러) 자바 개발 시 JDBC드라이버, Servlet, JAR 등의 여러 패키지를 사용하게 되는데, 이를 컴파일하기 위해서는 관련 패키지의 위치를 환경변수에 설정하거나, 윈도우 코멘드 쉘 창에서 클래스 위치를 나열해야 함 이러한 작업을 간소화게 처리할 수 있는 것이 Ant의 build.xml(C의 make와 유사)
24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일(계속) http://ant.apache.org/bindownload.cgi http://ftp.kaist.ac.kr/pub/Apache/ant/binaries/apache-ant-1.7.0-bin.zip
24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일(계속) jdk(java develop kit) apache-ant
24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일(계속) Build.xml doesn’t exist!
24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일(계속) 컴파일 위치 C:\paros-3.2.13-src\paros\build
24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일(계속) ANT 빌드 파일의 루트 엘리먼트는 <project/>이며 <project/> - 하위에는 빌드 과정에서 사용할 속성을 정의할 수 있는 <property/> 엘리먼트 - 엘리먼트와 각 Task에서 사용할 경로 정보를 포함하는 <path/> 엘리먼트 - 작업을 수행하는 <target/>엘리먼트를 사용하게 된다. < project name="projectName" default="first" basedir="."> - name: 프로젝트 이름을 의미한다. - default: 기본 작업을 수행을 하고자 할 때 사용한다. - basedir: 프로젝트에 대한 기준 폴더를 지정하며, 현재 폴더는 특수문자(.) 사용 < property name="src.dir" value="${basedir}/src" /> < property name="classes.dir" value="${basedir}/classes" /> - property는 변수를 의미한다. - name: 변수명을 의미한다. - value: 변수값을 의미한다. (변수를 호출할 때 ${변수명} 으로 사용한다.)
24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일(계속) - Ant를 실행할 위치는 어디인가? - 최종 결과물(실행파일)은 어디에 생성되는가?
05. 컴파일(계속) – SQL Injection FingerPrinting 패턴 추가 24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일(계속) – SQL Injection FingerPrinting 패턴 추가 현재 정의된 에러 문자열을 상당히 부족하다. 이를 보강할 필요가 있다.
05. 컴파일(계속) – SQL Injection FingerPrinting 패턴 추가 24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일(계속) – SQL Injection FingerPrinting 패턴 추가 소스: C:\paros-3.2.13-src\paros \src\org\parosproxy\paros\core\scanner \plugin\TestInjectionSQLFingerprint.java private static final Pattern patternErrorODBC1 = Pattern.compile("Microsoft OLE DB Provider for ODBC Drivers.*error", PATTERN_PARAM); private static final Pattern patternErrorODBC2 = Pattern.compile("ODBC.*Drivers.*error", PATTERN_PARAM); private static final Pattern patternErrorGeneric = Pattern.compile("JDBC|ODBC|not a valid MySQL|SQL", PATTERN_PARAM); private static final Pattern patternErrorODBCMSSQL = Pattern.compile("ODBC SQL Server Driver", PATTERN_PARAM);
24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일(계속) – SQL Injection FingerPrinting 패턴 추가
05. 컴파일(계속) – SQL Injection FingerPrinting 패턴 추가 24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일(계속) – SQL Injection FingerPrinting 패턴 추가 패턴 추가 시 주의 사항 (1) 고유한 이름으로 패턴을 추가한다. (2) 고유한 이름을 작성한 패턴에 대한 탐지근거를 추가한다. (3) 컴파일을 통해 에러 여부를 확인한다. (4) 신규 패턴 탐지여부를 검사한다.
24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일(계속) – SQL Injection FingerPrinting 패턴 추가
05. 컴파일(계속) – SQL Injection FingerPrinting 패턴 추가 24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일(계속) – SQL Injection FingerPrinting 패턴 추가 초기 페이지에 삽입했던 에러 문자열을 추가하여 무조건 탐지되는 조건을 만들어 정상여부를 검사한다. <html> <head> <LINK rel="stylesheet" type="text/css" href="Style.css"> <title>ORA-00921: unexpected end of SQL command</title> </head>
24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일(계속) – SQL Injection FingerPrinting 패턴 추가
24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일(계속) – 주민등록번호 검사 패턴 추가
05. 컴파일(계속) – 주민등록번호 검사 패턴 추가(계속) 24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일(계속) – 주민등록번호 검사 패턴 추가(계속) * 원본 public static final Pattern patternPrivateIP = Pattern.compile("(10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|172\\.\\d{2,2}\\.\\d{1,3}\\.\\d{1,3}|192\\.168\\.\\d{1,3}\\.\\d{1,3})", PATTERN_PARAM); * 변경 public static final Pattern patternPrivateIP = Pattern.compile("(\\d{6})[\\-|\\s]+([1|2]\\d{6})", PATTERN_PARAM);
24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일(계속) – 주민등록번호 검사 패턴 추가(계속)
05. 컴파일(계속) – 주민등록번호 검사 패턴 추가(계속) 24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일(계속) – 주민등록번호 검사 패턴 추가(계속) <html> <head> <LINK rel="stylesheet" type="text/css" href="Style.css"> <title>111111-1051911</title> </head>
24. 파로스 소스 커스터마이징을 통한 취약점 분석 05. 컴파일(계속) – 주민등록번호 검사 패턴 추가(계속)