Hi Frederic,
At 2024-05-29T05:21:38+0200, Frederic Chartier via wrote:
> On 2024-05-20 09:00 -0500, G. Branden Robinson wrote:
> > For grins, and for a data point from elsewhere in GNU-land, GNU
> > troff is pretty robust to this sort of thing. Much as I might like
> > to boast of having improved it in this area, it appears to have
> > already come with iron long johns courtesy of James Clark and/or
> > Werner Lemberg. I threw troff its own ELF executable as a crude
> > fuzz test some years ago, and I don't recall needing to fix anything
> > except unhelpfully vague diagnostic messages (a phenomenon I am
> > predisposed to observe anyway).
> >
> > I did notice today that in one case we were spewing back out
> > unprintable characters (newlines, character codes > 127) _in_ one
This would have better said "character codes > 159"; see below.
> > (but only one) of the diagnostic messages, and while that's ugly,
> > it's not an obvious exploitation vector to me.
>
> Going off-topic but I need a clarification. Are you saying that
> you wouldn't consider writing arbitrary characters to a terminal
> a security risk ?
In _groff_? No.
> To rephrase that in the form of a scenario :
>
> 1. Attacker crafts file that, when directly or indirectly
>processed by our program, causes it to include string /s/ in
>an error message,
>
> 2. Victim runs our program. Error message goes to standard error
>which is written to the victim's terminal.
>
> Is there no value of /s/ that could be considered harmful ?
I would not make that claim.
However, this is not groff's problem to solve. Its programs' standard
error streams (like its standard output streams) can be redirected.
Consider:
groff -Tps -mm whatever.mm > /dev/sda
Clearly, if one has write privileges to /dev/sda, this is an obvious
denial-of-service attack (assuming a device "lives" at /dev/sda). And
possibly something worse if whatever.mm is a nefariously crafted
document. (It could, perhaps, use `output` or `device` requests to
inject interesting material into the output despite postprocessing by
grops(1).)
But, in normal circumstances, redirecting output streams to files
(mundane files, not block devices) is not considered a hazardous
operation.
So what if one of those streams goes to a terminal emulator?
Well, certainly, a terminal emulator, or a shell, can decide to perform
any operation it wants upon receiving certain input.
I can do the following today without leveraging any sloppy handling of
diagnostic messages in GNU troff.
$ `printf '.tm rm -rf /\n' | groff 2>&1` # DO NOT RUN THIS
Even worse, if someone tricks me into specifying the `-U` flag...
$ `printf '.sy rm -rf /\n' | groff -U` # DO NOT RUN THIS, EITHER
But these hazards have been well known for decades and the latter is why
GNU troff _has_ "safer" mode as a default, whereas AT&T troff did not.
I have certainly seen terminal emulator (mis)behavior such that, after
accidentally catting some binary file to the terminal, some garbage
characters got stuffed back into the input stream and populated my shell
prompt, and, alarmingly, would be executed by the shell if I pressed
enter without killing the line first.
I haven't seen that problem in years. As I understand it, the
"bracketed paste mode" now supported by GNU Bash (and some other shells)
and by the XTerm teminal emulator (possibly among others), have closed
this door. (Perhaps bracketed paste mode proper didn't close this
security hole, but contemporaneous work around it did. I'm pretty vague
on the history. Anyone have any pointers to good resources?)
I'd say that, largely, the problem that concerns you is one that shells
and terminal emulators need to address, and to my knowledge, they have.
There does remain another point to consider. What, exactly, _can_ be
injected into the standard error stream by the mechanism described
earlier in the thread?
Here is the new diagnostic (still awaiting my push--I've had my
attention on other things for a few days).
35 troff:/usr/bin/troff: error: invalid positional argument number
(unprintable)
This diagnostic occurs only when an invalid escape sequence of the form
\$1
\$2
\$3
...
\$9
or
\$(01
...
\$(99
or (in a GNU troff extension)
\$[12345]
is encountered.
Unless you can wreak havoc with only 1 or 2 bytes, the first two look
like an unlikely vector. Can your exploit tolerate interruption by a
newline and another *roff diagnostic message?
So let's try something.
$ hd /tmp/branden/nefarious.groff
2e 74 6d 20 74 68 69 73 20 69 73 20 61 20 74 65 |.tm this is a te|
0010 73 74 20 6f 66 20 73 65 74 74 69 6e 67 20 74 68 |st of setting th|
0020 65 20 78 74 65 72 6d 20 74 69 74 6c 65 20 76 69 |e xterm title vi|
0030 61 20 61 20 67 72 6f 66 66 20 64 6f 63 75 6d 65 |a a groff docume|
0040 6e 74 0a 48 65 6c 6c 6f 2c 20 5c 24 5b 1b 5d 30 |nt.Hello, \$[.]0|
0050 3b 65 76 69 6c 20 6c 61 75 67 68 74 65 72 07 5d |;evil