무작정 따라하며 원리를 깨우치는 웹 해킹 : WebGoat 편
https://www.inflearn.com/course/%EC%9B%B9-%ED%95%B4%ED%82%B9-%EB%B3%B4%EC%95%88-webgoat
취약한 인증
2. Broken Authentication
- Authentication Bypasses
- JWT tokens
- Password reset
- Secure Passwords
Authentication Bypasses
2 Fator Password Reset (2단계 인증)
시나리오 : 2차인증으로 어떠한 질문에 대답해야 하는데, 그에 대한 2Fator 인증 우회
실제 사례 : 2016년 페이팔 2차인증에서 파라미터를 완전히 제거한 뒤 인증우회 성공
정상결과
파라미터 삭제의 경우 인증실패
파라미터 변조를 통해 인증 우회 성공
url을 보면 POST /WebGoat/auth-bypass/verify-account HTTP/1.1 이고
https://github.com/WebGoat/WebGoat
경로 : WebGoat/src/main/java/org/owasp/webgoat/lessons/authbypass/VerifyAccount.java
파일 내에서 path = "/auth-bypass/verify-account" 인 메소드를 찾는다
//주요 인증 부분
if (verificationHelper.verifyAccount(Integer.valueOf(userId), (HashMap) submittedAnswers)) {
userSessionData.setValue("account-verified-id", userId);
return success(this).feedback("verify-account.success").build();
} else {
return failed(this).feedback("verify-account.failed").build();
}
//verifyAccount메소드의 내용은 AccountVerificationHelper.java에 있다
public boolean verifyAccount(Integer userId, HashMap<String, String> submittedQuestions) {
// short circuit if no questions are submitted
if (submittedQuestions.entrySet().size() != secQuestionStore.get(verifyUserId).size()) {
return false;
}
if (submittedQuestions.containsKey("secQuestion0")
&& !submittedQuestions
.get("secQuestion0")
.equals(secQuestionStore.get(verifyUserId).get("secQuestion0"))) {
return false;
}
if (submittedQuestions.containsKey("secQuestion1")
&& !submittedQuestions
.get("secQuestion1")
.equals(secQuestionStore.get(verifyUserId).get("secQuestion1"))) {
return false;
}
// else
return true;
}
=> IF문을 보면, 질문의 개수가 다르거나, Q0/Q1의 답이 일치하지 않을때 false를 설정하고 있다.
파라미터에 Q0과 Q1이 없으므로 if문을 통과해버리고 자연스럽게 마지막의 return true가 반환된다
JWT tokens
Json Web Token
구성
[헤더].[페이로드].[시그니처] 각 Base64Url로 이루어짐
헤더 : 타입, 시그니쳐에 적용될 알고리즘 정보
페이로드 : 사용자 정보
시그니쳐 : 헤더와 페이로드의 내용을 비밀키를 통해 알고리즘 적용한 데이터 (데이터 조작 방지)
문제
JWT 토큰을 변조하여 관리자가 된 후 투표에 성공하는 것이 목표
옆에 보면 이렇게 계정을 변경할 수 있다
일단 Burp에서 json 데이터 응답 받을 수 있도록 설정해줘야 한다
강의와 Burp 버전이 달라서
extender가 없어서 한참 헤맸는데 Extensions에 BApp Store가 있었다
요 플러그인도 설치해야한다
Burp에서 확인하면, Proxy탭에 JWS 라는 새로운 탭이 형성되어 있다
JWT 토큰은 보통 시그니쳐가 있어 변조가 불가능하지만, none 알고리즘을 적용시 시그니쳐 값이 없어도 인증이 된다
여기서 이렇게 변조를 한다. 시그니쳐 부분은 완전삭제
이렇게 하면 풀려야 하는데......... 강의 버전과 코드가 달라진 모양인지 안됐다
=> 나는 바보다; intercept 할 때 휴지통 아이콘을 눌러야 하는데 (왜냐면, 리셋이 목표니까)
계정 변경 아이콘을 intercept 해놓고 안된다고 헛짓하고 있었다....
아무튼 성공
+
디버거 메뉴에서 짠 붙여넣으면 디코딩 되어 나오니 데이터를 볼 수 있다
JWT Crack의 원리
헤더 + 페이로드를 무작위로 알고리즘을 적용하여 시그니쳐와 맞는지 비교하여 알아낸다
Hashcat을 이용한 JWT Crack
문제
Given we have the following token try to find out secret key and submit a new key with the username changed to WebGoat.
eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJhdWQiOiJ3ZWJnb2F0Lm9yZyIsImlhdCI6MTczNjM0MjIzMCwiZXhwIjoxNzM2MzQyMjkwLCJzdWIiOiJ0b21Ad2ViZ29hdC5vcmciLCJ1c2VybmFtZSI6IlRvbSIsIkVtYWlsIjoidG9tQHdlYmdvYXQub3JnIiwiUm9sZSI6WyJNYW5hZ2VyIiwiUHJvamVjdCBBZG1pbmlzdHJhdG9yIl19.w1oahquV5fkJuMImk5YtFdv-vsLnL1LR4CvlYxRRZ44 |
주어진 토큰의 사용자명을 WebGoat으로 변경하여 제출할것
단순히 username만 변경하여 제출하면 이런 응답이 뜬다. 시그니쳐 변조가 필요하다.
https://hashcat.net/hashcat/
hashcat 사이트에 들어가서 hashcat binaries를 다운로드 받는다
이런 화면이 나온다
사전파일은 https://github.com/first20hours/google-10000-english/blob/master/google-10000-english.txt 를 이용했다
주어진 토큰값을 jwt.txt로 저장한다
-a 공격타입은 3번 모드(Brute-force)
-m 해시모드의 경우 jwt는 16500
따라서
hashcat -a 3 -m 16500 jwt.txt google-10000-english.txt
이렇게 입력한다
(hashcat.exe를 실행하는 것이 아니라, cmd 창에서 해당 위치에 들어가 명령어를 입력한다)
결과
너무 오래 걸려서 만료됐다고 퇴짜맞음;
새로고침하고, 다시 붙여넣고 진행하면 성공
+이전문제에서 진행한 none 공격으로 진행해도 성공함
Refresh Token
액세스토큰(jwt)을 재발급 받기 위한 키
7번 항목
Bugcrowd 현상금 프로그램을 기반으로 하며
전체 내용은 https://emtunc.org/blog/11/2017/jwt-refresh-token-manipulation/ 에서 확인가능
그냥 제출하면 당연히 에러난다
주어진 로그
194.201.170.15 - - [28/Jan/2016:21:28:01 +0100] "GET /JWT/refresh/checkout?token=eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1MjYxMzE0MTEsImV4cCI6MTUyNjIxNzgxMSwiYWRtaW4iOiJmYWxzZSIsInVzZXIiOiJUb20ifQ.DCoaq9zQkyDH25EcVWKcdbyVfUL4c9D4jRvsqOqvi9iAd4QuqmKcchfbU8FNzeBNF9tLeFXHZLU4yRkq-bjm7Q HTTP/1.1" 401 242 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0" "-" 194.201.170.15 - - [28/Jan/2016:21:28:01 +0100] "POST /JWT/refresh/moveToCheckout HTTP/1.1" 200 12783 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0" "-" 194.201.170.15 - - [28/Jan/2016:21:28:01 +0100] "POST /JWT/refresh/login HTTP/1.1" 200 212 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0" "-" 194.201.170.15 - - [28/Jan/2016:21:28:01 +0100] "GET /JWT/refresh/addItems HTTP/1.1" 404 249 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0" "-" 195.206.170.15 - - [28/Jan/2016:21:28:01 +0100] "POST /JWT/refresh/moveToCheckout HTTP/1.1" 404 215 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36" "-" |
js파일을 보는데
뭘 추가해줘야 할지 몰라서 일단 request랑 response 둘 다 넣었다
HTTP History 탭에 들어가면
여러가지 파일 중에 jwt-refresh.js 파일이 있다
핵심내용. 새 토큰을 발급받을때.
로그인은 /WebGoat/JWT/refresh/login
다른 사용자의 refresh_token인 GgHHRVjjrGlFmhXwhmof 를 이용하여
주어진 Tom의 액세스 토큰을 통해 재발급받는다
url : /WebGoat/JWT/refresh/newToken
강의대로 따라했는데 401 Unauthorized 가 떴다 ...
재발급 토큰이 아예 생성이 되지 않으니 당황스럽군... 이에 대해서는 강의 질문을 남겨놓았다
8번 항목
순서
기존과 다르게 추가된 부분은 kid라는 파라미터인데
해당 키를 변조하고 tom의 계정을 삭제해야 한다
1. union based sql injection을 통한 kid 변조 + base64 인코딩
2. jerry를 tom으로 변조
kid 파라미터에 인젝션하기 전에 취약한 것을 파악한다
"status" : 500,
"error" : "Internal Server Error"
'||' 를 넣었을때 정상적인 응답이 돌아오는 것으로 보아 취약한 것을 확인할 수 있다
Jerry의 토큰값
변조한 토큰값
kid부분에 sql injection
( w' and 1=2 union select 'd2ViZ29hdA==' from jwt_keys where id='webgoat_key )
username에 Tom
시그니쳐 부분에 webgoat 넣어주었다 select절에는 webgoat를 base64 인코딩해서 셋팅했다
결과는 에러
엥...
혹시나 해서 exp 부분 변조했더니 성공했다 휴
Password reset
webwolf 설치 : https://github.com/WebGoat/WebGoat/releases/download/v8.1.0/webwolf-8.1.0.jar
C:\Users\user\Desktop\webgoat>java -jar webwolf-8.1.0.jar
cmd창에서 실행해주고
http://127.0.0.1:9090/WebWolf/home
webwolf 페이지는 여기인데, 원래 192 ~ ip를 쓰고 있었으나 접속이 안되어 127.0.0.1 로 접속했다.
비밀번호 찾기를 하면 웹울프 메일함에 이렇게 들어와있다
해당 문제는 재설정 패스워드 결함을 의미한다 (자세히 보면 재설정 비밀번호가 id를 거꾸로 나열한 것에 지나지 않는다...)
사용자 이름은 webgoat 좋아하는 컬러는 red
다른 사용자의 패스워드를 알아내는 것이 목표
다른 사용자 : tom, admin, larry
=> 해당 문제는 인젝션을 하고 말고 하는게 아니라 그냥 무작위 대입이었다
색깔처럼 고정된 답이 있는 질문은 보안에 취약하다는 의미
이러한 무작위 대입은 Intruder에서 리스트를 셋팅하여 빠르게 진행할 수 있다
이외
좋아하는 동물, 어머니와 자신의 생년, 어릴 때 살았던 집 주소나 첫 취직한 도시 이름 등등
추측하기 쉬운 질문들은 보안이 취약하다
목표 : tom의 계정으로 로그인해야한다
비밀번호 재설정 메일을 보낼 때 해커의 url로 변조될 수 있는 위험이 있다. 이 문제의 경우 Host만 변조하면 그걸로 바꿔쳐짐
웹울프로 연결된 url로 host를 변경하면
웹울프의 incoming requests에서 볼 수 있다
앞쪽 url을 웹곳 쪽으로 변경하여 접속하고 비밀번호를 재설정한다
로그인....에 성공해야 하는데 실패한다. 왜인지 도무지 모르겠다.... ;;;
이메일 링크를 보냈고
웹울프로 확인했고
Password changed successfully, please login again with your new password
패스워드 설정 완료까지 떴는데도 로그인이 되지 않는다...
웹곳자체 오류인것으로 판단되니 넘어가야지;;
Secure Passwords
좋은 패스워드의 조건에 대한 항목
특문, 숫자, 소문자, 대문자를 섞어서 입력하자 클리어되었다
'정보보안 > WebGoat' 카테고리의 다른 글
OWASP Top 10 항목 진단 - Sensitive Data Exposure, XXE (0) | 2025.01.14 |
---|---|
OWASP Top 10 항목 진단 - Injection 인젝션 (0) | 2025.01.03 |
OWASP Top 10 항목 진단 - WebGoat (환경설정) (0) | 2024.11.18 |