보안/android

[앱][리버싱] 과제보충

y00&z1 2021. 9. 17. 17:49

✔️ Mission2: otp 인증 단계 통과하기

 

-OTP 생성 방식 검색
-함수만 구글에 검색해도 풀 수 있음! 

 

[1] OTP 생성 방식 

OTP? ; One Time PassWord

-일회용 패스워드 : 매번 다른 비밀번호로 사용자 인증 -> 현재 사용 비밀번호로 다음 사용 비밀번호 유추 불가

 

 

1-1) 비동기화 방식

- OTP 토큰과 인증서버 간에 미리 설정된 동기화 기준 없음. 
- 인증 요청 시 사용자가 직접 임의의 난수 값을 OTP 토큰에 입력하여 OTP 생성

 

->질의-응답 방식

 

1-2) 동기화 방식

-OTP 토큰과 인증서버 간에 미리 공유된 비밀 정보와 동기화 정보에 의해 OTP 생성.

-OTP 토큰과 인증서버 간에 반드시 동기화 이뤄져야 함 ; 올바른 인증처리 조건

-비동기화 방식 단점 개선(사용자 입력 불편, 기존 id/pw app 호환 어려움)

 

->시간 동기화 방식 

: 서버와 OTP 토큰 간에 동기화된 시간 정보 기준으로 특정 시간마다 변하는 비밀번호 생성.

=> 사용자 인증요청X 특정 시간 간격O 마다 OTP 변경 -> 공격자가 OTP 얻기 어려움

 

->이벤트 동기화 방식

: 서버와 OTP 토큰이 동일한 카운트 값 기준으로 비밀번호 생성.

카운트 값?  OTP 토큰과 인증서버만 알 수 있는 값. 비밀 이외에 입력되는 비밀 정보.

=> OTP 값을 얻은 후 다시 OTP 생성 요청할 때까지 비밀번호 유지. 

 

 

->조합 방식

: 시각 동기화 방식+이벤트 동기화 방식 장점의 조합(시각 동기화 중심조합 방식/이벤트 동기화 중심 조합방식)

 

https://eunguru.tistory.com/197

 

OTP(One Time Password)

OTP(One Time Password) - 일회용 패스워드 - 매번 다른 비밀번호로 사용자를 인증하는 일회용 비밀번호를 의미 - 현재 사용할 비밀번호로 다음번에 사용할 비밀번호를 유추하는 것이 불가 OTP 생성 매

eunguru.tistory.com

 

 

 

 

 

 

[2]OTP 인증 단계 통과

2-1) OTP 인증 관련 소스코드 살펴보기 

MainActivity 에서 로그인 성공하게 되면 SubActivity로 전환되는 걸 확인했었다. 

 

다시 SubActivity를 살펴보면, 

getTOTPCode -> TOTP.getOTP 순으로 함수를 호출하고 있다. 

 

 

 

 

TOTP 클래스의 소스코드를 살펴보자. (함수 위주)

한 번에 캡처가 안 돼서 일단 함수 위주로 캡처를 하였는데, 

getStep() 함수에 보면, 현재 시간을 가져와 세팅하는 함수처럼 보인다. -> OTP 생성 방식 중 시간 동기화 방식임을 유추할 수 있다. 

 

 

 

 

2-2) OTP 함수 찾기

그리고 함수명으로 구글링을 해보았는데, 

해당 소스코드와 거의 동일한 코드를 찾았다!

https://github.com/taimos/totp/blob/master/src/main/java/de/taimos/totp/TOTP.java

 

GitHub - taimos/totp: TOTP lib for RFC 6238

TOTP lib for RFC 6238. Contribute to taimos/totp development by creating an account on GitHub.

github.com

 

 

 

2-3) OTP 얻기

TOTP 코드를 찾았으니 입력 값만 제대로 넣으면 OTP를 얻을 수 있다. 

 

 

 

subActivity를 다시 살펴보면,

str 변수가 getTOTPCode의 인자로 입력되고, 해당 변수는 TOTP클래스의 getOTP로 전달됨을 알 수 있다.

 

 

 

 

str 변수의 선언 구문부터 다시 살펴보자.

String str = SubActivity.this.getString(2131755116).substring(15).toUpperCase();

 

-getString(2131755116)

 

; getString 함수?

SQLServerResultSet 개체의 현재 행에서 지정된 열 이름의 값을 검색하여 Java 프로그래밍 언어의 문자열로 반환하는 함수!!

 

 

: 2131755116 -> hex 값으로 변환; 0x7f10006c -> 해당 인덱스를 이용하여 반한 값 찾기

=> 203d233e382c1e215a6a7c6c7e725c6b

 

 

-substring(15)

: 문자열을 자르는 함수로, 15번째 인덱스부터 끝까지의 문자열을 리턴함

=>15a6a7c6c7e725c6b

 

 

-toUpperCase();

: 문자열을 모두 대문자로 바꾸어 리턴하는 함수

=> 15A6A7C6C7E725C6B

 

 

-> 해당 값을 매개변수로 넣고 코드 돌리면 OTP 얻을 수 있다!

 

 

혹시 몰라서 substring().toUpperCase() 부분은 자바에서 다시 작업했다. 

6자리 OTP가 나오기는 했지만 failed. 

 

 

 

 

바로 평문을 넣으면 안 되고,

혹시 subActivity에서 getTOTPCode() 함수를 거친 반환 값을 넣어야 하나? 싶어서

작성해보았지만 import 실패. 

실패하는 import

import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Hex;

 

 

https://mvnrepository.com/artifact/commons-codec

->찾았으나 어떻게 사용 가능한지 모르겠다. 

 

 

그래서 혹시 서버 시간이 다른가? 해서 살펴보았는데, 내가 찾은 코드랑 동일하다(currentTimeMillis() 사용하고 있음)

 

private static long getStep() {
// 30 seconds StepSize (ID TOTP)
return System.currentTimeMillis() / 30000;

}

->30초마다 OTP가 갱신되는 것 같다

(현재 안드로이드 스튜디오가 다른 사용자 계정이 있어서 입력하려면 30초가 훨씬 초과되어 failed가 뜨는 듯..? )