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

Reply via email to