xorl %eax, %eax

CVE-2009-1210: Wireshark PROFINET/DCP Format String

leave a comment »

This bug was disclosed on 1 April 2009 a PoC code by  THCX. If affects wireshark 0.99.6 through 1.0.6. PROFINET is provided as a plug-in on Wireshark. You can easily disable it. Anyway, here is the bug:

1 /* packet-pn.c
2  * Common functions for other PROFINET protocols like IO, CBA, DCP, ...   
...
272 /* append the given info text to item and column */
273 void
274 pn_append_info(packet_info *pinfo, proto_item *dcp_item, const char *text)
275 {
276     if (check_col(pinfo->cinfo, COL_INFO))
277         col_append_fstr(pinfo->cinfo, COL_INFO, text);
278
279     proto_item_append_text(dcp_item, "%s", text);
280 }

This function from plugins/profinet/packet-pn.c and it uses col_append_fstr() (line 277) to append text (its third argument) to pinfo->cinfo column. However, the correct call should be:

col_append_fstr(pinfo->cinfo, COL_INFO, "%s", text);

Since this routine (as seen in epan/column-utils.h) is used to append a string to a column and requires a format string specifier (that’s what that ‘f’ on fstr stands for). Here is its prototype:

164 /** Append the given text to a column element, the text will be formatted and copied.
165  *
166  * Same function as col_append_str() but using a printf-like format string.
167  *
168  * @param cinfo the current packet row
169  * @param col the column to use, e.g. COL_INFO
170  * @param format the format string
171  * @param ... the variable number of parameters
172  */
173 extern void     col_append_fstr(column_info *cinfo, gint col, 
173 const gchar *format, ...)
174     GNUC_FORMAT_CHECK(printf, 3, 4);

So… the above one is a common format string vulnerability. It was patched like this:

     if (check_col(pinfo->cinfo, COL_INFO))
-        col_append_fstr(pinfo->cinfo, COL_INFO, text);
+        col_append_str(pinfo->cinfo, COL_INFO, text);

Since col_append_str() doesn’t require a format string. A similar bug was also present at plugins/profinet/packet-pn-rt.c:

1 /* packet-pn-rt.c
2  * Routines for pn-rt (PROFINET Real-Time) packet dissection.
3  * This is the base for other PROFINET protocols like IO, CBA, DCP, ...
4  * (the "content subdissectors" will register themselves using a heuristic)   
...
93 /*
94  * dissect_pn_rt - The dissector for the Soft-Real-Time protocol
95  */
96 static void
97 dissect_pn_rt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
98 {
   ...
112   gchar szFieldSummary[100];
   ...
281                 g_snprintf (szFieldSummary, sizeof(szFieldSummary),
282                                   "%sID:0x%04x, Len:%4u, Cycle:%5u (%s,%s,%s,%s)",
283                                 pszProtAddInfo, u16FrameID, tvb_len - 2 - 4, u16 CycleCounter,
284                             (u8DataStatus & 0x04) ? "Valid" : "Invalid",
285                             (u8DataStatus & 0x01) ? "Primary" : "Backup",
286                             (u8DataStatus & 0x20) ? "Ok" : "Problem",
287                             (u8DataStatus & 0x10) ? "Run" : "Stop");
   ...
357         /* update column info now */
358     if (check_col(pinfo->cinfo, COL_INFO))
359       col_add_fstr(pinfo->cinfo, COL_INFO, szFieldSummary);
   ...
376 }


The call to col_add_fstr() at line 359 passes the completely user controlled szFieldSummary as a format string. Here is the patch to this one:

     if (check_col(pinfo->cinfo, COL_INFO))
-      col_add_fstr(pinfo->cinfo, COL_INFO, szFieldSummary);
+      col_add_str(pinfo->cinfo, COL_INFO, szFieldSummary);
        if (check_col(pinfo->cinfo, COL_PROTOCOL))


Written by xorl

April 13, 2009 at 14:23

Posted in bugs

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s