💡 공격 수행 시 사전 정보 보유 여부
있다 → 모의 해킹
없다 → 취약점 진단
모의 해킹 | 취약점 진단 |
---|---|
시나리오 기반 | 취약점 별 항목 기반 |
블랙박스 기반 점검 | 화이트박스 기반 점검 |
대상에 대한 정보 하나만을 가지고 공격 수행 | 담당자에게 정보 요청 |
Zero Base → 공격수행 | 담당자 정보 요청 → 정보수령 → 공격수행 |
동적 진단 | 소스코드(정적) 진단 |
서비스 1개 | URL 1개 |
시간 소요 ↑ (최소 1개월-최대 3개월) | 상대적으로 시간 소요 ↓ (짧으면 2-3일, 길면 일주일) |
→ Burp Suite 같은 툴을 활용해 서비스를 진단하는 행위
장점 | 단점 |
---|---|
상대적으로 진단 소요기간 ↓ (1 URL 보통 2-3DAY, 길면 1주-2주) | 누락의 가능성이 상대적으로 ↑ |
→ 동적진단 + 소스코드 진단
→ 소스코드 방법론 (Data Tracing)
결과물에 대한 편차를 최대한 줄이고자 하는 방법
장점 | 단점 |
---|---|
보다 깊고 상세한 진단 가능 | 시간이 오래 걸림 (1 서비스 1 URL 최소 2주-수개월) 진단자의 역량에 따라 결과 산출물의 품질이 달라짐 (편차 심함) |
소스코드를 활용하여 애플리케이션 내 모든 입출력 값에 대에 Data Tracing을 통해 취약점 누락 최소화 및 상세 취약점 점검을 수행하여 보안 수준을 향상하는데 목적을 둔다.
결과 보고서가 자동으로 나옴
Ex. App Scan, Fortify 등
장점 | 단점 |
---|---|
간편, 시간 소요 ↓ | 과/오탐 비율이 큼 솔루션을 잘 이해하고 있는 엔지니어(진단자) 필요 |
비교적 편차가 큰 결과물이 나옴
장점 | 단점 |
---|---|
도출한 취약점에 대한 결과가 명확 | 시간 소요 ↑ 진단자에 대한 결과물 품질의 편차가 큼 |
✅ 기존 동적 진단 대비 깊이 있는 진단 수행 및 다양한 케이스 도출 가능
✅ 개발 언어에 구애받지 않고 모든 분석 가능 (입/출력 Data Tracing)
✅ 취약점 다포인트 리스트 업 방식을 통한 누락률 최소화
✅ 입/출력 분석을 통한 상세 서비스 분석 가능
❎ 진단자의 역량에 따라 산출물 품질 결정
① 대상 서비스 정보 수집/획득
② 소스코드 기반 환경분석(서비스 분석)
③ 입출력 트레이싱(분석)
④ 취약점 분석
⑤ 보고서 작성
⑥ 취약점 조치 및 이행점검 수행
전달받은 모든 소스 코드를 확인하여 분석할 경우 오래 걸리기 때문에 빠른 시간 내 전체 입/출력 데이터를 식별·분석하기 위함
개발 유형 파악을 통해 개발자가 의도한 입출력 및 환경 구성을 빠르게 파악
애플리케이션이 가진 모든 입/출력 파악
키워드 검색 시 넓은 범위의 키워드 검색
개발자 코딩 유형 분석
✅ GET (입력-가져온다), SET(초기화, 변수세팅, 출력), IN(입력), OUT(출력) 등
SQL DB 공통 정의
✅ SELECT / INSERT / UPDATE / DELETE
웹 프레임워크
✅ MVC 구조 파악 (Model, View, Controller, request, response)
입력 → 입력처리 → DB처리 → 출력처리 → 출력
✅ SQL 쿼리 프레임워크
#
쿼리로서 동작 X
✅ SQL 쿼리문에서 변수나 파라미터를 의미
✅ MyBatis에서 자동으로 JDBCPreparedStatement 매개변수로 바인딩
✅ SQL 쿼리가 값을 안전하게 처리하고 SQL Injection 공격 방지 가능
SELECT * FROM users WHERE id = #{userId}
$
쿼리로서 동작
✅ SQL 쿼리문에서 변수나 파라미터를 삽입하는 역할
✅ 단순 문자열로 치환되기 때문에 값이 SQL 쿼리문에 직접 들어감
✅ 동적 쿼리문을 생성하는데 사용 → 보안에 취약
SELECT * FROM users WHERE id = ${userId}
💡 Prepared Statement의 원리
1. 컴파일
✔ PreparedStatement 생성 시 SQL 쿼리는 먼저 데이터베이스 측에서 컴파일
✔ SQL 문장 구조를 데이터베이스가 분석 → 실행 계획 준비2. 파라미터화
✔ SQL 쿼리에 파라미터를 사용하여 값을 넣을 수 있는 형태로 작성
✔ 여기서 파라미터는?
와 같은 Placeholder를 통해 지정3. 재사용
✔ 한번 컴파일 된 후 동일한 쿼리를 반복해서 실행할 때 재사용
✔ 쿼리가 실행될 때마다 파라미터 값만 변경되고 실행 계획은 미리 준비되어 있어 빠른 실행 가능
📢 블랙리스트 검증보다 화이트리스트 검증이 보안 상 👍
String fileName = request.getParameter("P")
BufferedInputStream bis = null
BufferedOutputStream bos = null
FileInputStream fis = null
try {
response.setHeader("Content Disposition", attachment;filename fileName+";")
...
fis = new FileInputStream ("C:/datas/"+fileName);
bis = new BufferedInputStream(fis)
bos = new BufferedOutputStream(response.getOutputStream());
✅ 취약점 명 : Directory Traversal(경로 순회)
✅ 양호/취약 여부 : 취약
✅ 양호일 경우 양호 사유 / 취약할 경우 취약 사유 작성 : 파라미터로 받은 fileName("P")에 대한 검증 없이 파일을 읽고 있기 때문이다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "--//mybatis.org//DTD Mapper 3.0//"http://mybatis.org/dtd /mybatis-3-mapper.dtd">
...
<select id="boardSearch" parameterType ="map" resultType="BoardDto">
select * from tbl_board where title like '%'||#{{keyword}||'%' order by pos asc
</select>
✅ 취약점 명 : SQL Injection
✅ 양호/취약 여부 : 양호
✅ 양호일 경우 양호 사유 / 취약할 경우 취약 사유 작성 : Keyword 입력 값을 mybatis를 사용하여 #로 바인딩 처리를 하고 있어 양호하다.
💡 #로 데이터 바인딩 처리를 할 경우, PreparedStatement와 같은 효과로 데이터를 구조화시켜 쿼리가 변경되지 않도록 함
<% String keyword = request.getParameter ("keyword");%>
keyword = keyword.replaceAll ("&", "&");
keyword = keyword.replaceAll ("<", "<")"
keyword = keyword.replaceAll (">", ">")"
keyword = keyword.replaceAll ("\", """)"
keyword = keyword.replaceAll ("'", "'")"
keyword = keyword.replaceAll ("/"", "/")"
keyword = keyword.replaceAll ("(", "(")"
keyword = keyword.replaceAll (")", ")")"
<%=keyword%>
✅ 취약점 명 : XSS
✅ 양호/취약 여부 : 양호
✅ 양호일 경우 양호 사유 / 취약할 경우 취약 사유 작성 : Keyword 입력 값에 대해 특수 문자 필터링을 하고 있어서 양호하다.
📢 취약일 수도 있는 사유
#은 필터링이 되어있지 않으므로 XSS 공격이 가능해 취약일 수도 있으나 가능성이 희박하다.
if (FileUploadCtr.PostedFile.ContentType == "image/jpeg")
{
if (FileUploadCtr.PostedFile.ContentLength < 102400)
{
string fn = Path.GetFileName(FileUploadCtr.FileName);
FileUploadCtr.SaveAs(Server.MapPath("~/") + fn);
StatusLabel.Text = "Upload status: File uploaded!";
}
else
{
StatusLabel.Text = "Upload Status: The File has to be less than 100 kb!";
}
}
else
{
StatusLabel.Text = "Upload Status: Only JPEG files are accepted!";
}
✅ 취약점 명 : 파일 업로드
✅ 양호/취약 여부 : 양호
✅ 양호일 경우 양호 사유 / 취약할 경우 취약 사유 작성 : 파일 타입(화이트 리스트 기반)과 파일 크기를 검증하고 있기 때문에 양호하다.
📢 취약일 수도 있는 사유
최선의 방법인 확장자(화이트 리스트 기반)에 대한 검증(파일명.jpg)이 없다는 점과 루트에 첨부 파일을 저장한다는 점, 두 가지를 뽑을 수 있다.
💡 악성파일 업로드
최선 → 확장자 검증(화이트 리스트 기반)
차선 → Content-type(파일 타입) | 파일 크기 | 파일의 실행 권한 제어 | 특수 문자 검증
String id = request.getParameter("id");
String bn = request.getParameter("gubun");
String rd = request.getParameter("redirect");
if (id.length() > 0) {
String sql = "select * from customer where customer_id = ? ";
conn = db.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, id);
rs = pstmt.executeQuery();
rs.next();
if ("0".equals(rs.getString(1)) && "01AD".equals(bn)) {
response.sendRedirect(rd);
return;
}
}
✅ 취약점 명 : SQL Injection
✅ 양호/취약 여부 : 양호
✅ 양호일 경우 양호 사유 / 취약할 경우 취약 사유 작성 : PrepareStatement를 사용하며 데이터 바인딩을 통해 동적 쿼리로서 동작되지 않도록 설정하여 사용하고 있으므로 양호하다.
✅ 취약점 명 : Open Redirect / Reflected XSS
✅ 양호/취약 여부 : 취약
✅ 양호일 경우 양호 사유 / 취약할 경우 취약 사유 작성 : redirect 파라미터에 대한 검증 부재로 악의적 사이트로 리다이렉트 또는 Reflected XSS 공격 가능성이 존재하므로 취약하다.
String gubun = request.getParameter("gubun");
...
String sql = "SELECT * FROM board WHERE b_gubun = '"+gubun+"'";
Connection con = db.getConnection();
Statement stmt = con.createStatement();
ResultSet rs = stmt.excuteQuery(sql);
✅ 취약점 명 : SQL Injection
✅ 양호/취약 여부 : 취약
✅ 양호일 경우 양호 사유 / 취약할 경우 취약 사유 작성 : Statement 클래스를 통해 입력 값(gubun)을 보호하여 db 쿼리를 실행하고 있지 않기에 취약하다.
public static void main(String[] args) throws IOException {
List<String> allowedCommands = new ArrayList<String>();
allowedCommands.add("calc");
allowedCommands.add("notepad");
String cmd = args[0];
if (!allowedCommands.contains(cmd)) {
System.err.println("Error");
return;
}
Process ps = null;
try {
ps = Runtime.getRuntime().exec(cmd);
...
✅ 취약점 명 : Command(OS) Injection
✅ 양호/취약 여부 : 양호
✅ 양호일 경우 양호 사유 / 취약할 경우 취약 사유 작성 : 화이트 리스트 기반의 응용 프로그램을 정의하여 양호하다.
string file = Request.QueryString["path"];
if(file != null){
if(file.IndexOf('\\') > -1 || file.IndexOf('/') > -1){
Response.Write("Path Traversal Attrack");
}else{
File.Delete(file);
}
}
✅ 취약점 명 : Directory Traversal(경로 순회) / 경로 조작 및 자원 삽입
✅ 양호/취약 여부 : 양호
✅ 양호일 경우 양호 사유 / 취약할 경우 취약 사유 작성 : 경로 순회 문자열 /와 \를 검증하고 있기에 양호하다.
<%
String Param = request.getParameter("param");
if(param != null){
param = param.replaceAll("<script>","");
param = param.replaceAll("</script>","");
}
%>
...
<p> 제목 : <%=param%></p>
✅ 취약점 명 : XSS / CSRF 공격 가능성
✅ 양호/취약 여부 : 취약
✅ 양호일 경우 양호 사유 / 취약할 경우 취약 사유 작성 : 키워드 필터링을 적용하고 있으나 XSS 공격을 방어하기에 부족한 키워드 수를 가지고 있으므로 취약하다.
<%@taglibprefix="c" url="http://java.sun.com/jsp/jstl/core"%>
<%@tagliburi="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
...
<c:out value="${param.name}" escapeXml="false" />
✅ 취약점 명 : XSS (Reflected XSS)
✅ 양호/취약 여부 : 취약
✅ 양호일 경우 양호 사유 / 취약할 경우 취약 사유 작성 : 출력 값에 대한 필터링을 해주는 escapeXml를 false로 설정했기 때문에 필터링이 되지 않아 취약하다.
💡 <c:out 태그
✔ 입력 값이 아닌 출력 값에 대해 검증
✔ 태그 설정 시 하단 표의 왼쪽에 있는 특수 문자들을 오른쪽과 같은 형태로 자동으로 필터링 처리해주나 escapeXml이 false 상태인 경우, 필터링 처리 적용이 되지 않음에 유의
관리 컨설팅 요소 + 기술 컨설팅 요소
laaS(Infrastructure-as-a-Service) 기반 설정 진단
유휴 리소스 점검
클라우드 사용자 권한 적정 여부 점검
클라우드 관리 컨설팅 요소 점검
① 대상 정보 요청
② 보안 진단 수행
③ 담당자 전달
④ 보고서 작성 및 취약점 리뷰
⑤ 취약점 조치 및 이행점검 수행
6가지 관리 영역(계정, 권한, 접근통제, 데이터, 운영, 정책)에서 클라우드 서비스 및 리소스에 대한 현황을 파악하고 취약점 체크리스트를 기반으로 주요정보의 전자적 침해 행위에 대한 취약점을 분석∙평가하여 존재하는 위협 요소에 대한 보안 대책 제시
💡 Security Group VS Network ACL 차이점 및 공통점
✔ 공통점
IP/Port 기반 접근제어
✔ 범위
Security Group → 인스턴스 기반 IP/Port 접근제어
Network ACL → 네트워크 기반 IP/Port 접근제어