You are able to pass null bytes across a pipe (like you say in the title), but the bash
shell will not allow null bytes in expansions. It does not allow null bytes in expansions because the shell uses C strings to represent the results of expansions, and C strings are terminated by null bytes.
$ hexdump -C <<< $( python2 -c "print('c'*6+b'\x00'+'c'*6)" )
bash: warning: command substitution: ignored null byte in input
00000000 63 63 63 63 63 63 63 63 63 63 63 63 0a |cccccccccccc.|
0000000d
Passing the data across a pipe is fine:
$ python2 -c "print('c'*6+b'\x00'+'c'*6)" | hexdump -C
00000000 63 63 63 63 63 63 00 63 63 63 63 63 63 0a |cccccc.cccccc.|
0000000e
Redirecting a process substitution also works, as process substitutions don't expand to the data produced by the command but to the name of a file containing that data:
$ hexdump -C < <( python2 -c "print('c'*6+b'\x00'+'c'*6)" )
00000000 63 63 63 63 63 63 00 63 63 63 63 63 63 0a |cccccc.cccccc.|
0000000e
So, the solution is to avoid having the shell store the data containing the null byte in a string, and instead pass the data over a pipe, without using a command substitution. In your case
$ python2 -c "print('c'*6+b'\x00'+'c'*6)" | ./bf
Related:
Or switch to zsh
which does allow null bytes in strings:
$ hexdump -C <<< $( python2 -c "print('c'*6+b'\x00'+'c'*6)" )
00000000 63 63 63 63 63 63 00 63 63 63 63 63 63 0a |cccccc.cccccc.|
0000000e
od -c < <(python2 -c "print('c'*6+b'\x00'+'c'*6)")
– terdon Jun 03 '20 at 17:12