Control: retitle -1 ckermit: CVE-2025-68920: Malicious remote can overwrite and exfiltrate local files
On Mon, Dec 15, 2025 at 06:59:51PM -0600, John Goerzen wrote: > Package: ckermit > Version: 416~beta12-1 > Severity: grave > Tags: security patch upstream > Justification: user security hole > X-Debbugs-Cc: Debian Security Team <[email protected]> > > This security issue is a bit weird in that the behavior I'm covering here is > somewhat documented and was an explicit choice by upstream Kermit authors some > years back, which lingers today. (ckermit has been around since the 1980s and > security expectations were different then) > > Kermit, in its default configuration, permits a remote system to make changes > to, and retrieve data from, the local one. A malicious remote could damage > the > local system. This is roughly akin to connecting to a FTP server where the > FTP > server can also extract files from you, or change arbitrary files on your > system, without your involvement. > > In the default configuration, a remote system can: > > - change the working directory on the local > > - overwrite files in the current working directory on the local > > - download any arbitrary file from the local system > > Of course, by replacing files like .bashrc or such, a malicious remote could > easily cause malicious code to be executed on the local. Also, secret > exfiltration is easily possible with this. > > This seems, to me, to be a pretty critical security issue. The components of > it > are somewhat documented in kermit help text. I will admit to writing some > time > back, at https://www.complete.org/kermit/, that "If you connect to untrusted > remote systems, I recommend running disable all to prevent the remote from > doing > much to your local system other than sending files. For instance, rcd is > enabled > by default and allows the remote to change the directory for you to receive > files." But I didn't go the step further to question why this should be so > and > think through the security process. > > A simple patch will prevent it. > > The normal mode of using kermit is to run the kermit command on your local > system. Then, within kermit, you connect to a remote host in some way; > perhaps > with ssh, or maybe with a serial line or something. > > Then you can run kermit on the remote to interact with it. In some cases, in > fact, the local kermit will automatically send "kermit -r" (when sending files > to the remote) or "kermit -x" (when receiving files from the remote) to put > the > remote kermit in an appropriate receive or server mode. > > When kermit is in server mode, you can issue certain REMOTE commands to it. > REMOTE CD, REMOTE DELETE, REMOTE SEND, etc. These are all fine in the usual > case, where your local system is controlling a remote. > > Further detail: > > The remote system can send a series of bytes (actually a Kermit packet) that > can > put the local system into server mode also. This capability is typically used > to automatically start a file transfer when you type "kermit -s filename" to > the remote (or a similar SEND at a kermit prompt on the remote). This is > governed by the SET TERMINAL AUTODOWNLOAD setting. The help text states: > > SET TERMINAL AUTODOWNLOAD { ON, OFF, ERROR { STOP, CONTINUE } } > Enables/disables automatic switching into file-transfer mode when a valid > Kermit or ZMODEM packet of the appropriate type is received during CONNECT > mode. Default is OFF. > > When TERMINAL AUTODOWNLOAD is ON, the TERMINAL AUTODOWNLOAD ERROR setting > tells what to do if an error occurs during a file transfer or other > protocol operation initiated by the terminal emulator: STOP (the default) > means to remain in command mode so you can see what happened; CONTINUE > means to resume the CONNECT session (e.g. so a far-end script can continue > its work). > > This is actually incorrect about the default; the default is ON, as SHOW > TERMINAL shows "Autodownload: on, error stop". Autodownload doesn't just mean > the system will automatically download a file; it means it can automatically > enter server mode also. > > SET FILE COLLISION is set to BACKUP by default. > > This combines to make a nasty security situation. For instance, let's do a > test. The user is sitting at keyboardhost and is logging in to remotehost. > > First, we'll prepare a test directory: > > jgoerzen@keyboardhost:/$ cd /tmp > jgoerzen@keyboardhost:/tmp$ mkdir keyboardhosttest > jgoerzen@keyboardhost:/tmp$ cd keyboardhosttest > jgoerzen@keyboardhost:/tmp/keyboardhosttest$ echo 'Test file' > file1 > jgoerzen@keyboardhost:/tmp/keyboardhosttest$ cd / > > Now, we'll fire up kermit and ssh to a remote: > > jgoerzen@keyboardhost:/$ kermit > (/) C-Kermit>ssh remotehost > jgoerzen@remotehost:~$ > > Now, we'll make a new test file: > > jgoerzen@remotehost:~$ cd /tmp > jgoerzen@remotehost:/tmp$ echo 'Hi' > file1 > > And fire up kermit on the remote host, running inside the ssh session that is > inside our local kermit: > > jgoerzen@remotehost:/tmp$ kermit > (/tmp/) C-Kermit> > > Right now, our local kermit can't receive a bare file because its CWD is /, > which it doesn't have permission for. We can, in fact, see this: > > (/tmp/) C-Kermit>pwd > /tmp > (/tmp/) C-Kermit>remote pwd > Return to your local Kermit and give a SERVER command. > > KERMIT READY TO SEND SERVER COMMAND... > ---------------------------------------------------- > Entering server mode on ssh -e none remotehost > Type Ctrl-C to quit. > > C-Kermit server done > ---------------------------------------------------- > / > (/tmp/) C-Kermit> > > Now we can issue a command *ON REMOTEHOST* to change the directory on > keyboardhost: > > (/tmp/) C-Kermit>remote cd /tmp/keyboardhosttest > > And now we can send our own file: > > (/tmp/) C-Kermit>send file1 > Return to your local Kermit and give a RECEIVE command. > > KERMIT READY TO SEND... > SENT: [/tmp/file1] To: [/tmp/keyboardhosttest/file1] (OK) > > In a new terminal window on the local machine, we see: > > jgoerzen@keyboardhost:~$ ls -l /tmp/keyboardhosttest/ > total 2 > -rw-r--r-- 1 jgoerzen jgoerzen 3 Dec 4 07:24 file1 > -rw-rw-r-- 1 jgoerzen jgoerzen 10 Dec 4 07:22 file1.~1~ > > We have just allowed the remote machine to overwrite a file in an arbitrary > location on the local machine. > > We can't delete it though: > > (/tmp/) C-Kermit>remote del test1 > Return to your local Kermit and give a SERVER command. > > KERMIT READY TO SEND SERVER COMMAND... > Entering server mode on ssh -e none remotehost > Type Ctrl-C to quit. > > C-Kermit server done > > Even though this looks like it was successful, it wasn't. > > > Can remotehost extract arbitrary files from keyboardhost? Yes, it turns out: > > (/tmp/) C-Kermit>get /bin/bash > > or > > (/tmp/) C-Kermit>remote cd /bin > (/tmp/) C-Kermit>get bash > > both work. > > ckcmai.c defines: > > #ifndef NOSERVER > /* > Server services: > 0 = disabled > 1 = enabled in local mode > 2 = enabled in remote mode > 3 = enabled in both local and remote modes > only as initial (default) values. > */ > int en_xit = 2; /* EXIT */ > int en_cwd = 3; /* CD/CWD */ > int en_cpy = 3; /* COPY */ > int en_del = 2; /* DELETE */ > int en_mkd = 3; /* MKDIR */ > int en_rmd = 2; /* RMDIR */ > int en_dir = 3; /* DIRECTORY */ > int en_fin = 3; /* FINISH */ > int en_get = 3; /* GET */ > #ifndef NOPUSH > int en_hos = 2; /* HOST enabled */ > #else > int en_hos = 0; /* HOST disabled */ > #endif /* NOPUSH */ > int en_ren = 3; /* RENAME */ > int en_sen = 3; /* SEND */ > int en_set = 3; /* SET */ > int en_spa = 3; /* SPACE */ > int en_typ = 3; /* TYPE */ > int en_who = 3; /* WHO */ > #ifdef datageneral > /* Data General AOS/VS can't do this */ > int en_bye = 0; /* BYE */ > #else > int en_bye = 2; /* PCs in local mode... */ > #endif /* datageneral */ > int en_asg = 3; /* ASSIGN */ > int en_que = 3; /* QUERY */ > int en_ret = 2; /* RETRIEVE */ > int en_mai = 3; /* MAIL */ > int en_pri = 3; /* PRINT */ > int en_ena = 3; /* ENABLE */ > #else > int en_xit = 0, en_cwd = 0, en_cpy = 0, en_del = 0, en_mkd = 0, en_rmd = 0, > en_dir = 0, en_fin = 0, en_get = 0, en_hos = 0, en_ren = 0, en_sen = 0, > en_set = 0, en_spa = 0, en_typ = 0, en_who = 0, en_bye = 0, en_asg = 0, > en_que = 0, en_ret = 0, en_mai = 0, en_pri = 0, en_ena = 0; > #endif /* NOSERVER */ > > SHOW SERVER duplicates this: > > Function: Status: > GET Enabled > SEND Enabled > MAIL Enabled > PRINT Enabled > REMOTE ASSIGN Enabled > REMOTE CD/CWD Enabled > REMOTE COPY Enabled > REMOTE DELETE Remote only > REMOTE DIRECTORY Enabled > REMOTE HOST Remote only > REMOTE QUERY Enabled > REMOTE MKDIR Enabled > REMOTE RMDIR Remote only > REMOTE RENAME Enabled > REMOTE SET Enabled > REMOTE SPACE Enabled > REMOTE TYPE Enabled > REMOTE WHO Enabled > BYE Remote only > FINISH Enabled > EXIT Remote only > ENABLE Enabled > > keyboardhost can issue a "REMOTE DEL" to remotehost, but remotehost can't > issue > a "REMOTE DEL" to keyboardhost. > > So we can see that the remote system is able to control keyboardhost by > issuing > any command where the enable mode is 1 or 3 in ckcmai.c. Therefore, by > changing > these defaults, the issues can be mitigated. > > Note that "remote only" means the situation in which a kermit is in "remote > server" mode. This would be the case for the system you have ssh'd to, not > the > local system you're sitting at. > > https://www.kermitproject.org/ckututor.html describes: "To upload files (send > them from your desktop computer to the remote Unix computer) do the same > thing, > but use the -g (GET) option instead of -s on the remote computer: kermit -g > somefile.txt . This causes your local Kermit to enter server mode; then the > remote Kermit program requests the named file and the local Kermit sends it > and > returns automatically to Connect state when done. " > > https://www.columbia.edu/~fdc/misc/kermit-file-transfer-overview.html > > The attached patch adjusts these defaults. I have verified that the remote > system can no longer control the local one in that way, but the local one can > still control the remote one. This keeps all the usual use cases intact while > avoiding a more complex fate with DISABLE ALL. The one that it might break is > kermit -g filename, executed on the remote, which would normally cause the > local > system to transmit the given file. Of course, this is one of the most serious > exfiltration risks. The same transfer can easily (actually, MORE easily) be > initiated on the local system, without allowing the remote to have control, > using the local SEND command, so this is hardly a regression. > > With the patch, > > SHOW SERVER now shows: > > Function: Status: > GET Remote only > SEND Remote only > MAIL Remote only > PRINT Remote only > REMOTE ASSIGN Remote only > REMOTE CD/CWD Remote only > REMOTE COPY Remote only > REMOTE DELETE Remote only > REMOTE DIRECTORY Remote only > REMOTE HOST Remote only > REMOTE QUERY Remote only > REMOTE MKDIR Remote only > REMOTE RMDIR Remote only > REMOTE RENAME Remote only > REMOTE SET Remote only > REMOTE SPACE Remote only > REMOTE TYPE Remote only > REMOTE WHO Remote only > BYE Remote only > FINISH Remote only > EXIT Remote only > ENABLE Remote only > > A remote can still initiate a transfer to the local and give a filename > to save it in. This patch also disables the default "collision" mode, > which allows the remote to overwrite a local file (and renames the > original local file). There may still be some reason for concern for > allowing the remote to place a file with an arbitrary name in the > local's CWD, but this is also the behavior for zmodem (in lrzsz), and > some CLI HTTP clients that follow redirects and use the resulting name > for the local. It may not be ideal but it seems to match the generally > expected behavior. CVE-2025-68920 has been assigned for this issue. Regards, Salvatore

