[목차]
1. 런타임 조작 실습 3
- 키워드 검색 후 검증 로직 확인
- 분기점 주소 및 반환 값 확인
- 풀이 case 1 : Brute Force 공격 코드 작성
- 풀이 case 2 : 비교 값 변조 코드 작성
1. 런타임 조작 실습 3
# 힌트 키워드 찾기
DVIA 앱에서 [Runtime Manipulation] 메뉴 선택 후
임의의 인증 코드 입력 후 Validate Code 요청 시
에러 팝업 발생 확인

Error : Incorrect Code
1) 키워드 검색 후 검증 로직 확인

분기점을 찾아 올라가다 보면
인증 코드가 평문으로 노출되는 것을
확인할 수 있는데

본 실습은 런타임 조작에
중점을 두고 있으니 실습을
계속 이어나간다.
2) 분기점 주소 및 반환 값 확인

분기가 이루어지는 주소
바로 위에서 x9, x8 레지스터가
cmp, 비교를 하고 있는데
두 값이 일치하지 않으면
바로 아래 분기점 주소,
Incorrect Code 부분으로
점프를 뛰도록 되어 있다.
# 해결 아이디어 1
cmp 레지스터 두 값을 1, 1
즉 16진수로 0x1, 0x1로
통일 시켜준다.
# 해결 아이디어 2
비교 부분 위를 보면

x8 값에는
해당 바이너리가 비교할 값인 0x2290을 넣어 주었고
x9 값에는 #local_28 즉,
이용자 입력 값을 받아 넣어준 뒤
최종적으로 x9, x8 두 값을 비교하여
결과에 따라 분기를 해준다.
문제에 코드가 4자리인 것이 주어졌고
Brute Force 공격으로 일치되는 값을
찾으라고 했으니 이를 시도해 본다.
참고로 16진수 0x2290을 10진수로 바꾸면

인증 코드 확인이 가능해 문제가 풀리지만
이 역시 의도가 아니기에 넘어간다.
위에서 기술한 해결 아이디어
1, 2번 모두 실습해 본다!
# 풀이 Case 1
Brute Force 공격 코드 작성
1) 주소 확인
먼저 Interceptor를 걸 주소는
비교가 이루어지는 부분

0x15e3e0
2) 레지스터 값 확인
var realBase = Module.findBaseAddress('DVIA-v2')
console.log("[+] 앱 실제 메모리 주소 : " + realBase)
var runtime_address = realBase.add('0x15e3e0')
console.log("[+] 분기점 실제 주소 : " + runtime_address)
Interceptor.attach(runtime_address, {
onEnter:function(args){
console.log("")
console.log("[+] x8, x9 값 : ")
console.log(JSON.stringify(this.context))
}
})
파일 돌려주고 앱에서
인증코드 1111 입력 시


정상적으로 담겼으나
x8 값과 맞지 않으므로 Error가 발생!
3) Brute force
var realBase = Module.findBaseAddress('DVIA-v2')
//console.log("[+] 앱 실제 메모리 주소 : " + realBase)
var runtime_address = realBase.add('0x15e3e0')
//console.log("[+] 분기점 실제 주소 : " + runtime_address)
// [+] 네 자릿수 맞춰주는 함수 정의
function padToFour(number){
if(number<=9999){
number = ("000" + number).slice(-4) // slice로 4자리 맞춰주면 됨
return String(number) // 위에서 "000"이 스트링으로 묶였는데 혹시 몰라 한번 더 형 변환을 해준다.
}
}
Interceptor.attach(runtime_address,{
onEnter:function(args){
console.log("")
console.log("[+] x8, x9 값 : ")
console.log(JSON.stringify(this.context))
console.log("x8 값 :" + this.context.x8)
console.log("x9 값 :" + this.context.x9)
// [+] 비교가 가능하도록 16진수 x8 값을 정수형(10진수)로 변환 작업
var hex_pin = parseInt(this.context.x8, 16) // 데이터 형식 주의! 여기선 정수(Int)형으로 반환됨
hex_pin = String(hex_pin) // padToFour 함수가 스트링 타입이기에 여기도 동일하게 형 변환시켜 줘야함!
// [+] Brute Force 반복문
for(var i=0;i<10000;i++){
console.log("[+] Brute force attack : " + padToFour(i))
if(hex_pin == padToFour(i)){
this.context.x9 = padToFour(i)
console.log("new x8 값 :" + this.context.x8)
console.log("new x9 값 :" + this.context.x9)
console.log("x8의 정수 코드는 : " + hex_pin)
break
}
}
}
})
돌려보면


Brute Force 로 크랙 성공!
# 풀이 Case 2
비교 값 변조
1) 비교 값을 통일하는 코드 작성
var realBase = Module.findBaseAddress('DVIA-v2')
//console.log("[+] 앱 실제 메모리 주소 : " + realBase)
var runtime_address = realBase.add('0x15e3e0')
//console.log("[+] 분기점 실제 주소 : " + runtime_address)
Interceptor.attach(runtime_address,{
onEnter:function(args){
console.log("")
console.log("x8 값 :" + this.context.x8)
console.log("x9 값 :" + this.context.x9)
this.context.x8 = 0x1
this.context.x9 = 0x1
// 또는 간단히 x9를 x8에 담아주면 됨
// this.context.x8 = this.context.x9
console.log("new x8 값 :" + this.context.x8)
console.log("new x9 값 :" + this.context.x9)
}
})
2) 돌려주면

또는


끝
[도움 출처]
: 보안프로젝트 김태영 팀장 iOS 모바일 앱 모의해킹(기초) 강의
'APP 진단 > iOS' 카테고리의 다른 글
18. IPC Issues (0) | 2022.11.23 |
---|---|
17. Side Channel Data Leakage (0) | 2022.11.22 |
15. Runtime Manipulation - 인증 우회 실습 2 (0) | 2022.11.20 |
14. Runtime Manipulation - 인증 우회 실습 1 (0) | 2022.11.20 |
13. Sensitive Information in Memory (0) | 2022.11.20 |