목차
5. 클라이언트 측 통제 우회
웹 애플리케이션의 핵심적인 보안 문제는 결국 클라이언트가 임의의 입력값을 전달할 수 있다는 것임. 애플리케이션이 클라이언트 측 통제를 통해 사용자의 입력값을 제한하는 방법은 크게 두가지임
1.
특정 클라이언트 컴포넌트를 사용한 메소커니즘을 통해 사용자들이 데이터를 조작하는 것을 막을 수 있다고 생각하는 방식
2.
사용자에 의해 입력된 데이터를 받아들이는 과정에서 애플리케이션 자체적으로 사용자가 전달한 데이터를 통제하기 위한 클라이언트 측 조치들을 구현하는 방법
5.1 클라이언트를 통한 데이터 전송
5.1.1 숨겨진 폼 필드
hidden 필드는 사용자에게는 보이지 않지만 서버로 전송되는 값이다.
위 코드는 내가 구현한 php 사이트의 코드중 일부이다. 정렬을 위해 hidden 필드로 asec 값을 넘기는데 , 비록 이걸로 할수 있는건 없지만, 만약 저 hidden 필드가 중요한 값을 나타낸다면, 공격자는 이를 가로채서 변조가 가능함.
5.1.2 HTTP 쿠키
HTTP 쿠키를 통해서도 데이터를 전송할 수 있다.
HTTP/1.1 200 ok
Set-Cookie: DiscountAgreed=25
Content-Lenght: 1530
JavaScript
복사
이러한 쿠키 값들은 사용자가 입력폼에서 입력으로 조질수는 없지만, 프록시를 통해 가로채서 변조할 수 있다. 위 예를 보면, 쿠키에 할인율 처럼 보이는 값을 수정한다. get, post 등의 메소드로 전송되는 데이터들은 보안적 기능을 잘 처리할수 있는데 저런 쿠키나 http 헤더를 통해 데이터를 전송하는건 생각보다 보안이 안되어 있는경우도 있다고 함
5.1.3 URL 매개변수
url 뒤에 붙여지는 파라미터 변수들를 이용해서 데이터 전송이 이루어진다. get 요청이 요렇게 전송된다. 저 값은 직접 url에서 사용자가 변경가능하면, 직접 수정하지 못하게 백단에서 처리되는 url 매개변수는 프록시를 통해 수정 가능함
5.1.4 Referer 헤더
브라우저 대부분은 요 헤더를 포함함. 이는 해당 URL에 대한 요청이 어떤 URL에서 온 것인지를 나타내기 위해 쓰이는데, 사용자가 링크를 클릭하거나, 폼을 제출하거나 그런 경우를 말한다.
GET /auth/...php http/1.1
host: ....
referer: http:.../admin.php
JavaScript
복사
만약 비번을 잃어버렸을때 이를 스스로 초기화 할 수 있게하는 페이지가 저렇게 요청된다고 가정하자. 물론 정상적인 경우는 저 요청에 오기까지 일련의 과정을 거쳤을 것이고, 저렇게 요청을 할 것이다. 애플리케이션은 refere 헤더를 통해, 해당 요청이 정상적인 곳에서 온 요청이라고 받아들일것으로 처리를 한다.
하지만 이역시 공격자가 프록시툴을 이용해서 요청을 가로채고, referer 헤더를 적절히 변경하면, 정상적이지 않는 방법으로도 비번을 초기화 시킬수 있을 것이다.
5.1.5 변형된 데이터
클라이언트를 통해 전송되는 데이터가 암호화가 되거나 변경되는 경우가 있다.
<input type="hidden" name="pricing_token" value="jsf3243krfjeklfj2kr23423">
HTML
복사
저렇게 제품의 가격의 값이 암호화가 되어있으면 한눈에 식별하기 어려움. 하지만 서버에서 분명 복호화가 진행되기때문에 복호화 루틴을 유추 하면 문제가 안됨.
5.1.6 ASP 닷넷 ViewState
이는 클라이언트를 통해 변형된 데이터를 전송하는데 사용되는 방식임. 이는 모든 ASP 닷넷 웹 애플리케이션에서 기본적으로 생성되는 숨겨진 필드임. 이는 사용자 인터페이스 내의 요소들을 클라측에 저장해서 서버에서는 관련 상태를 유지할 필요가 없게해서 성능을 높임
ASP 닷넷 플랫포믄 ViewState를 보호하기 위해서 추가적인 해시 값을(MAC) 더해서 ViewState 값을 변형함. 버프에서 MAC 보호기능이 활성화 되어있는지 확인가능함. 수정도 가능함.
5.2 사용자 데이터의 획득 : HTML 폼
5.2.1 길이 제한
간단하게 form 안에 입력하는 공간의 길이 제한이 걸려있는 경우가 있다. 이는 요청을 가로채서 수정이 가능하다. 근데 주의해야할 점이 하나 있음
HTTP/1.1 304 Not Midified
Data: ...
Etag: ...
Expires: Thr, ...
Cache-Control: max-age=7200
HTML
복사
요런 서버 응답이 오면 브라우저 캐시에 이미 요청된 리소스의 사본이 있는 경우를 뜻한다.따라서 가로채서 수정한 뒤 보낸 값이 세팅이 안되고 브라우저 남아있는 캐시를 돌려줄것이다. 브라우저가 캐시된 리소스를 요청하는 경우
GET ...
Host: ...
If-Modified-Since: 날짜
If-None-Match: "545-6433"
HTML
복사
If- 머시기 헤더 두개를 추가해서 보낸다. 브라우저가 최종적으로 캐시에 사본을 업데이트한 시간과 해당 리소스를 제공할 때 서버가 같이 제공했던 Etag 문자열을 서버에 알려준다. Etag는 개시 가능한 각 리소스에 서버가 부여한 일종의 일련번호이다. 해당 리소스가 변경될때마다 업데이트된다.
서버가 해당 리소스에 대한 If-modifed.. 헤더에 나온 날짜보다 더 새로운 버전을 보유하고 있거나, Etag 값이 서버 내에 있는 현재 버전의 Etag값과 같이 않으면 서버는 최신 버전의 리소스로 응답을 한다. 그렇지 않으면 304 응답코드를 돌려보내는데, 이는 요청된 리소스가 변경되지 않았으니 이미 캐시된 사본을 사용하라고 브라우저에게 알려주는 것이다.
브라우저가 캐시한 리소스를 가로채서 변조해야하는 경우 요청을 가로채서 저 If-.. 헤더를 제거한뒤 요청하면, 서버에게 요청한 해당 리소스를 새롭게 전달 받을 수 있다.
5.2.2 스크립트 기반 검증
html 코드내에, js 코드로 입력값을 검증하는 기능이 들어가있는 경우를 뜻한다. 입력한 값이 js 함수의 인자로 들어가서 유효성 체크를 하게되는데, 이는 해당 js 스크립트가 호출이 안되게 하는등의 우회 방법을 생각하면 된다.
하지만, 단순히 스크립트를 동작하지 않게하면, 그 후의 정상동작이 안될수도 있다. 따라서 이같은 경우는, 스크립트 검증이 끝난 값을 가로채서 수정한뒤 제출하는 방식으로 수정할수있다.
5.2.3 비활성화 된 요소
disable 된 태그가 있다? 근데 그게 중요한 값이다? 수정가능.
5.3 사용자 데이터의 획득 : 브라우저 확장
브라우저 확장은 여러가 다양한 방식으로 데이터를 받아들이는데, 입력 폼과 어떤 경우는 클라이언트의 운영체제 내에 있는 파일 시스템이나 레지스트리와 상호작용하기도 함. 이들이 작동하는 것이 html 폼이나 js보다는 사용자에게 덜 보이므로, 개발자들은 이런 검증 작업을 우회하기 어려울 것이라고 착각하기도 함.
5.3.1 일반적인 브라우저 확장 기술
•
브라우저 확장 기술은 중간 바이트코드로 컴파일됨
•
브라우저 확장 기술은 샌드박스 환경이 제공되는 가상머신 내에서 실행됨
•
브라우저 확장 기술은 복잡한 데이터 구조나 HTTP를 통한 객체를 전송하기 위해 직렬화를 적용한 원격 프레임워크를 사용함
1.
자바
자바 애플릿은 JVM에서 동작하고 자바 보안 정책에 의해 적용되는 샌드박스에 영향을 받음
⇒ 자바 애플릿은 자바 바이트코드 형태로 배포되는 애플릿이다.
2.
플래시
플래시 가상머신 내에서 실행되며, 호스트 컴퓨터의 샌드박스에 의해 보호됨
3.
실버라이트
5.3.2 브라우저 확장에 대한 접근
브라우저 확장 컴포넌트를 사용하는 애플리케이션을 목표로 삼을때 2가지 기술
1.
컴포넌트에서 생성하는 요청과 서버로부터 전달받는 응답을 가로채서 수정하기
2.
컴포넌트 자체를 직접적인 공격 대상으로 삼기
5.3.3 브라우저 확장 트래픽 가로채기
1.
직렬화 데이터 처리
애플리케이션은 데이터나 객체를 HTTP 요청에 담아 전달하기 전에 직렬화를 할수도 있음
5.3.4 브라우저 확장 디컴파일
일반적으로 바이트코드는 애플리케이션 페이지의 HTML 소스코드 내에 브라우저 확장을 구동하게 명시돼 있는 URL로부터 파일을 로드함. 만약 브라우저 확장 바이트코드에 대한 URL을 찾으면, 이를 주소창에 입력하여 바이트코드를 별도의 파일로 다운가능.
다운받고 → 디컴파일 → 코드 수정 → 다시 업로드 요런 식으로 브라우저 확장 기술 우회가능
5.3.5 디버거 붙이기
5.3.6 네이티브 클라이언트 컴포넌트
6장. 인증 무력화
6.1 인증기술
사용자 인증은 악의적인 공격에 맞서 애플리케이션을 보호하기 위한 핵심적인 조치임. 사용자 인증 기법은 다양한 기술이 있음
1.
HTML 폼 기반 사용자 인증
2.
비밀번호 + OTP를 결합한 다중 요인 인증 기법
OTP발생기는 애플리케이션이 제시한 입력 값으로 'challenge-response' 함수를 처리해서 일회용 비밀번호를 생성한다.
3.
SSL 인증서와 스마트 카드
4.
HTTP 기본이나 해시 인증
5.
NTLM이나 커버로스를 이용한 윈도우 통합 인증
6.
사용자 인증 서비스
6.2 인증 메커니즘에서 발견되는 설계상 결함
1.
안전하지 않은 비밀번호
2.
브포 공격이 가능한 로그인
•
클라측에서 브포를 막으려고 쿠키에 failedlogins=1 같이 써서 실패할때마다 시도 횟수를 기록하고 특정 횟수를 넘어가면, 더이상의 로그인 시도를 거부하는 로직도 있음. 하지만 이건 저 쿠키를 없애면 우회가능
3.
불필요하게 상세한 로그인 실패 메시지
•
로그인 요청에 대한 애플리케이션의 응답에 걸린 속도로 유효성을 판별할 수 도 있음
4.
로그인 정보의 전송 취약점
•
로그인 정보가 POST 요청 값의 본문에 기록되지 않고 쿼리 문제 전송되면 안됌
•
HTML POST 요청의 본문을 사용한다 처도 이런 요청을 다른 URL로 리다이렉트해 로그인 정보를 쿼리문의 매개변수로 다시 전달하는 경우를 많이 볼수 있음. 이러면 안됨
5.
비밀번호 변경 기능
6.
비밀번호 복구 기능
•
비밀 번호 변경 기능도 마찬가지로 로그인 페이지에서는 막고 복구기능이나 변경 기능 페이지에서는 브포가 가능하게 잘못 구현되어있을수도 있음
6.3 사용자 인증 구현상의 결함
아무리 잘 설계된 인증 메커니즘이라도 구현상의 실수로 매우 취약할수 있음
1.
장애 우회를 내포한 로그인 메커니즘
2.
다단계 로그인 메커니즘의 결함
3.
사용자 신원 정보의 안전하지 않은 보관
6.4 안전한 인증
1.
강력한 사용자 신원 정보 사용
2.
사용자 신원 정보의 안전한 처리
3.
적절한 신원 정보 검증