ARM ROP를 더 연습해보고 싶어서 마땅한 코드가 없을까 하고 고민하는 과정에서 어느 github를 발견했다.
https://github.com/Billy-Ellis/Exploit-Challenges 이 링크에서는 MarchO 버전의 컴파일된 코드로 ROP를 단계별로 수행하는 소스코드들의 모음집이 있다. 다행히도 소스코드가 있어 따로 라즈베리파이 ARMv7의 아키텍쳐로 따로 컴파일을 해주었다. ROP를 해결하는 방법을 단계별로 풀어나가볼 것이다. 일단 첫번째 코드는 다음과 같다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
char string[] = "date";
void change(){
strcpy(string,"ls");
printf("string changed.\n");
}
void secret(){
printf("executing string...\n");
system(string);
}
int main(){
printf("Welcome to ROPLevel1 for ARM!\n");
char buff[12];
gets(buff);
return 0;
}
컴파일은 아무런 옵션을 주지 않고 컴파일을 해주었고 ASLR환경은 꺼놓았다. ASLR을 킨 환경에서도 진행을 해볼것이다.
NX비트 말고는 아무런 보호기법을 적용하지 않았다.
ASLR도 0으로 환경을 꺼주었다. 이번 코드는 change함수가 실행되고 다시 change함수를 실행해서 string에 date값을 ls로 바꿔주는 일을 해야 한다. change함수를 실행후 secret함수를 실행하여 system("ls")가 실행되어야 한다.
gdb로 change 함수를 보면 0x00010464에서 push 명령어를 실행하여 스택에 r11과 lr을 저장한다. 그러나 main함수에서 overflow시켜 pc를 덮어 써줘서 change 함수를 실행 하려면 0x00010464주소로 branch 하면 안된다. 이 주소로 간다면 스택에 r11과 lr이 들어가 주소 0x00010494에서 pop 명령어를 실행할 때 스택에 원래 들어있던 r11과 lr의 값이 들어갈 것이다. 따라서 스택에 변화를 주지 않는 0x00010468부터 시작해야 한다.
그러면 명령어를 다음과 같이 쓸 수 있을 것이다. change함수로 branch 되어 0x00010468주소로 가게 되면 r11에는 더미값인 AAAA를 넣어주고 pc에는 secret함수가 실행 될 수 있게 0x000104a4 주소를 넣어주면 될 것이다.
secret함수가 마지막으로 call할 함수이므로 주소를 0x000104a8이 아닌 0x000104a4에서부터 시작해도 괜찮다.
완성된 명령어는 다음과 같다.
system에 들어갈 명령어가 date에서 ls로 바뀌어서 나타난다.
'ARM아키텍쳐' 카테고리의 다른 글
[ARM] Cross-Compiler 설치 (0) | 2023.01.11 |
---|---|
[ARM] roplevel2 (0) | 2020.06.26 |
[ARM] exploit RTL Chaining (0) | 2020.03.25 |
[ARM] Hello World!_Part 2 (0) | 2020.01.13 |
[ARM] Hello World!_Part 1 (0) | 2020.01.08 |