0xrawsec / golang-evtx

GNU General Public License v3.0
157 stars 26 forks source link

PANIC - Not initialized slice: parsing *evtx.ValueText #12

Closed codekoala closed 5 years ago

codekoala commented 5 years ago

I see this error (with a stacktrace) 9 times in a simple 7MB .evtx file when using evtxdump -c thefile.evtx.

2019/05/14 16:02:16 PANIC - Not initialized slice: parsing *evtx.ValueText
 goroutine 1 [running]:
runtime/debug.Stack(0x5630fd3a98ef, 0xe, 0xc0000a9308)
        /usr/lib/go/src/runtime/debug/stack.go:24 +0x9f
github.com/0xrawsec/golang-utils/log.DontPanicf(0x5630fd3a98ef, 0xe, 0xc0000a9308, 0x2, 0x2)
        /home/wheaties/dev/go/pkg/mod/github.com/0xrawsec/golang-utils@v1.1.0/log/log.go:192 +0x8f
github.com/0xrawsec/golang-evtx/evtx.checkParsingError(0x5630fd534e00, 0xc0001e77a0, 0x5630fd537540, 0xc000399860, 0x5630fd535220, 0xc00014a6f0)
        /home/wheaties/dev/golang-evtx/evtx/parser.go:16 +0x113
github.com/0xrawsec/golang-evtx/evtx.Parse(0x5630fd537540, 0xc000399860, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
        /home/wheaties/dev/golang-evtx/evtx/parser.go:150 +0x81d
github.com/0xrawsec/golang-evtx/evtx.(*Attribute).Parse(0xc000409d80, 0x5630fd537540, 0xc000399860, 0x1, 0x2)
        /home/wheaties/dev/golang-evtx/evtx/structs.go:294 +0x246
github.com/0xrawsec/golang-evtx/evtx.(*AttributeList).ParseAttributes(0xc00040a158, 0x5630fd537540, 0xc000399860, 0xc00040a158, 0x5630fd53c8e0)
        /home/wheaties/dev/golang-evtx/evtx/structs.go:315 +0xb4
github.com/0xrawsec/golang-evtx/evtx.(*AttributeList).Parse(0xc00040a158, 0x5630fd537540, 0xc000399860, 0xccdc, 0x0)
        /home/wheaties/dev/golang-evtx/evtx/structs.go:333 +0xda
github.com/0xrawsec/golang-evtx/evtx.(*ElementStart).Parse(0xc00040a120, 0x5630fd537540, 0xc000399860, 0xccd1, 0x0)
        /home/wheaties/dev/golang-evtx/evtx/structs.go:190 +0x6d2
github.com/0xrawsec/golang-evtx/evtx.Parse(0x5630fd537540, 0xc000399860, 0x0, 0x1, 0x5630fd534e60, 0xc00049bede, 0x0, 0x0)
        /home/wheaties/dev/golang-evtx/evtx/parser.go:90 +0x1db
github.com/0xrawsec/golang-evtx/evtx.(*TemplateDefinitionData).Parse(0xc000409bc0, 0x5630fd537540, 0xc000399860, 0xcc26, 0x0)
        /home/wheaties/dev/golang-evtx/evtx/structs.go:714 +0x2af
github.com/0xrawsec/golang-evtx/evtx.(*Chunk).ParseTemplateTable(0xc0004d0800, 0x5630fd537540, 0xc000399860, 0x80, 0x0)
        /home/wheaties/dev/golang-evtx/evtx/chunk.go:163 +0x1f7
main.fetchChunkFromReader(0x5630fd538640, 0xc000010098, 0x3c1000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        /home/wheaties/dev/golang-evtx/tools/evtxdump/evtxdump.go:149 +0x37f
main.carveFile(0x7fff2a20c54b, 0x1c, 0x0, 0x0)
        /home/wheaties/dev/golang-evtx/tools/evtxdump/evtxdump.go:178 +0x355
main.main()
        /home/wheaties/dev/golang-evtx/tools/evtxdump/evtxdump.go:369 +0xa65
2019/05/14 16:02:16 ERROR - Not initialized slice

I haven't done much digging into the stack yet, but I can supply the .evtx file privately if necessary.

qjerome commented 5 years ago

Hi Josh, Any particular reason why you want to carve from an EVTX file? Did you try without the -c switch? Carving option is rather to use on a disk image. Anyway if the bug happens on the EVTX file it is very likely it would happen on a disk image too. If you don't mind to share the file I would be interested to get it in order to fix the bug.

codekoala commented 5 years ago

I used the carve option because without it evtxdump immediately crashed with that same error. Carving was just the one thing I tried that produced some kind of output. I only stumbled upon this project an hour or so ago, so I'm still learning the ropes :)

codekoala commented 5 years ago

@qjerome do you happen to have a GPG public key I can use to send an encrypted version of the .evtx file to you?

codekoala commented 5 years ago

You probably already knew this, but after doing a little digging it's obvious that evtxdump without the -c flag did not immediately crash. It just didn't offer any other output before the stacktrace, which caused me to make some assumptions.

qjerome commented 5 years ago

Yep, you can grab my GPG key there https://rawsec.lu/data/gpg/info@rawsec.lu.pub-gpg-key.txt I will dig into this, when I have time. Just a quick question about the context in which you got this file. Is this a file you got from a live acquisition (running system) or from a forensic image?

codekoala commented 5 years ago

Cool, thank you!

The .evtx file was created from a live system (which I no longer have) just a few days ago.

qjerome commented 5 years ago

Alright, that is very likely why there is parsing error, because EVTX on live system are not gently closed and some internal structure are only partial leading to further parsing issues. I will look at it and attempt to produce a fix for that.

codekoala commented 5 years ago

We may not be talking about the same thing. When I said it was from a live system, I meant that I pulled up the Windows Event Log Viewer (or whatever it's called) and selected an option to save some logs to a .evtx file. I get the impression that you meant something different when you asked about a live system?

Also, how would you prefer to receive the encrypted file? Do you have a preferred email or shall I drop it in a temporary location online?

qjerome commented 5 years ago

OK, then you are right. I did not meant this kind of live acquisition. I rather thought about copying the EVTX file straight from the file-system. So, in your scenario the file should be correctly formatted if it is an export from the event viewer. I will dig into this.

codekoala commented 5 years ago

Thank you!

It looks like the error may originate from around here: https://github.com/0xrawsec/golang-evtx/blob/master/evtx/structs.go#L430

It seems to happen when uts.Size is 0. I'm not sure how correct this is in the context of EVTX parsing, but adding a simple conditional around the unmarshaling of uts.String seems to resolve the problem for me:

func (uts *UnicodeTextString) Parse(reader io.ReadSeeker) error {
    err := encoding.Unmarshal(reader, &uts.Size, Endianness)
    if err != nil {
        return err
    }

    if uts.Size > 0 {
        uts.String = make(UTF16String, uts.Size)
        err = encoding.UnmarshaInitSlice(reader, &uts.String, Endianness)
        //log.Debugf("len:%d value:%s", uts.Size, string(uts.String.ToASCII()))
    }
    return err
}
qjerome commented 5 years ago

Yep, that is my exact same bug fix :)