안녕하세요! 오늘은 '디버깅 기능 취약점' 그리고 '런타임 조작 취약점' 2개를 실습해보려고 포스팅하였습니다! 디버깅 취약점으로 인해 런타임 조작이 일어날 수 있어서 이 두개의 항목을 묶게 되었습니다!
['디버깅 취약점' 이란?]
> Application Debuggable 취약점은 안드로이드 디버깅 모드의 설정 여부에 따라 발생합니다. AndroidManifest.xml 에 포함되는 속성인데 기본적으로 디버깅 모드는 앱이 배포될때 "false" 로 지정되어 있습니다. 하지만 개발중에 편의상 디버깅 옵션을 "true"로 해놓는 경우가 있는데 이 경우 앱의 중대한 보안 결함이 발생할 수 있습니다.
['런타임 조작' 이란?]
> 앱이 실행되는 도중 메모리상에 악의적인 행동을 하는 취약점입니다. 메모리상에 올라가는 변수값이나 함수의 조작을 공격자가 원하는 값으로 바꾸어 동작흐름을 바꾸고 악의적인 동작을 할 수 있게 만드는 취약점입니다. 대표적으로 Frida 를 통한 방식이 있고 이번시간에는 자바에서 지원하는 jdb를 이용하여 디버깅하는 방법을 실습해보겠습니다!
1. 취약점 탐색
> 인시큐어 뱅크 어플을 Jadx로 디컴파일링 한뒤 AndroidManifest.xml 파일을 열어보시면 debuggable="true" 설정이 되어있는 것을 확인하실 수 있습니다. 디버깅 취약점이 발견이 되었으니 이 점을 이용하여 런타임 조작까지 이어보겠습니다!
2. 공격과정
2.1. 우선 런타임 조작을 위해선 메모리상에 함수나 값들이 올라가야하기 때문에 인시큐어 뱅크 앱을 실행합니다!
2.2. 이후 가상머신에서 인시큐어뱅크 앱을 사용하고 있는 포트정보 확인을 위하여 해당 명령어를 입력합니다. 현재 녹스에서 돌아가고 있는 어플은 인시큐어뱅크 앱 뿐이므로 4538이 인시큐어 뱅크가 사용하고 있는 포트번호가 됩니다.
> nox_adb jdwp
2.3. 이후 nox_adb 를 통해 디버깅 포트를 로컬 포트로 포트포워딩을 해준 후 , jdb 명령어를 통해 로컬 디버깅 포트로 연결할 것입니다. 포트포워딩을 위하여 아래의 명령어를 입력합니다.
> nox_adb forward tcp:11111 jdwp:4538
2.4. 그리고 jdb사용을 위해서 jdb가 있는 폴더로 이동합니다. 주로 C:\Program Files\Java\jdk-23\bin 경로에 존재합니다. 이동을 하셨으면 해당 명령어를 통해 nox와 포트포워딩 되어있는 로컬포트인 11111을 로컬 디버깅 포트로 연결해줍니다.
<JDB 명령어 표>
명령어 | 사용법 | 설명 |
Next | >next | 다음 라인 실행 |
Local | >local | 현재 로컬 영역 변수 보기 |
threads | >threads | 현재 실행 중인 스레드 확인 |
methods | >methods 클래스 명 | 해당 클래스가 사용하는 모든 메서드 출력 |
stop in | >stop in 메서드 | 특정 메서드에 브레이크 포인트 설정 |
>print 특정변수 | 특정 변수의 값 출력 | |
eval | >eval 자바코드 | 자바코드를 실행시킴. |
run | >run | 현재 브레이크 포인트 무시하고 실행 |
2.5. 이제 JDB를 사용해서 무단으로 비밀번호를 바꿔볼 것입니다. 우선 해당 명령어를 통해 ChangePassword 액티비티를 강제 실행해봅니다! 아래 표에서 보시다시피 정상적으로 실행하면 Username 값이 디폴트로 적혀있어야 하는데 강제 실행을 하게되면 Username 칸이 비게됩니다. 이를 JDB를 통하여 동적으로 dinesh라는 글자를 채워넣어주겠습니다.
> nox_adb shell am start -n com.android.insecurebankv2/.ChangePassword
강제실행 했을때 결과 | 정상실행 했을때 결과 |
2.6. ChangePassword 액티비티가 실행될때 Username 변수값을 dinesh로 바꾸면 되는것이니, 강제실행 하는 중간에 동작을 멈춘후 Username 값을 넣어주어야 합니다. 브레이크 포인트를 잡기 위해서 우선 Jadx에서 ChangePassword 액티비티의 Smali 코드를 확인해봅시다. 우선 액티비티를 시작하는 함수인 oncreate 함수를 찾아서 브레이크를 걸어보도록 하죠!
사진을 보시면 75번째 라인이 onCreate 가 시작하는 지점이라고 표시되어 있습니다!
2.7. 이제 아래 명령어를 통해 onCreate 부분에서 브레이크포인트를 걸어줍니다.
> stop in com.android.insecurebankv2.ChangePassword.onCreate
2.8. 이제 다시 액티비티를 강제 실행시키면 해당 문구가 뜨면서 중간에 브레이크가 걸린것을 확인하실 수 있습니다! 위에 Smali 코드에서 확인했듯이 75번째 라인을 가르키고 있습니다.
> nox_adb shell am start -n com.android.insecurebankv2/.ChangePassword (액티비티 강제실행)
2.9. Smail 코드를 다시 살펴보시면 uname 이라는 변수가 설정되는 라인은 85번째 라인이라는 것을 알 수 있습니다. 그러면 next 명령어를 써서 85번째 라인까지 진행해보도록 하겠습니다.
2.10. 86번째 라인까지 next 명령어를 통해 진행시켜 주었습니다. 왜냐하면 uname 이라는 변수가 선언이 되어야 메모리상에 올라간 뒤 변수값을 JDB를 통해 조작할 수 있기 때문입니다.
2.11. 현재 uname 값을 확인하는 명령어로는 "print this.전역 변수 이름" 를 사용하면 됩니다. 이제 해당 명령어를 통해 차례대로 uname 값이 조작하고 조작된 것을 확인하실 수 있습니다!
> print this.uname (현재 uname 이란 전역변수의 값 확인)
> set this.uname = "dinesh"(uname 변수값으로 dinesh 라는 문자열 넣어주기)
> print this.uname (변경된 uname 값 확인)
2.12. 이제 uname 값이 바뀐것도 확인했으니 run 명령어를 입력하여 중단했던 액티비티를 진행시켜줍니다.
2.13. 실행된 액티비티의 dinesh 라는 Username이 삽입된 것을 확인하실 수 있습니다. 이제 Password를 바꿔보겠습니다.
2.14. 성공적으로 패스워드가 바뀌었다는 문구를 확인하실 수 있습니다. 이를통해 디버깅 취약점을 통한 런타임 조작이 얼마나 위험한 공격으로 이어지는지 실습을 통해 확인해보았습니다!!
3. 대응방안
1. Android:debuggable="false" 설정
> 제가 이 공격을 시도하게된 궁극적인 포인트는 Android:debuggable="true" 설정이 되어있음에서 시작되었습니다. 그러니 이 설정을 false 로 바꿔서 동적 디버깅이 불가능하도록 만들어야 합니다.
2. 소스코드 난독화
> 소스코드 난독화를 코드의 적용하면 제가 Smali 코드를 손쉽게 따라가는 것을 방지할 수 있습니다. 즉 위의 실습처럼 흐름을 쉽게 파악하여 공격 포인트를 바로 잡아내지 못하게 됩니다.
이 동적디버깅을 완벽히 100% 막을수 있는 방법은 현재로서는 없습니다.. 따라서 심층 보안 개념을 적용해 공격자가 쉽게 공격하지 못하도록 겹겹이 보안을 적용하는 것이 바람직합니다!
긴 글 읽어주셔서 감사합니다!
'모바일 앱해킹(Android) > Insecure Bank' 카테고리의 다른 글
[Insecure Bank] 안전하지 않은 SD 카드 저장소 (0) | 2024.12.13 |
---|---|
[Insecure Bank] 안드로이드 백업 취약점 (0) | 2024.12.12 |
[Insecure Bank] 안드로이드 키보드 캐시 이슈 (0) | 2024.12.10 |
[Insecure Bank] 안전하지 않은 로깅 메커니즘 취약점 (0) | 2024.12.08 |
[Insecure Bank] 메모리 내 민감한 정보 저장 (0) | 2024.12.06 |