Re: NULL Pointer Dereference in help()

2022-07-07 Thread Simon Josefsson via Bug reports for the GNU Internet utilities
Erik Auerswald  writes:

> On Thu, Dec 23, 2021 at 09:15:59PM +0800, AiDai wrote:
>> Line 1: # NULL Pointer Dereference in help() at
>> inetutils/telnet/commands.c:3094
>
> Thanks for fuzzing GNU inetutils!

Hi AiDai and Erik.  Thanks for the report, debugging and patch!

I installed your fixes and a regression self-check:

https://git.savannah.gnu.org/gitweb/?p=inetutils.git;a=commitdiff;h=0e5767771a89498f8a9fa65733321b5e1107cace
https://git.savannah.gnu.org/gitweb/?p=inetutils.git;a=commitdiff;h=fe1c596e029cab03271190674fe715d2d0ed8d26
https://git.savannah.gnu.org/gitweb/?p=inetutils.git;a=commitdiff;h=9a2a28719e9f84e8bc6506e50d5e7d0735ace1d7

/Simon


signature.asc
Description: PGP signature


Re: NULL Pointer Dereference in help()

2022-02-12 Thread Erik Auerswald
Hi,

On Thu, Dec 23, 2021 at 09:15:59PM +0800, AiDai wrote:
> Line 1: # NULL Pointer Dereference in help() at
> inetutils/telnet/commands.c:3094

Thanks for fuzzing GNU inetutils!

> AiDai  于2021年12月23日周四 21:13写道:
> 
> > **command:**
> >
> > ```
> > ./telnet < ./poc
> > ```
> >
> >> ## Description
> >>
> >> A NULL Pointer Dereference was discovered in help() at
> >> inetutils/telnet/commands.c:3094. The vulnerability causes a segmentation
> >> fault and application crash.

This problem occurs when asking for the help text for the help command
using the name "help" instead of "?":

$ telnet/telnet
telnet> help ?
print help information
telnet> help help
Segmentation fault (core dumped)

The cause is no help text for "help" in cmdtab2.  This is valid according
to the comments describing "struct Command":

typedef struct
{
  const char *name; /* command name */
  const char *help; /* help string (NULL for no help) */
  int (*handler) ();/* routine which executes command */
  int needconnect;  /* Do we need to be connected to execute? */
} Command;

But the code in help() only checks this when given no arguments, not
with arguments to "help".

The first attached patch "inetutils-telnet-dont_print_nonexistent_help.patch"
fixes this.

This is the correct fix for this issue.

The second attached patch "inetutils-telnet-use_help_helptext.patch" adds
the existing help text for the help command to cmdtab2.  This also fixes
the NULL pointer dereference, but only for the "help" entry.  This suffices
currently, because this is the only entry without a help text, but
providing no help text is intended as valid and thus must be handled.  Thus
this is intended to improve the user experience, not as a fix for following
a NULL pointer into chaos and madness.

Thanks,
Erik
-- 
Golden rule #12: When the comments do not match the code, they probably
 are both wrong.
-- Steven Rostedt
diff --git a/telnet/commands.c b/telnet/commands.c
index 9e04944f..3b05800f 100644
--- a/telnet/commands.c
+++ b/telnet/commands.c
@@ -3090,7 +3090,7 @@ help (int argc, char *argv[])
 	printf ("?Ambiguous help command %s\n", arg);
   else if (c == (Command *) 0)
 	printf ("?Invalid help command %s\n", arg);
-  else
+  else if (c->help)
 	printf ("%s\n", c->help);
 }
   return 0;
diff --git a/telnet/commands.c b/telnet/commands.c
index 9e04944f..4cd01beb 100644
--- a/telnet/commands.c
+++ b/telnet/commands.c
@@ -2931,7 +2931,7 @@ static char crmodhelp[] = "deprecated command -- use 'toggle crmod' instead";
 static char escapehelp[] = "deprecated command -- use 'set escape' instead";
 
 static Command cmdtab2[] = {
-  {"help", 0, help, 0},
+  {"help", helphelp, help, 0},
   {"escape", escapehelp, setescape, 0},
   {"crmod", crmodhelp, togcrmod, 0},
   {NULL, NULL, NULL, 0}


Re: NULL Pointer Dereference in help()

2021-12-23 Thread AiDai
**command:**

```
./telnet < ./poc
```

AiDai  于2021年12月23日周四 21:11写道:

> # NULL Pointer Dereference in setnmap() at cmds.c:2303
>
> ## Description
>
> A NULL Pointer Dereference was discovered in help() at
> inetutils/telnet/commands.c:3094. The vulnerability causes a segmentation
> fault and application crash.
>
> **version**
>
> ```
> ./telnet --version
> telnet (GNU inetutils) 2.2.16-cf091
> Copyright (C) 2021 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or later <
> https://gnu.org/licenses/gpl.html>.
> This is free software: you are free to change and redistribute it.
> There is NO WARRANTY, to the extent permitted by law.
>
> Written by many authors.
> ```
>
> **System information**
> Ubuntu 20.04 focal, AMD EPYC 7742 64-Core @ 16x 2.25GHz
>
> ## Proof of Concept
>
> **poc**
>
> ```
> base64 poc
>
> ID8JCQn/CQn/CQj/CQlkCQkJCQnwCQkJCQloCQkJCQn/CQlkCQkJCQnwCQkJ7ekJCQkJ
> CQkJCeoICQkZCQkJKiwJCQkJCQkJCQkJCQk=
> ```
>
> **command:**
>
> ```
> ./ftp < ./poc
> ```
>
> **Result**
>
> ```
> ./telnet < poc
> telnet> ?Invalid help command �
> ?Invalid help command �
> ?Invalid help command
> display operating parameters
> ?Invalid help command �
> [3]398703 segmentation fault  ./telnet < poc
> ```
>
> **gdb**
>
> ```
> Breakpoint 2, 0xdbd3 in help (argc=8, argv=0x5557c130
> ) at commands.c:3094
> 3094printf ("%s\n", c->help);
> LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
> [ REGISTERS
> ]─
> *RAX  0x0
> *RBX  0x5557b480 (cmdtab2) —▸ 0x55571232 ◂— 0x6f6400706c6568 /*
> 'help' */
>  RCX  0x0
> *RDX  0xc6
> *RDI  0x0
> *RSI  0x555719cc ◂— 0x646f6d7263 /* 'crmod' */
>  R8   0x0
> *R9   0x18
>  R10  0x55572ee2 ◂— 0x2500454d4f48000a /* '\n' */
>  R11  0x246
> *R12  0x5557befd (line+29) ◂— 0x090909090068 /* 'h' */
>  R13  0x7fffe210 ◂— 0x1
>  R14  0x0
>  R15  0x0
>  RBP  0x7fffe060 —▸ 0x7fffe090 —▸ 0x7fffe120 ◂— 0x0
>  RSP  0x7fffe040 —▸ 0x5557c130 (margv+48) —▸ 0x5557befd
> (line+29) ◂— 0x090909090068 /* 'h' */
>  RIP  0xdbd3 (help+212) ◂— call   0x9790
> ──[ DISASM
> ]──
>0xdbcc movrax, qword ptr [rbx + 8]
>0xdbd0 movrdi, rax
>  ► 0xdbd3 call   puts@plt
> s: 0x0
>
>0xdbd8 subdword ptr [rbp - 0x14], 1
>0xdbdc cmpdword ptr [rbp - 0x14], 0
>0xdbe0 jg help+116
>
>0xdbe2 moveax, 0
>0xdbe7 addrsp, 0x10
>0xdbeb poprbx
>0xdbec popr12
>0xdbee poprbp
> ──[ SOURCE (CODE)
> ]───
> In file: /root/disk2/fuzzing/inetutils/inetutils/telnet/commands.c
>3089   if (Ambiguous (c))
>3090 printf ("?Ambiguous help command %s\n", arg);
>3091   else if (c == (Command *) 0)
>3092 printf ("?Invalid help command %s\n", arg);
>3093   else
>  ► 3094 printf ("%s\n", c->help);
>3095 }
>3096   return 0;
>3097 }
>3098
>3099 static char *rcname = 0;
> ──[ STACK
> ]───
> 00:│ rsp 0x7fffe040 —▸ 0x5557c130 (margv+48) —▸ 0x5557befd
> (line+29) ◂— 0x090909090068 /* 'h' */
> 01:0008│ 0x7fffe048 ◂— 0x85557bee1
> 02:0010│ 0x7fffe050 —▸ 0x5557b440 (cmdtab+480) —▸
> 0x5557121b ◂— 0x616c70736944003f /* '?' */
> 03:0018│ 0x7fffe058 —▸ 0x9d20 (_start) ◂— endbr64
> 04:0020│ rbp 0x7fffe060 —▸ 0x7fffe090 —▸ 0x7fffe120 ◂— 0x0
> 05:0028│ 0x7fffe068 —▸ 0xdab9 (command+550) ◂— test   eax,
> eax
> 06:0030│ 0x7fffe070 ◂— 0x0
> 07:0038│ 0x7fffe078 ◂— 0x1
> [ BACKTRACE
> ]─
>  ► f 0   0xdbd3 help+212
>f 1   0xdab9 command+550
>f 2   0xe3c8 main+776
>f 3   0x77db50b3 __libc_start_main+243
>
> ──
> pwndbg> bt
> #0  0xdbd3 in help (argc=8, argv=0x5557c130 ) at
> commands.c:3094
> #1  0xdab9 in command (top=1, tbuf=0x0, cnt=0) at
> commands.c:3044
> #2  0xe3c8 in main (argc=0, argv=0x7fffe220) at main.c:423
> #3  0x77db50b3 in __libc_start_main (main=0xe0c0 ,
> argc=1, argv=0x7fffe218, init=, fini=,
> rtld_fini=, stack_end=0x7fffe208) at
> ../csu/libc-start.c:308
> #4  0x9d4e in _start ()
> ```
>
> crash
>
> ```
> Program received signal SIGSEGV, Segmentation