The bug is in update_volume
.
pglobal_data -> radio_data.speakers_volume[index] = new_volume;
index
is an int, it can take negative values too. Ideally you should not be able to access -ve indices in an array as it gives you read/write over memory area preceding the array. Here we just have a check to limit its max value to 4 but you can use negative integers to INT_MIN and overwrite a byte.
For exploitation, global_data
belongs to main's stack frame. Accessing negative indices you can overwrite a byte in return address of update_volume
(somewhere in main) on the stack. This gives you the primitive to jump to maybe hacked
or good
functions.
Resources: Use ASAN to verify your claims while fuzzing with inputs.
Here is the ASAN dump for this case.
ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-6.0/bin/llvm-symbolizer ./test
address of main: 0xCA77FE6F.
enter volume index:-36
enter new volume:65
updating the speaker -36 to volume 65
=================================================================
==27759==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffebfb3ff98 at pc 0x55f1ca77fe6f bp 0x7ffebfb3fed0 sp 0x7ffebfb3fec0
WRITE of size 1 at 0x7ffebfb3ff98 thread T0
#0 0x55f1ca77fe6e in update_volume /tmp/re.c:39
#1 0x55f1ca78004b in main /tmp/re.c:57
#2 0x7f237a433b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#3 0x55f1ca77fcf9 in _start (/tmp/test+0xcf9)
Address 0x7ffebfb3ff98 is located in stack of thread T0 at offset 136 in frame
#0 0x55f1ca77fe7e in main /tmp/re.c:47
This frame has 3 object(s):
[32, 36) 'index'
[96, 100) 'new_volume'
[160, 180) 'global_data' <== Memory access at offset 136 underflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /tmp/re.c:39 in update_volume
Shadow bytes around the buggy address:
0x100057f5ffa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100057f5ffb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100057f5ffc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100057f5ffd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100057f5ffe0: 00 00 f1 f1 f1 f1 04 f2 f2 f2 f2 f2 f2 f2 04 f2
=>0x100057f5fff0: f2 f2 f2[f2]f2 f2 00 00 04 f2 00 00 00 00 00 00
0x100057f60000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100057f60010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100057f60020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100057f60030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100057f60040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==27759==ABORTING
Please specify while posting if this a homework problem. We are happy to help but won't do all the job for you if you don't show any progress made/research done as @SYS_V mentioned in comments.
index
andnew_volume
) checked prior to being used in the program logic? have you been able to trigger an overflow, segfault, bug, error, unexpected behavior? what have you done to analyze this program for potential vulnerabilities? what is your approach to this problem? what is your reasoning?