Broken Access Control (접근 제어 오류)
- 권한이 없는 사용자가 민감한 데이터나 시스템에 접근할 수 있도록 허용하는 취약점. 인증 및 권한 부여가 제대로 구현되지 않았거나 이러한 제어가 실행되는 방식에 취약점이 있을 때 발생한다.
- 사용자별 접근 제어가 제대로 적용이 되지 않는 취약점
- 주어진 권한을 벗어난 행동을 야기함
- 관리자 페이지 등에 공격자가 접근할 수 있음
[공격 방법]
1. Brute Force
- 완전 탐색 알고리즘. 가능한 모든 경우의 수를 모두 탐색하면서 요구조건에 충족되는 결과만을 가져온다. 이 알고리즘은 예외 없이 100%의 확률로 정답만을 출력한다. (순차탐색, 깊이 우선 탐색, 너비 우선 탐색 사용) 때문에 툴을 사용해 가능한 모든 경우의 수를 다 탐색한 후 pw를 찾아낼 수 있게 된다.
- 비밀번호, PIN, 암호화 키를 무작위로 계속해서 입력함으로써 해킹을 시도하는 공격 방식
[대응방법]
- 관리자 인터페이스: 별도의 포트 번호로 제공 or HTTPS로 구현
- 강력한 비밀번호 사용
- 로그인 횟수/재시도 시간 제한, 2단계 인증 등을 설정하여 방어
- 응답을 느리게 한다. (가능하면 난수로)
- 일정 시간동안 락킹 (아예 일정 시간동안 로그인 시도를 딜레이 해 무력화)
- captcha 등 실제 사람이 입력하는지 확인 할 수 있는 수단을 사용
2. Weak Session ID
: 사용자 식별을 위해 할당되는 세션 ID가 단순하면 쉽게 위조가 가능해지고, 공격자가 타 사용자의 세션 ID를 쉽게 추측해 접근할 수 있게 된다.
[대응방법]
- 랜덤 정수 생성 함수를 이용해 매번 세션 아이디를 랜덤하게 발급하도록 한다.
- sha1 등의 안전한 암호화 알고리즘을 통해 암호화를 진행한다.
- session time out 등의 기능을 이용해 다른 사용자의 세션을 이용해 권한 탈취를 하기 어렵게 해야 한다.
3. Authorization Bypass
: 인증 우회 취약점. 공격자가 무단 액세스를 얻기 위해 장치의 인증 메커니즘을 우회할 때 발생한다. 공격자가 다른 사용자의 자격 증명을 무단으로 사용해 액세스할 수 있다.
[대응 방법]
- 잦은 패치로 앱과 서버를 최신 상태로 유지한다.
- 다단계 인증 등의 인증을 시행해 본인이 아니면 접근할 수 없도록 조치한다.
- 가능한 모든걸 암호화한다.
- 데이터 파일 & 폴더를 보호한다.
[실습]
1. Brute Force
(1) security level: low
[국예린]: 버프스위트로 비밀번호 무차별 대입(딕셔너리 사용)

proxy → http history 탭에서 가장 최근 get 클릭
입력값 찾을 수 있음
해당 get 우클릭→ send to intruder
Intruder로 이동 → positions

선택 되어있던 부분 삭제 후 password 부분만 선택해 우측 add 클릭




상부 우측 start attack 클릭 후 실행 화면 → 상부 메뉴에 Attack→pause 누르면 멈춤
각각의 라인이 하나의 요청을 의미한다
payload→ 각각 요청에 어떤 값 보냈는지 표시중

이렇게 기다리다보면 찾음
시간이 많이 걸리고 pw가 길면 길수록 오래걸려 효율이 떨어짐
터미널을 하나 열어서
gedit /usr/share/john/password.lst 입력



brute force에서 simple list로 변경

앞의 주석 내용들은 선택해서 remove
start attack ㅇㅇ.

password 하나만 응답 길이가 크게 다르다.

테스트 해보니 로그인 완
[류현주]: 소스코드 분석, 버프스위트로 무차별 대입

간단하게 소스코드를 훑어보면 GET 방식으로 username, password를 보내는 코드다. 그런데 md5로 해시 암호화하는 비밀번호랑 다르게 사용자 이름에는 아무런 조치도 없다!..→ sql 인젝션도 가능하다는 뜻


GET 요청으로 username과 password 파라미터를 보낸다. admin, test로 로그인을 시도했다는 것이 보인다. 이제 이 페이로드를 intruder 탭으로 보낸다.





[송연수]: 버프스위트로 비밀번호 무차별 대입(딕셔너리 사용)

아무 입력 값이나 넣어본다

proxy를 활용해 brute force 공격


자주 사용되는 passwordlist 정리 파일을 활용



(2) security level: medium
[국예린]: 소스코드 분석, 버프스위트로 비밀번호 무차별 대입

<?php
if( isset( $_GET[ 'Login' ] ) ) {
// Sanitise username input
$user = $_GET[ 'username' ];
$user = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $user ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Sanitise password input
$pass = $_GET[ 'password' ];
$pass = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass = md5( $pass );
// Check the database
$query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
if( $result && mysqli_num_rows( $result ) == 1 ) {
// Get users details
$row = mysqli_fetch_assoc( $result );
$avatar = $row["avatar"];
// Login successful
echo "<p>Welcome to the password protected area {$user}</p>";
echo "<img src=\"{$avatar}\" />";
}
else {
// Login failed
sleep( 2 );
echo "<pre><br />Username and/or password incorrect.</pre>";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
login 성공시 “Welcome to the password protected area”와 이미지 출력
실패시 sleep(2)로 응답을 지연시켜 브루트 포스로 인한 비밀번호 찾기가 오래 걸리도록 방해중이다.
이와 같은 기능을 통해 해당 공격을 어느정도 대응 할 수 있게 되는 것이다.
[류현주]: 소스코드 분석, 버프스위트로 비밀번호 무차별 공격

medium에서는 low와 공격과정은 일치하지만 브루트포스의 진행시간이 더 길다.

view source 버튼을 눌러서 확인해보니, 공격시간이 늘어나도록 로그인 실패할 때마다 2초씩 멈추게 설정해놨다.
[송연수]: 소스코드 분석, 버프스위트로 비밀번호 무차별 대입

medium은 sleep(2)로 지연을 주고 있지만 low과 동일한 공격을 하는 데에 큰 문제는 없었다
(3) security level: high
[국예린]: 소스코드 분석


정해진 시간이 아니라 난수를 쓰는 이유?
해당 시간동안 바로 응답 오지 않으면 바로 다른 요청으로 갈 수 있기 때문에
[류현주]: 소스코드 분석

이번에는 로그인을 하기 전에 유저의 토큰을 확인하는 과정을 거친다. 요청을 보낸 유저 토큰과 서버가 가지고 있는 세션 토큰이 일치해야 한다. 그렇다면 소스코드에 서버로 보낼 토큰이 있어야 하니 찾아보자.

로그인 실패할 때는 sleep하는 시간을 0~2초 중 랜덤으로 설정해 더욱 더 보안성을 높였다.

input태그가 hidden 타입으로 존재하는 것을 확인했다.

text 타입으로 바꿨더니 유저 토큰값이 보인다. CSRF 공격을 막는 데에는 효과적이겠지만 브루트포스에서는 아니다.
[송연수]: 버프스위트로 비밀번호, CSRF 토큰 무차별 대입



password 부분은 앞선 실습과 그대로 진행

incorrect 문자열을 찾는다고 설정 → 없으면 correct = password


웹 응답에서 토큰을 추출하기 위해서 extract 설정을 진행

리다이렉션 자동 설정 후 공격하면

발견!
(4) security level: impossible
[국예린]: 에러메세지 분석

아예 로그인을 15분간 차단하는 방식을 사용
이런 경우 아예 비밀번호를 틀려 15분간 사용자가 접속하지 못하게 하는 경우의 공격이 사용될 수 있음
[류현주]: 소스코드 분석


또한 로그인은 3번까지 기회가 있고, 15분씩 멈춘다. 브루트포스의 방법이 불가능한 대응방법이 되겠다.
2. Weak Session ID
(1) security level: low
[국예린]: 소스코드 분석, 세션 ID 발급해 관찰
proxy http history에서 가장 최근 post 파트를 클릭해보면


소스코드를 한번 보고자 한다

이로 인해 공격자가 타인의 세션을 훔칠 수 있게 된다.
(2) security level: medium
[국예린]: 소스코드 분석, 세션 ID 관찰

첫 번째로는 1710174492가 나왔다. low 레벨의 정수와는 다르다.

두 번째로는 1710174604. 뒤의 세자리가 바뀌었다.

세 번째로는 1710174667… 패턴 예측이 잘 안되어 소스코드를 보겠다

쉽게 대응할 수 없도록 지금까지 지나온 초를 정수형태로 리턴해주는 time 함수를 사용해 접근에 대응하고 있다.
(3) security level: high
[국예린] : 소스코드 분석, 세션 ID 관찰


두 번째도 발급해 보았지만 별다른 규칙성이 눈에 띄지 않는다.

쿠키의 만료 시간을 현재 시간에서 3600초. 즉 한시간 후로 정하고 있고 지난 세션 변수의 값을 하나 증가시킨 후,
그 값을 md5 해시로 변환해 쿠키로 저장한다.
쿠키에 해시값을 적용해 접근을 대응하고 있다.
그러나 해당 내용도 md5 알고리즘을 알면 그렇게 어려운 내용이 아니다.
1,2,3,4,5 … 1씩 증가한 값을 md5로 암호화하면 해당 세션 값이 나온다.
높은 수준의 보안은 아니다.
(4) security level: impossible
[국예린]: 소스코드 분석, 세션 ID 관찰

이전보다 더 길고 무작위해보이는 값이 나왔다.
바로 소스코드를 보았다.

mt_rand()로 무작위 정수를 생성하고, 현재 시간을 초 단위로 반환한다. 랜덤 생성된 정수를 md5보다 강력한 sha1 암호 알고리즘을 활용해 바꾸었다.
쉽게 추측할 수 없도록 쿠키값을 바꾸어 접근을 대응하고 있다.
3. Authorization Bypass
(1) security level: low
[국예린]: 페이지 경로 직접 접속 실습
다른 브라우저로 예시 속 다른 유저 godeonb로 로그인한다.


admin으로 로그인 되어있던 브라우저의 proxy 탭을 활용해 해당 페이지의 경로값을 복사한다.




gordonb 계정으로 접속된 모습이다.
[송연수]: 페이지 경로 직접 접속 실습

해당 페이지에 second user로 접근하는 것이 목표


보여지는 화면에서만 숨겨져있고
authbypass에 직접 접근 가능
(2) security level: medium
[국예린]: API 직접 접속 실습


low 처럼 경로 붙여넣기 시 권한없음이 뜬다

해당 페이지 get 부분을 repeater로 보내보겠다.

OPTIONS로 변경 → send

HEAD로 변경 → send

우클릭 → change request methond → send


admin 로그인 시 볼 수 있는 get_user_data.php 페이지를 경로에 입력해본다


회원정보 DB 열람 가능
[송연수]: API 직접 접속 실습

vulnerabilities/authbypass 경로는 막혔지만

사용자 데이터를 반환하는 API에 직접 액세스 가능(get방식 처리가 안됨)

(3) security level: high
[송연수]:

high로 넘어오면 get_user_data.php도 막힌 걸 알 수 있다
이를 우회하기 위해 update 쪽을 공략 (post방식은 안 막힘)


gordonb로 로그인 했을 때의 쿠키를 복사해서

post 요청을 repeater를 이용해서

값을 변경 후

보내주면

접근 권한이 없는 페이지에서의 update가 가능하다
+ 참고)
실습 참고 링크
공격을 위한 proxy 설정
'4-2. 2024-1 심화 스터디 > 웹 취약점 분석' 카테고리의 다른 글
[7주차] Security Misconfiguration 취약점 (3) (0) | 2024.05.25 |
---|---|
[6주차] Security Misconfiguration 취약점 (2) (0) | 2024.05.25 |
[4주차] Injection 취약점 분석/실습 (2/2) (0) | 2024.04.03 |
[3주차] Injection 취약점 분석/실습 (1/2) (1) | 2024.03.27 |
[1주차] OWASP top 10 & DVWA 환경 구축 (0) | 2024.03.15 |