페이지 1 / 9 https://scan.bitscan.co.kr -BMT version 웹취약점점검보고서 점검대상 : testasp.vulnweb.com 주의 : 점검대상웹서버보안에관련된중요한정보를포함하고있습니다. 빛스캔 ( 주 ) https://scan.bitscan.co.kr
페이지 2 / 9 목차 1. 2. 3. 4. 개요웹취약점분류점검결과해결방안 주의사항 : 빛스캔 ( 주 ) 의취약성검사가대상웹사이트의취약점을 100% 진단하지못할가능성이있으며, 원격에서탐지 하는점검의특성상오탐지 (False Positive) 할가능성이있으므로충분한검토과정을거치시기바랍니다. 본보고서를법적또는기타관련된증빙자료로이용하실수없습니다. 모의해킹및웹취약점관련보안솔루션을통해보다안전한웹사이트를위한노력을기울이시기바랍니다. 웹사이트의리뉴얼과같이웹서버의소스가변경된후에는기존에는발견되지않았던취약점이새로출현할 가능성이있으므로정기적으로웹취약점을점검하시기바랍니다. 보고서는검사시점이후에는더이상제공되지않습니다. 즉, 당사는고객님의취약점과같이중요한정보를 저장하지않고자동으로파기합니다. 따라서, 보고서를프린터로인쇄하거나 HTML 파일로저장하여이용하 십시오. 만약, 이러한사유로재검사를요청하시더라도고객의과실로간주하여무상으로제공해드리지않습 니다.
페이지 3 / 9 1. 개요 본문서는빛스캔 ( 주 ) 에서제공되는웹취약점점검서비스를통해점검대상웹서버 (URL) 의웹취약점을점검한결 과보고서입니다. 보고서에서언급된취약점에관련된소스상의취약점을해결하여웹보안을강화할수있습니다. 특히, SQL Injection, XSS 취약점은가장많은피해사례및규모를보이고있으므로반드시해결해야합니다. 보고서에는포티파이웹취약점점검서버가원격에서자동으로웹취약점을진단한내역및발견된취약점의세부 설명그리고취약점을해결하는방안을포함하고있습니다. 2. 웹취약점분류 취약점등급은국내외적으로널리인용되는 OWASP Top 10 및 CVE/Sans Top 25의분류방식과달리웹취약점으로인해발생할수있는기술적, 사업적피해규모에따라당사의기준에따라결정됩니다. 포티파이웹취약점점검서비스가진단하는웹취약점은다음과같이 1단계 ( 가장높음 ) 부터 5단계 ( 가장낮음 ) 까지나누어분류합니다. 등급취약점유형발생할수있는피해상황 1 SQL Injection 데이터베이스에저장된레코드에대한변조, 누출, 삭제. 악성코드유포지로활용가능성. 공격자에의한서버권한획득및내부망침입가능. 웹서버방문자에대한악성코드설치시도로신뢰상실. 2 3 Blind SQL Injection HTTP 500 Error XSS (Cross-Site Scripting) 1등급의취약성과동일한피해유발가능하나공격시간및정보 획득에시간이다소오래걸림. 데이터베이스의정보 ( 테이블이름, 컬럼등등 ) 누출. 공격가능한정보를획득할수있으며에러의상태에따라 1,2 등급에해당되는공격이유발될수있음. Internal Server Error를유발하여장애를일으킬수있음. 세션하이재킹. 피싱에활용될수있으며관리자권한및사용자권한유출. 리디렉션공격. 사용자정보의유출가능성. 4 Exceptional Error 5 Suspicious Error 실행경로의노출가능성. 구성패키지정보노출. 예외처리미비할경우에러의종류에따라 1등급및 2등급의공 격이가능한에러도있음. 취약성여부는확인되지않았지만, 오류로인식될수있는문제 점. 오류가능성이있으며, 추가적인검토가필요한오류. 의심이되는상황에대해리포트되나에러가아닌경우도있음. 주의 : 표에서언급한취약점이외의취약점은진단하지않으며, 이러한취약점을진단하기위해서는별도의솔루 션을이용하십시오.
페이지 4 / 9 3. 점검결과 1) 검사내역 점검대상 testasp.vulnweb.com 점검시각 Mon Sep 5 13:44:11 2011 검사한 URL testasp.vulnweb.com/ 접근횟수 24 분석횟수 9 의심부분 / 검사부분 15 / 15 2) 취약점내역 취약점유형 발견된취약점개수 SQL Injection 2 Blind SQL Injection / HTTP 500 Error 0 XSS(Cross-site Scripting) 0 Exceptional Error 0 Suspicious Error 0 3) 취약점세부내역 취약점유형소스매개변수 URL SQL injection vulnerable /showforum.asp? id [ 보기 ] SQL injection vulnerable /showthread.asp? id [ 보기 ] * 오탐가능성이있으므로문제발생부분을확인하시기바랍니다. 4. 해결방안 발견된취약점은아래링크에서제공하는기술자료를통해해결하시기바랍니다. SQL 인젝션취약점 (1등급) 1) 설명 사용자가입력한값이명령어나 SQL 쿼리구문의일부분으로전달될때발생합니다. 공격자가교묘하게조작한 URL이나매개변수를전송할경우에의도하지않은명령어를실행하거나데이터를조작할수있습니다. 사용자가입력하는값을다음단계로처리하기전에한번더필터링하는과정 (sanitization) 을소스상에서추가함으로써문제점을미리방지할수있습니다.
페이지 5 / 9 2) 해결방안사용자가입력하는값에서는 Single Quote, Double Quote, Slash, Back Slash, Semi-colon, Colon, Plus, Minus, NULL, Carriage Return, New Line 문자열을필터링해야합니다. 추가적으로 Pipe와같이명시적으로사용하지않는문자열이있다면그것또한필터링하는것을추천합니다. JSP, PHP에서는 PrepareStatement라는문자열을미리처리해주는방식을사용할수있으며,.NET에서는매개변수를검증하는별도의처리방법이있습니다. MS-SQL, Oracle 등에서는 SP(Stored Procedure) 를통해서문자열을처리할수있습니다. A) ASP function SQLiFilter1(string) // 가장간단한방법 string=trim(string) string=replace(string, "'", "\'") string=replace(string, """, "\"") end function function SQLiFilter2(string) Dim outstring outstring=string outstring= replace(outstring, """", """) outstring= replace(outstring, "'", "'") outstring= replace(outstring, "/", "/") outstring= replace(outstring, "\", "\") outstring= replace(outstring, ",", ",") outstring= replace(outstring, chr(10), " ") outstring= replace(outstring, chr(13), "<br/>") outstring= replace(outstring, "NULL", "") end function B).NET(C#) 서버컨트롤을사용하여입력값을제한하기위해 RegularExpressionValidator와 RagneValidator와같은 ASP.NET validator 컨트롤을사용합니다. 정형화된 HTML 입력컨트롤을사용하는경우에는 Regex 클래스를사용합니다. // 텍스트박스에서입력값검증 <%@ language="c#" %> <form id="form1" runat="server"> <asp:textbox ID="ID_NO" runat="server"/> <asp:regularexpressionvalidator ID="regexpID_NO" runat="server"/> ErrorMessage=" 주민번호가올바르지않습니다." ControlTovalidate="ID_NO" ValidationExpression="^\d{6-\d{7$" /> </form> // HTML 컨트롤 ( 쿼리매개변수, 쿠키등 ) if (Regex.IsMatch(Request.Cookies["ID_NO"], "^\d{6-\d{7$")) { // 참. 데이터베이스에명령어실행 else { // 거짓. 입력값검증실패 // SQL 구문에서매개변수값검증 using System;
페이지 6 / 9 using System.Text.RegularExpressions; public void CreateNewAccount(string name, string password) { if (!Regex.IsMatch(userID.Text, @"^[a-za-z'./s]{1,40$")) throw new FormatException("ID 가올바르지않습니다 "); // 정상적인처리진행.NET 에서는 parameterized statement 라는방법을통해입력값을제한할수있습니다. // Oracle oracleconnection conn = new OracleConnection(ConnectionString); string sqlstr = "SELECT * FROM users WHERE username=:username" + " AND password=:password"; cmd = new OracleCommand(sqlstr, conn); cmd.parameters.add("username", OracleType.VarChar, 16); cmd.parameters.add("password", OracleType.VarChar, 16); cmd.parameters.value["username"] = username; cmd.parameters.value["password"] = password; reader = cmd.executereader(); C) PHP addslashes() 함수를이용하여특수문자를일반문자로변환합니다. 또는 mysql_real_escape_string() 함수를이용할수있지만, 문자열의크기가 24 바이트라는단점이있습니다. <? function SQLiFilter($string) { $string=addslashes($string); $string=str_replace("--", "- -", $string); $string=str_replace("#", "\#", $string); return $string; // mysql_real_escape_string() 함수를이용하는방법 ( 주의 : 24 바이트까지만지원 ) $name=mysql_real_escape_string($name); $sqlstr="select * FROM users WHERE username = '$name'"; // 처리진행?> D) JSP 자바에서는정규표현식을이용하여입력값을제한합니다. <% page import="java.util.regex.*" %> string query=request.getparameter("db_string"); string querystring; static Pattern escaper=pattern.compile("([^a-za-z0-9.])"); querystring=escaper.matcher(query).replaceall("\\\\$1");
페이지 7 / 9 // 처리진행 preparestatement() 를이용하여입력값에서 SQL 구문을실행할수없도록제한할수있습니다. Connection conn = DriverManager.getConnection(connection_string); String sqlstr = "SELECT * FROM users WHERE username=? AND password=?"; PreparedStatement lookupuser = conn.preparestatement(sqlstr); // 매개변수추가 lookupuser.setstring(1, username); lookupuser.setstring(2, password); rs = lookupuser.executequery(); // 처리진행 오라클데이터베이스를사용하는경우에는다음과같습니다. Import java.sql.*; public class OraclePreparedStatement() { public static void main(string[] args) { String url = "jdbc:oracle:thin:@hostname:1521:orcl"; Try { Class.forName("oracle.jdbc.OracleDriver"); conn = DriverManager.getConnection(url, username, password); String param =......; String sql = "SELECT * FROM users WHERE name=?"; PreparedStatement stmt = conn.preparestatement(sql); Stmt.setString(1, param); ResultSet rs = stmt.executequery(); While(rs.next()) { int id = rs.getint("id");; String name = rs.getstring("name"); // 추가처리 rs.close(); stmt.close(); conn.close(); catch (Exception err) { Err.printStackTrace(); E) VB.NET Parameters 프로시저를이용하여매개변수값을검증합니다. Import System.Data.SqlClient Partial Class SQLExample Inherits System.Web.UI.Page Protected Sub Page Load(ByVal sender As Object, ByVal err As System.EventArgs) Handles Me.Load Dim dbconn As SqlConnection
페이지 8 / 9 Dim dbcmd As SqlCommand Dim dataread As SqlDataReader Dim sqlstr As String Dbconn = New SqlConnection("Server= 호스트이름 ;database= 데이터베이스이름 ; userid= 사용자 ID;password= 비밀번호 ") Dbconn.Open() sqlstr = "SELECT * FROM users WHERE name=@s1" dbcmd = New SqlCommand(sqlStr, dbconn) Dim param as String =.... Dim p1 As SqlParameter = New SqlParameter("@s1", param) Dbcmd.Parameters.Add(p1) dataread = dbcmd.executereader() dataread.close() dbcmd.dispose() dbconn.close() dbconn.dispose() end sub end Class F) PERL 일반적으로 DBI 모듈을이용하여처리하며 preparestatement 를이용합니다. #! /usr/bin/perl use CGI; use DBI; use DBI qw(:sql_types) use strict; use utf8; use Encode 'decode', 'encode'; my $db = DBI->connect('DBI:mysql:database=dbname;host=hostname;mysql_server_prepare=1; mysql_enable_utf8=1', 'xxx',,xxx'); if (! $db){ # 오류처리 My $sql = 'SELECT * FROM users WHERE number=? And name=?'; My $str = $db->prepare($sql); $str->bind_param(1, $number, SQL_INTEGER); $str->bind_param(2, $name, SQL_VARCHAR); My $rs = $str->execute(); If (! $rs){ # 진행처리 $str->finish $db->disconnect; G) Cold Fusion cfqueryparam 태그를이용합니다. <cfquery name="qitemname" datasource=" "> SELECT * FROM Item WHERE ItemID = <cfqueryparam cfsqltype="cf_sql_integer"
페이지 9 / 9 </cfquery> value="#url.itemid#"> SP(Stored Procedure) 를이용하는방법은다음과같습니다. <CFSTOREDPROC PROCEDURE="pkg_simple.Get_Vaules" DATASOURCE="oracle "> <CFPROCPARAM VALUE="#yearStart#" CFSQLTYPE="cf_sql_numeric"> <CFPROCPARAM VALUE="#yearEnd#" CFSQLTYPE="cf_sql_numeric"> <CFPROCRESULT NAME="getCrossData"> </CFSTOREDPROC> 주의 : 위해결방안에서제공하는소스코드는참고용으로활용하시기바랍니다. 복사하여사용하여발생하는오류 및문제에대해서는책임지지않습니다. 본서비스는 URL 에서사용되는인자 ( 매개변수 ) 에대해자동으로분석하고검증함으로써웹애플리케이션에서가 장많이나타나는입력값검증오류를서비스기반으로관리자나개발자가직접확인하고, 발견된문제점을수정한 후에다시점검할수있도록구성되어있습니다. 입력값검증서비스로활용하여웹서비스의안정성을확보하고개선하는데활용하여개발자에대한교육및점검, Q/A 차원에서활용이가능하며관리자및보안전문가들에게는빠른시간내에대규모의서비스점검과긴급한문 제점에대한신속한확인및검토에활용할수있습니다. 감사합니다. 알림 : 취약점이나해결방안에대한문의사항은당사 Q/A 게시판이나웹사이트하단에있는이메일주소로연락주 십시오. 감사합니다.