2018. 1. 15. 10:16, 워게임/Pwnable.kr
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #include <stdio.h> #include <fcntl.h> int key1(){ asm("mov r3, pc\n"); } int key2(){ asm( "push {r6}\n" "add r6, pc, $1\n" "bx r6\n" ".code 16\n" "mov r3, pc\n" "add r3, $0x4\n" "push {r3}\n" "pop {pc}\n" ".code 32\n" "pop {r6}\n" ); } int key3(){ asm("mov r3, lr\n"); } int main(){ int key=0; printf("Daddy has very strong arm! : "); scanf("%d", &key); if( (key1()+key2()+key3()) == key ){ printf("Congratz!\n"); int fd = open("flag", O_RDONLY); char buf[100]; int r = read(fd, buf, 100); write(0, buf, r); } else{ printf("I have strong leg :P\n"); } return 0; } | cs |
접속해서보면 gdb를 사용할 수 없습니다. 사용할 수 있으면 그냥 메모리를 들여다봐서 key를 보면 되니까 쉬울텐데 아쉽네요. 차근차근 풀어나가야할 것 같습니다. key1(), key2(), key3()이 어떤 값을 반환하는지 알아야겠네요. INTEL/AT&T에서는 함수의 리턴값을 eax에 두는데 arm에서는 r0에 둡니다. 이는 *main+48, +56, +68에서도 확인 가능합니다. pc는 program counter이고, 다음에 실행할 주소를 담고 있는데, 독특하게도 현재 주소의 +4가 아니라 +8을 가지고 있습니다. 이는 CPU가 Fetch/Decode/Execute를 동시에 진행하기 때문인데, 즉 Fetch - 0x1000 // Decode - 0x1004 // Execute - 0x1008 Fetch - 0x1004 // Decode - 0x1008 // Execute - 0x100C .
.
.
이런식으로 진행하기 때문에 Execute 되는 주소(=pc)는 Fetch하는 주소보다 8이 큰 값입니다.
lr은 link register이고, 함수를 호출하거나 어딘가로 점프를 했을 떄 돌아올 주소를 넣어두는 레지스터입니다.
그러면 key1의 값은 0x8cdc + 8 = 0x8ce4
key2의 값은 0x8d04 + 8 + 4 = 0x8d0c
key3의 값은 0x8d80(*main+68으로 돌아올 것이므로)입니다.
0x8ce4+0x8d0c+0x8d80 = 108400을 입력해주면 됩니다.
|
'워게임 > Pwnable.kr' 카테고리의 다른 글
[Pwnable.kr] coin1 (3) | 2018.01.15 |
---|---|
[Pwnable.kr] shellshock (0) | 2018.01.15 |
[Pwnable.kr] mistake (0) | 2018.01.15 |
[Pwnable.kr] input (0) | 2018.01.15 |
[Pwnable.kr] random (0) | 2018.01.15 |
[Pwnable.kr] passcode (0) | 2018.01.15 |
Comments