Bash Scripting – Sending Null Byte in Unix Pipe

bashio-redirectionnull

I am trying to redirect python generated input to ELF 64-bit executable in bash 5.0.3. I am getting:

> ./bf <<< $(python2 -c "print('c'*6+b'\x00'+'c'*6)")
bash: warning: command substitution: ignored null byte in input
Enter password: Password didn't match
input: cccccccccccc

How can I allow a null byte in the input?

Best Answer

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
Related Question