Skip to content

Commit

Permalink
Escape control characters in log messages and "sudoreplay -l" output.
Browse files Browse the repository at this point in the history
The log message contains user-controlled strings that could include
things like terminal control characters.  Space characters in the
command path are now also escaped.

Command line arguments that contain spaces are surrounded with
single quotes and any literal single quote or backslash characters
are escaped with a backslash.  This makes it possible to distinguish
multiple command line arguments from a single argument that contains
spaces.

Issue found by Matthieu Barjole and Victor Cutillas of Synacktiv
(https://synacktiv.com).
  • Loading branch information
millert committed Jan 18, 2023
1 parent 77557f8 commit 334daf9
Show file tree
Hide file tree
Showing 10 changed files with 383 additions and 225 deletions.
44 changes: 34 additions & 10 deletions docs/sudoers.man.in
Original file line number Diff line number Diff line change
Expand Up @@ -5877,14 +5877,31 @@ can log events via
syslog(3),
to a local log file, or both.
The log format is almost identical in both cases.
Any control characters present in the log data are formatted in octal
with a leading
\(oq#\(cq
character.
For example, a horizontal tab is stored as
\(oq#011\(cq
and an embedded carriage return is stored as
\(oq#015\(cq.
In addition, space characters in the command path are stored as
\(oq#040\(cq.
Command line arguments that contain spaces are enclosed in single quotes
('').
This makes it possible to distinguish multiple command line arguments
from a single argument that contains spaces.
Literal single quotes and backslash characters
(\(oq\e\(cq)
in command line arguments are escaped with a backslash.
.SS "Accepted command log entries"
Commands that sudo runs are logged using the following format (split
into multiple lines for readability):
.nf
.sp
.RS 4n
date hostname progname: username : TTY=ttyname ; PWD=cwd ; \e
USER=runasuser ; GROUP=runasgroup ; TSID=logid ; \e
date hostname progname: username : TTY=ttyname ; CHROOT=chroot ; \e
PWD=cwd ; USER=runasuser ; GROUP=runasgroup ; TSID=logid ; \e
ENV=env_vars COMMAND=command
.RE
.fi
Expand Down Expand Up @@ -5933,6 +5950,9 @@ was run on, or
\(lqunknown\(rq
if there was no terminal present.
.TP 14n
chroot
The root directory that the command was run in, if one was specified.
.TP 14n
cwd
The current working directory that
\fBsudo\fR
Expand All @@ -5957,7 +5977,7 @@ A list of environment variables specified on the command line,
if specified.
.TP 14n
command
The actual command that was executed.
The actual command that was executed, including any command line arguments.
.PP
Messages are logged using the locale specified by
\fIsudoers_locale\fR,
Expand Down Expand Up @@ -6195,17 +6215,21 @@ with a few important differences:
1.\&
The
\fIprogname\fR
and
\fIhostname\fR
fields are not present.
field is not present.
.TP 5n
2.\&
If the
\fIlog_year\fR
option is enabled,
the date will also include the year.
The
\fIhostname\fR
is only logged if the
\fIlog_host\fR
option is enabled.
.TP 5n
3.\&
The date does not include the year unless the
\fIlog_year\fR
option is enabled.
.TP 5n
4.\&
Lines that are longer than
\fIloglinelen\fR
characters (80 by default) are word-wrapped and continued on the
Expand Down
38 changes: 30 additions & 8 deletions docs/sudoers.mdoc.in
Original file line number Diff line number Diff line change
Expand Up @@ -5503,12 +5503,29 @@ can log events via
.Xr syslog 3 ,
to a local log file, or both.
The log format is almost identical in both cases.
Any control characters present in the log data are formatted in octal
with a leading
.Ql #
character.
For example, a horizontal tab is stored as
.Ql #011
and an embedded carriage return is stored as
.Ql #015 .
In addition, space characters in the command path are stored as
.Ql #040 .
Command line arguments that contain spaces are enclosed in single quotes
.Pq '' .
This makes it possible to distinguish multiple command line arguments
from a single argument that contains spaces.
Literal single quotes and backslash characters
.Pq Ql \e
in command line arguments are escaped with a backslash.
.Ss Accepted command log entries
Commands that sudo runs are logged using the following format (split
into multiple lines for readability):
.Bd -literal -offset 4n
date hostname progname: username : TTY=ttyname ; PWD=cwd ; \e
USER=runasuser ; GROUP=runasgroup ; TSID=logid ; \e
date hostname progname: username : TTY=ttyname ; CHROOT=chroot ; \e
PWD=cwd ; USER=runasuser ; GROUP=runasgroup ; TSID=logid ; \e
ENV=env_vars COMMAND=command
.Ed
.Pp
Expand Down Expand Up @@ -5551,6 +5568,8 @@ or
was run on, or
.Dq unknown
if there was no terminal present.
.It chroot
The root directory that the command was run in, if one was specified.
.It cwd
The current working directory that
.Nm sudo
Expand All @@ -5570,7 +5589,7 @@ option is enabled.
A list of environment variables specified on the command line,
if specified.
.It command
The actual command that was executed.
The actual command that was executed, including any command line arguments.
.El
.Pp
Messages are logged using the locale specified by
Expand Down Expand Up @@ -5794,14 +5813,17 @@ with a few important differences:
.It
The
.Em progname
and
field is not present.
.It
The
.Em hostname
fields are not present.
is only logged if the
.Em log_host
option is enabled.
.It
If the
The date does not include the year unless the
.Em log_year
option is enabled,
the date will also include the year.
option is enabled.
.It
Lines that are longer than
.Em loglinelen
Expand Down
9 changes: 9 additions & 0 deletions docs/sudoreplay.man.in
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,15 @@ In this mode,
will list available sessions in a format similar to the
\fBsudo\fR
log file format, sorted by file name (or sequence number).
Any control characters present in the log data are formated in octal
with a leading
\(oq#\(cq
character.
For example, a horizontal tab is displayed as
\(oq#011\(cq
and an embedded carriage return is displayed as
\(oq#015\(cq.
.sp
If a
\fIsearch expression\fR
is specified, it will be used to restrict the IDs that are displayed.
Expand Down
10 changes: 10 additions & 0 deletions docs/sudoreplay.mdoc.in
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,16 @@ In this mode,
will list available sessions in a format similar to the
.Nm sudo
log file format, sorted by file name (or sequence number).
Any control characters present in the log data are formatted in octal
with a leading
.Ql #
character.
For example, a horizontal tab is displayed as
.Ql #011
and an embedded carriage return is displayed as
.Ql #015 .
Space characters in the command name and arguments are also formatted in octal.
.Pp
If a
.Ar search expression
is specified, it will be used to restrict the IDs that are displayed.
Expand Down
7 changes: 7 additions & 0 deletions include/sudo_lbuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,15 @@ struct sudo_lbuf {

typedef int (*sudo_lbuf_output_t)(const char *);

/* Flags for sudo_lbuf_append_esc() */
#define LBUF_ESC_CNTRL 0x01
#define LBUF_ESC_BLANK 0x02
#define LBUF_ESC_QUOTE 0x04

sudo_dso_public void sudo_lbuf_init_v1(struct sudo_lbuf *lbuf, sudo_lbuf_output_t output, int indent, const char *continuation, int cols);
sudo_dso_public void sudo_lbuf_destroy_v1(struct sudo_lbuf *lbuf);
sudo_dso_public bool sudo_lbuf_append_v1(struct sudo_lbuf *lbuf, const char *fmt, ...) sudo_printflike(2, 3);
sudo_dso_public bool sudo_lbuf_append_esc_v1(struct sudo_lbuf *lbuf, int flags, const char *fmt, ...) sudo_printflike(3, 4);
sudo_dso_public bool sudo_lbuf_append_quoted_v1(struct sudo_lbuf *lbuf, const char *set, const char *fmt, ...) sudo_printflike(3, 4);
sudo_dso_public void sudo_lbuf_print_v1(struct sudo_lbuf *lbuf);
sudo_dso_public bool sudo_lbuf_error_v1(struct sudo_lbuf *lbuf);
Expand All @@ -47,6 +53,7 @@ sudo_dso_public void sudo_lbuf_clearerr_v1(struct sudo_lbuf *lbuf);
#define sudo_lbuf_init(_a, _b, _c, _d, _e) sudo_lbuf_init_v1((_a), (_b), (_c), (_d), (_e))
#define sudo_lbuf_destroy(_a) sudo_lbuf_destroy_v1((_a))
#define sudo_lbuf_append sudo_lbuf_append_v1
#define sudo_lbuf_append_esc sudo_lbuf_append_esc_v1
#define sudo_lbuf_append_quoted sudo_lbuf_append_quoted_v1
#define sudo_lbuf_print(_a) sudo_lbuf_print_v1((_a))
#define sudo_lbuf_error(_a) sudo_lbuf_error_v1((_a))
Expand Down
Loading

0 comments on commit 334daf9

Please sign in to comment.