May 28, 2019

Assessing risk in Office documents - Part 3: Exploited “weaponized” RTFs

Kurt Natvig Principal Research Scientist

In part 3 of this 4-part blog series we focus on RTF (Rich-Text-Format) which is often the go-to format for obfuscating malicious code in Office documents. We’ll investigate what differentiates a hand-crafted RTF from clean documents and where we need to look for risk in RTF files. We will also have a look at an exploit - CVE-2017-11882 - hidden inside a RTF file.

In case you missed part 1 and part 2, here is the background: Forcepoint Innovation Labs conducted a research project to see if we can evaluate risk associated with Microsoft Office documents without focusing on specific malware families. Anti-virus-engines need to be able to classify a document as malicious to block it, while we want to evaluate the level of risk a document carry without those constraints. Code, or the possibility of getting any code in any form, adds risk. If the level of risk is unacceptable we can then block/quarantine the document on our gateways.

As you progress through the blog series you will build up the knowledge to assess risk instead of depending on a clear AV engine conviction.

Introduction to RTF

Rich-Text-Format (RTF) is not a commonly used format in the corporate world, especially when we focus on emails having RTF documents attached to them. As little as 0.11%-0.12% of total clean attachments over a week are sent using RTF (the statistics are from our cloud-based email gateways).

RTF is basically text. A simple RTF document having the words “hello world” can look as simple as this:

As you can see, it has sections described with { and }. Inside these sections there are keywords being applied, “\” is used to define the start of a new keyword. In this case rtf is the first keyword, and the parameter given is 1. The next is ansi with no parameter, then ansicpg set to 1252. The last keyword is pard with no parameter. What follows next is the data “hello world” which is sent to the current destination as characters. A destination is a keyword with special meaning. Not all keywords have the weight as a destination, but some do. This means that data following will be attached to the current destination.


In the example above:

  • \rtf is a keyword defined as a destination, will be set as current
  • \ansi is a keyword for flag dealing with the character-set
  • \ansicpg is a keyword for flag dealing with the character-set
  • \pard is a keyword for a flag dealing with paragraph formatting properties

That means in this simple example, the data “hello word” is attached to the rtf destination.

For a good source on the RTF specifications and valid keywords, check out Microsoft’s Rich Text Format (RTF) Specification 1.9.1.


Welcome to the real world of RTF

In part 2 we created a clean document with notepad.exe embedded into it and we saved it in the RTF format. Let’s examine this document to see what we shall expect Word to generate before we have a look at some of the malicious implementations. The document starts like this:

{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff0\deff0\stshfdbch39\stshfloch39\stshfhich39\stshfbi0\deflang2057\deflangfe2057\themelang2057\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;}

Armed with the knowledge from the introduction, we can easily decode these keywords, their parameters and the data which is to be attached to the current destination at the time:

rtf=1, adeflang=1025, ansi=0, ansicpg=1252, uc=1, adeff=0, deff=0, stshfdbch=39, stshfloch=39,stshfhich=39, stshfbi=0, deflang=2057, deflangfe=2057, themelang=2057, themelangfe=0, themelangcs=0
fonttbl=0, DATA: “Times New Roman;”
    f=0, fbidi,froman,fcharset=0,fprq=2
        panose DATA: 02020603050405020304
    f=34, fbidi, froman, fcharset=0, fprq=2
        panose DATA: 02020603050405020304
fonttable DATA += “Cambria Math;”

Here we can see the use of a \*\keyword like the \*\panose – which basically tells the RTF reader “if you don’t understand the keyword “panose”, just ignore it”. RTF has taken into account that different readers might be implementing the specification on different levels, and as a result, this provides a way to handle “unknown” keywords.


When we get to the embedded notepad.exe, the RTF keywords and data look like this:

{\object\objemb\objw1216\objh811{\*\objclass Package}{\*\objdata 0105000002000000080000005061636b6167650000000000000000002e9b0300


Let’s process this one thoroughly:

  • \object is a destination for “Objects” (set as current)
  • \objemb is a flag for “Objects”
  • \objw is a value (set to 1216) for “Objects”
  • \objh is a value (set to 811) for “Objects”
  • \objclass is a new destination for this new section starting with { having the data “Package” and then the new section ends with }
  • \*\objdata  (used in a way an RTF reader can ignore it if it doesn’t understand objdata) is a destination keyword for “Objects” started within a new section, hence data following now will be stored in the destination objdata, not in object.

Since objdata is a destination that have data defined as SDATA (hexadecimal data), the characters you see there needs to be converted to binary format.

As you can see, if we proceed systematically, it’s easy to follow and decode an RTF written by Word. That doesn’t seem to be complex or difficult in any way, does it? So what’s the real problem here?

How are malicious actors using RTF to hide their real intentions?

If you glance-over an RTF file without interpreting its content properly, you might miss out on a lot of malicious activity. In this section we’ll examine tricks used to make the documents harder to examine, and also possibly breaking detections from vendors not having a strong RTF parser.

Obfuscation can be considered as an ability to hide real content in “noise”. It can be

  • garbage that will be ignored
  • tricks to make it more difficult to understand what bytes mean what
  • tricks to throw of the RTF decoder in the wrong direction, skip a vital byte or insert a garbage byte that will ruin file integrity
  • simply re-packaging of the original document in several layers, making it more difficult to understand the flow if you have a look at the outer envelope only. 

There are different claims about obfuscation, so let’s discuss a few:

  • Obfuscation makes it more difficult to understand what’s underneath
    • Yes, you need to understand the layer to remove noise, encoding, compression and so on to reveal the real content
    • No, most vendors do have methods to remove obfuscation
  • Obfuscation makes it more difficult to detect something as malicious or risk
    • No, obfuscation tricks make it more difficult to say WHAT the malware is hiding beneath, but signs of obfuscations are used by many AV vendors to detect malware on generic terms. You can actually say obfuscation makes the document stand out even more as being malicious and result in being detected way easier.
  • Utilizing no obfuscation - having the output perfectly the way e.g. Microsoft Word normally would produce - might lower the chance of heuristic detections?
    • Yes, detection on the outer envelope (obfuscation layer) becomes “impossible” as it’s similar to the “golden standard”.
    • No, most vendors will keep unpacking layers until they fully understand the content and doesn’t bail out when the envelope is “perfectly formatted”.


Let’s start this time with a quite complex - CVE-2017-11882 - sample (Appendix B, Sample 1). We won’t go through all the details, but will focus on some of the tricks applied.

If you look at the sample in a text-editor, it’s more difficult to apply logic to the data you see compared to the normal use in files produced with Word. Unfortunately it is very easy to add obfuscation once Word produced the original RTF file, there are no counters or offsets to update, everything flows in one direction. For example, you can easily inject garbage wherever you want.

Let’s start with the declaration of \objdata, as we know this is an often-used destination for embedding objects. This sample has 2 objdata declarations, we are focusing on the first one.

As we’ve learned previously, the objdata is a keyword marked as a destination. That means the current destination going forward is objdata, all data found from this point on will enter objdata. It then starts a new section with { and use a \unknowntype keyword. This is an unknown keyword according to the RTF specification, and the parameter given will be ignored for our purpose. There is a limit to how big a parameter-string can be (0xFF) and data after this length is treated as data, even though it’s stored in the parameter space. It then starts a new section with { and use a new keyword \defpap. Defpap indeed is a keyword for another destination, so the garbage data following defpap will be stored in there, not objdata. This means all the above can be ignored when we focus on objdata, but its important to keep in mind that the first section has the destination objdata.

Let’s look at this:

A new section is opened, and the keyword “‘” is used. This is a special keyword declaring an ascii-hex-encoded byte is coming next. In this case, this is 0x3I – which isn’t valid in hex. Again, we can just ignore it (also we shall remember this when we talk about disappearing bytes in the next chapter).

Further down in data we find this while the objdata destination is active:

A new section is created with {, and an invalid keyword is given \mzeroAsc, which means the data following the keyword is ignored (41460354534219418497…27706148127968654831). Then the section is closed and the data d0cf11 will be entered into the objdata destination. Then the same trick is performed over and over again. So what is the purpose of this? They are trying to masquerade the actual data being stored on the objdata stream which will look like this after parsing:

d0 cf 11 e0 a1 b1 1a e1

That does surely look familiar! That’s the start of an OLE2 file which is embedded. If you don’t interpret the structures correctly you might miss it completely. Once again further down in data we find this:

It turns out \1 and \0 are special keywords. What happens here is that bytes are stored in the destination if the \0 and \1 keywords carry a second character.

  • \1 = no second character given, ignored
  • \16 = 6 is moved towards the destination
  • \1 = no second character given, ignored
  • \15 = 5 is moved towards the destination
  • \1 = no second character given, ignored
  • \10 = 0 is moved towards the destination

This means the current destination will get the following data when its decoded properly:

They are trying to hide the name inside the OLE2 file for the Ole10Native stream, which it knows several vendors will react to, and which is vital for the execution of the malicious code (as explained in part 2 of the blog series).

In the end, when we’ve processed the objdata destination – one of them will be this:

     0 : 88 D1 4E 04 02 00 00 00 12 00 00 00 42 35 36 53  | ..N.........B56S
    10 : 48 64 79 64 5A 61 59 7A 53 38 47 47 65 00 00 00  | HdydZaYzS8GGe...
    20 : 00 00 00 00 00 00 00 10 00 00 D0 CF 11 E0 A1 B1  | ................
    30 : 1A E1 00 00 00 00 00 00 00 00 00 00 00 00 00 00  | ................
    40 : 00 00 3E 00 03 00 FE FF 09 00 06 00 00 00 00 00  | ..>.............
    50 : 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00 00  | ................
    60 : 00 00 00 10 00 00 02 00 00 00 01 00 00 00 FE FF  | ................

As you’ve learned in part 2, this is a normal embedding of an OLE2 file into an RTF. When we run the original RTF sample against our research tool we find this:

-ScanObject("GENERIC_FS" (31:"HEX",8299,"1f5b6f979d5ef79f405a0bdfa58a4d28620fb8563e3393a975d5cb5a1ae13856|objdata_1")
       -ScanObject("MEM_FS" (1:"OLE2",4149,"1f5b6f979d5ef79f405a0bdfa58a4d28620fb8563e3393a975d5cb5a1ae13856|objdata_1|HEX")
              -ScanObject("OLE2_FS" (0:"UNKNOWN",1580,"1f5b6f979d5ef79f405a0bdfa58a4d28620fb8563e3393a975d5cb5a1ae13856|objdata_1|HEX|Root Entry/.Ole10Native")

The output basically tells us this RTF contains an OLE2 archive with an .Ole10Native stream even though it’s heavily obfuscated to begin with. Why do we think it is exploiting CVE-2017-11882? Let’s have a look.



There are a few things you need to understand about the OLE2 file embedded into this RTF. The first is that the Root Entry of the OLE2 file has an embedded class-ID (CLSID):

In clear text it looks like this: {0002ce02-0000-0000-c000-000000000046} and it means that the document must be treated as an EquationEditorFiles object. When we have a look at the data embedded into the .Ole10Native stream, it looks like this:

First, we find a minimum header that states the length of the object - 0x0628, then it goes straight into the data of an EquationEditorFiles object. The first 5 bytes are the MTEF header

02 D3 01 3D E2

In this case it means:

  • version - 2
  • generating platform - 0xd3
  • generating product - 0x01 (Equation Editor)
  • product version - 0x3d and sub-version - 0xe2

All of the above, except the version - which needs to be 2 or 3 - can be random. The following 2 bytes we can ignore, and now we get to the first record:

08 F5 A0 BA DB 33 2E 34 81 EA 9F 76 E8 33 8B 1A 8B 2B BF A4 53 

This means a Font Record (0x08), typeface number 0xF5, style 0xA0 and then a 40 (0x28) byte long buffer allowed for the font-name. As you can see in the dump of the entire stream above, the length is purposely more than 40 (0x28) and it will exploit the vulnerability and run its embedded code. Detection of this specific exploit is therefore easy, as long as you can decode all the layers until the final stage.

For a good read on CVE-2017-11882 and the EquationEditor exploit, refer to this article. At the time of writing of this blog, 32 of 55 engines on Virus Total detected this file as malicious.

In the real-world RTF can get abused in many ways. You saw keywords acting as destinations; but there are also destinations that don’t consume any data. Already being confused? As you can see in the Virus Total detection chart above, some AV engines detect it based only on obfuscation (they don’t know what it really is) while other engines were able to go through the obfuscation-layers and find the real exploitation of CVE-2017-11882.

Disappearing bytes

RTF readers tend to be very forgiving when it comes to interpreting documents. In this example we’ll examine something exploiting that (Sample 2). When we go through this RTF we find the objdata destination and we start to examine the bytes that follow to find out what its hiding:

Normally we expect a header starting with 0x????????02000000 (see part 2 for details), followed by the length of the name as a DWORD and then the actual name embedded – but this surely look very different. Did they just add garbage data and this isn’t the object containing the malicious part? Or did we take the wrong path?

The secret lays in bytes the RTF parser will ignore due to a bug. You can read more about the specific bug in this excellent article. It boils down to the Most-Significant-Byte (MSB) and the Least-Significant-Byte (LSB) being used in a way that the RTF renderer will “ignore” some specific bytes. If we start with the first equation 017: 0 and 1 are the MSB and LSB, and will be stored. 7 gets loaded as MSB, but the keyword for hex encoding “/’” now tells it to start again and the reader will ignore the half-started byte and unfortunately also the next complete byte too. It doesn’t have to be a valid hex-byte either, as it will be ignored either case. This pattern goes on so the original data will decode to the important data marked in red:

Which you can see match what we expect to start with: 0105000002000000. Now when we have the stream decoded properly, what does this object contain? Looking at the new header, it’s an OLE2 archive

with content of(using oledir from Decalage oletools):

If you recall part 2 of the blog series (embedding and linking) the .Ole structure (listed here with 240 bytes of data) can contain links to other objects. Let’s have a look at this object:

As you can see this document is a downloader that will download further components from the given URL using a URL Moniker.



In this part we’ve covered RTF in detail and the abuse malware authors apply to it to make it more difficult to reveal the real content of an RTF file. We’ve also covered an attack using the well-known CVE-2017-11882 vulnerability.


What is next in Part 4?

In part 4 - which is the final part of this series - we’ll focus on exploitation of more CVEs and on general exploit detection techniques for Office malware. We'll also see that Office macro source code isn't what you think

[UPDATE] 4 June 2019: Part 4 is now available.


Appendix A: hashes

Sample 1 - 1f5b6f979d5ef79f405a0bdfa58a4d28620fb8563e3393a975d5cb5a1ae13856

Sample 2 - 55e3211bca0a1c3ede72453ea04b886a06855328


Appendix B: tool output

Full output of Sample 1:

-ScanObject("GENERIC_FS" (10:"RTF",157939,"1f5b6f979d5ef79f405a0bdfa58a4d28620fb8563e3393a975d5cb5a1ae13856")
       -ScanObject("GENERIC_FS" (31:"HEX",5576,"1f5b6f979d5ef79f405a0bdfa58a4d28620fb8563e3393a975d5cb5a1ae13856|mzeroAsc_0")
              -ScanObject("MEM_FS" (0:"UNKNOWN",2562,"1f5b6f979d5ef79f405a0bdfa58a4d28620fb8563e3393a975d5cb5a1ae13856|mzeroAsc_0|HEX")
       -ScanObject("GENERIC_FS" (31:"HEX",8299,"1f5b6f979d5ef79f405a0bdfa58a4d28620fb8563e3393a975d5cb5a1ae13856|objdata_1")
              -ScanObject("MEM_FS" (1:"OLE2",4149,"1f5b6f979d5ef79f405a0bdfa58a4d28620fb8563e3393a975d5cb5a1ae13856|objdata_1|HEX")
                     -ScanObject("OLE2_FS" (0:"UNKNOWN",1580,"1f5b6f979d5ef79f405a0bdfa58a4d28620fb8563e3393a975d5cb5a1ae13856|objdata_1|HEX|Root Entry/.Ole10Native")
       -ScanObject("GENERIC_FS" (21:"TEXT",2899,"1f5b6f979d5ef79f405a0bdfa58a4d28620fb8563e3393a975d5cb5a1ae13856|mopEmu_2")
       -ScanObject("GENERIC_FS" (21:"TEXT",2899,"1f5b6f979d5ef79f405a0bdfa58a4d28620fb8563e3393a975d5cb5a1ae13856|writereservhash_3")
       -ScanObject("GENERIC_FS" (21:"TEXT",2899,"1f5b6f979d5ef79f405a0bdfa58a4d28620fb8563e3393a975d5cb5a1ae13856|defpap_4")
       -ScanObject("GENERIC_FS" (31:"HEX",2165,"1f5b6f979d5ef79f405a0bdfa58a4d28620fb8563e3393a975d5cb5a1ae13856|objdata_5")
              -ScanObject("MEM_FS" (0:"UNKNOWN",1082,"1f5b6f979d5ef79f405a0bdfa58a4d28620fb8563e3393a975d5cb5a1ae13856|objdata_5|HEX")
       -ScanObject("GENERIC_FS" (21:"TEXT",112834,"1f5b6f979d5ef79f405a0bdfa58a4d28620fb8563e3393a975d5cb5a1ae13856|object_6")
       -ScanObject("GENERIC_FS" (21:"TEXT",52,"1f5b6f979d5ef79f405a0bdfa58a4d28620fb8563e3393a975d5cb5a1ae13856|xmlnstbl_7")


Full output of Sample 2:

-ScanObject("GENERIC_FS" (10:"RTF",838277,"55e3211bca0a1c3ede72453ea04b886a06855328")
       -ScanObject("GENERIC_FS" (32:"OLEOBJ",2601,"55e3211bca0a1c3ede72453ea04b886a06855328|objdata_0")
              -ScanObject("MEM_FS" (1:"OLE2",2560,"55e3211bca0a1c3ede72453ea04b886a06855328|objdata_0|RTFOLEOBJECT|ole2link")
                     -ScanObject("OLE2_FS" (0:"UNKNOWN",6,"55e3211bca0a1c3ede72453ea04b886a06855328|objdata_0|RTFOLEOBJECT|ole2link|Root Entry/.ObjInfo")
                     -ScanObject("OLE2_FS" (0:"UNKNOWN",240,"55e3211bca0a1c3ede72453ea04b886a06855328|objdata_0|RTFOLEOBJECT|ole2link|Root Entry/.Ole")
                                  -ScanObject("URL_FS" (0:"UNKNOWN",0,"55e3211bca0a1c3ede72453ea04b886a06855328|objdata_0|RTFOLEOBJECT|ole2link|Root Entry/.Ole|serviced-163mail.com/stack-ny/overflow.php")
                     -ScanObject("OLE2_FS" (0:"UNKNOWN",183,"55e3211bca0a1c3ede72453ea04b886a06855328|objdata_0|RTFOLEOBJECT|ole2link|Root Entry/.LinkInfo")
       -ScanObject("GENERIC_FS" (21:"TEXT",15,"55e3211bca0a1c3ede72453ea04b886a06855328|objclass_1")
       -ScanObject("GENERIC_FS" (32:"OLEOBJ",1592,"55e3211bca0a1c3ede72453ea04b886a06855328|datastore_2")
              -ScanObject("MEM_FS" (1:"OLE2",1536,"55e3211bca0a1c3ede72453ea04b886a06855328|datastore_2|RTFOLEOBJECT|msxml2.saxxmlreader.6.0")
       -ScanObject("GENERIC_FS" (21:"TEXT",9338,"55e3211bca0a1c3ede72453ea04b886a06855328|lsdlockedexcept_3")
       -ScanObject("GENERIC_FS" (31:"HEX",1256,"55e3211bca0a1c3ede72453ea04b886a06855328|colorschememapping_4")
              -ScanObject("MEM_FS" (5:"XML",628,"55e3211bca0a1c3ede72453ea04b886a06855328|colorschememapping_4|HEX")
       -ScanObject("GENERIC_FS" (31:"HEX",12388,"55e3211bca0a1c3ede72453ea04b886a06855328|themedata_5")
              -ScanObject("MEM_FS" (7:"ZIP",6194,"55e3211bca0a1c3ede72453ea04b886a06855328|themedata_5|HEX")
                     -ScanObject("ARCHIVE_FS" (5:"XML",310,"55e3211bca0a1c3ede72453ea04b886a06855328|themedata_5|HEX|_rels/.rels")
                     -ScanObject("ARCHIVE_FS" (5:"XML",138,"55e3211bca0a1c3ede72453ea04b886a06855328|themedata_5|HEX|theme/theme/themeManager.xml")
                     -ScanObject("ARCHIVE_FS" (5:"XML",7089,"55e3211bca0a1c3ede72453ea04b886a06855328|themedata_5|HEX|theme/theme/theme1.xml")
                     -ScanObject("ARCHIVE_FS" (5:"XML",283,"55e3211bca0a1c3ede72453ea04b886a06855328|themedata_5|HEX|theme/theme/_rels/themeManager.xml.rels")
       -ScanObject("GENERIC_FS" (31:"HEX",96,"55e3211bca0a1c3ede72453ea04b886a06855328|blipuid_6")
              -ScanObject("MEM_FS" (0:"UNKNOWN",48,"55e3211bca0a1c3ede72453ea04b886a06855328|blipuid_6|HEX")
       -ScanObject("GENERIC_FS" (21:"TEXT",38,"55e3211bca0a1c3ede72453ea04b886a06855328|sv_7")
       -ScanObject("GENERIC_FS" (27:"BASE64",168,"55e3211bca0a1c3ede72453ea04b886a06855328|sn_8")
              -ScanObject("MEM_FS" (0:"UNKNOWN",126,"55e3211bca0a1c3ede72453ea04b886a06855328|sn_8|B64")
       -ScanObject("GENERIC_FS" (31:"HEX",745420,"55e3211bca0a1c3ede72453ea04b886a06855328|pict_9")
              -ScanObject("MEM_FS" (28:"JPEG",372710,"55e3211bca0a1c3ede72453ea04b886a06855328|pict_9|HEX")
       -ScanObject("GENERIC_FS" (21:"TEXT",5,"55e3211bca0a1c3ede72453ea04b886a06855328|pntxtb_10")
       -ScanObject("GENERIC_FS" (21:"TEXT",9,"55e3211bca0a1c3ede72453ea04b886a06855328|pntxta_11")
       -ScanObject("GENERIC_FS" (31:"HEX",4,"55e3211bca0a1c3ede72453ea04b886a06855328|wgrffmtfilter_12")
              -ScanObject("MEM_FS" (21:"TEXT",2,"55e3211bca0a1c3ede72453ea04b886a06855328|wgrffmtfilter_12|HEX")
       -ScanObject("GENERIC_FS" (21:"TEXT",52,"55e3211bca0a1c3ede72453ea04b886a06855328|xmlnstbl_13")
       -ScanObject("GENERIC_FS" (27:"BASE64",12,"55e3211bca0a1c3ede72453ea04b886a06855328|operator_14")
              -ScanObject("MEM_FS" (0:"UNKNOWN",6,"55e3211bca0a1c3ede72453ea04b886a06855328|operator_14|B64")
       -ScanObject("GENERIC_FS" (31:"HEX",4,"55e3211bca0a1c3ede72453ea04b886a06855328|author_15")
              -ScanObject("MEM_FS" (0:"UNKNOWN",2,"55e3211bca0a1c3ede72453ea04b886a06855328|author_15|HEX")
       -ScanObject("GENERIC_FS" (21:"TEXT",144,"55e3211bca0a1c3ede72453ea04b886a06855328|stylesheet_16")
       -ScanObject("GENERIC_FS" (21:"TEXT",18,"55e3211bca0a1c3ede72453ea04b886a06855328|colortbl_17")
       -ScanObject("GENERIC_FS" (27:"BASE64",16,"55e3211bca0a1c3ede72453ea04b886a06855328|falt_18")
              -ScanObject("MEM_FS" (0:"UNKNOWN",9,"55e3211bca0a1c3ede72453ea04b886a06855328|falt_18|B64")
       -ScanObject("GENERIC_FS" (31:"HEX",240,"55e3211bca0a1c3ede72453ea04b886a06855328|panose_19")
              -ScanObject("MEM_FS" (0:"UNKNOWN",120,"55e3211bca0a1c3ede72453ea04b886a06855328|panose_19|HEX")
       -ScanObject("GENERIC_FS" (0:"UNKNOWN",1328,"55e3211bca0a1c3ede72453ea04b886a06855328|fonttbl_20")
       -ScanObject("GENERIC_FS" (0:"UNKNOWN",118,"55e3211bca0a1c3ede72453ea04b886a06855328|rtf_21")

Kurt Natvig

Principal Research Scientist

Kurt Natvig is a Principal Research Scientist in Forcepoint's Innovation Lab. The Innovation Lab focuses on reducing the engineering-risk by researching and implementing proof-of-concepts beyond the roadmap.

Kurt is also heavily involved in reverse engineering malware and performs...

Read more articles by Kurt Natvig

About Forcepoint

Forcepoint is the leading user and data protection cybersecurity company, entrusted to safeguard organizations while driving digital transformation and growth. Our solutions adapt in real-time to how people interact with data, providing secure access while enabling employees to create value.