Skip to content

Commit

Permalink
add kolide_jwt parsing table (#1440)
Browse files Browse the repository at this point in the history
  • Loading branch information
zackattack01 authored Nov 7, 2023
1 parent f8222fa commit 837a7c8
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
55 changes: 55 additions & 0 deletions pkg/dataflatten/jwt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package dataflatten

import (
"fmt"
"io"
"os"

"github.com/golang-jwt/jwt/v5"
)

// JWTFile adds support for the kolide_jwt table, which allows parsing
// a file containing a JWT. Note that the kolide_jwt table does not handle
// verification - this is a utility table for convenience.
func JWTFile(file string, opts ...FlattenOpts) ([]Row, error) {
return flattenJWT(file, opts...)
}

func flattenJWT(path string, opts ...FlattenOpts) ([]Row, error) {
// for now, make it clear that any data we parse is unverified
results := map[string]interface{}{"verified": false}

jwtFH, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("unable to access file: %w", err)
}

defer jwtFH.Close()

tokenRaw, err := io.ReadAll(jwtFH)
if err != nil {
return nil, fmt.Errorf("unable to read JWT: %w", err)
}

// attempt decode into the generic (default) MapClaims struct to ensure we capture
// any claims data that might be useful
token, _, err := new(jwt.Parser).ParseUnverified(string(tokenRaw), jwt.MapClaims{})
if err != nil {
return nil, fmt.Errorf("unable to parse JWT: %w", err)
}

claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
return nil, fmt.Errorf("JWT has no parseable claims")
}

parsedClaims := map[string]interface{}{}
for k, v := range claims {
parsedClaims[k] = v
}

results["claims"] = parsedClaims
results["header"] = token.Header

return Flatten(results, opts...)
}
5 changes: 5 additions & 0 deletions pkg/osquery/tables/dataflattentable/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const (
PlistType DataSourceType = iota + 1
JsonType
JsonlType
JWTType
ExecType
XmlType
IniType
Expand Down Expand Up @@ -47,6 +48,7 @@ func AllTablePlugins(logger log.Logger) []osquery.OsqueryPlugin {
TablePlugin(logger, IniType),
TablePlugin(logger, PlistType),
TablePlugin(logger, JsonlType),
TablePlugin(logger, JWTType),
}
}

Expand All @@ -73,6 +75,9 @@ func TablePlugin(logger log.Logger, dataSourceType DataSourceType) osquery.Osque
case IniType:
t.flattenFileFunc = dataflatten.IniFile
t.tableName = "kolide_ini"
case JWTType:
t.flattenFileFunc = dataflatten.JWTFile
t.tableName = "kolide_jwt"
default:
panic("Unknown data source type")
}
Expand Down

0 comments on commit 837a7c8

Please sign in to comment.