
Goot는 GO를위한 정적 분석 프레임 워크입니다. Goot는 학습하기 쉽고 사용하기 쉬우 며 확장하기 쉽기 때문에 새로운 분석을 쉽게 개발할 수 있습니다.
현재 Goot은 다음 주요 분석 구성 요소를 제공합니다 (및 더 많은 분석이 진행 중).
goot에 의해
go get -u github.com/cokeBeer/goot
분석 할 프로젝트에 아래 코드를 작성하십시오 (예 : cmd/taint/main.go
package main
import "github.com/cokeBeer/goot/pkg/example/dataflow/taint"
func main () {
// if this file is cmd/taint/main.go
// and you want to analyse package pkg
// the path should be "../../pkg"
// or "../../pkg..." for all packages under pkg
runner := taint . NewRunner ( "relative/path/to/package" )
// for this project, is "github.com/cokeBeer/goot"
runner . ModuleName = "module-name"
runner . PassThroughDstPath = "passthrough.json"
runner . TaintGraphDstPath = "taintgraph.json"
runner . Run ()
} 코드를 실행하면 프로젝트의 모든 기능에 대한 오염 된 통과 정보가 포함 된 동일한 디렉토리에 passthrough.json 을 얻게됩니다.
Key fmt.Sprintf 가 값 객체를 보유하는 것을 볼 수 있습니다
{
"fmt.Sprintf" : {
"Recv" : null ,
"Results" : [
[ 0 , 1 ]
],
"Params" : [
[ 0 , 1 ],
[ 1 ]
]
}
}이것은 세 가지를 의미합니다
또한 동일한 디렉토리에서 taintgraph.json 을 얻을 수 있습니다.
JSON 파일에 한 통화 매개 변수에서 다른 통화 매개 변수로 오염 된 가장자리가 포함되어 있습니다.
{
"(*github.com/example/runnner.Runner).RunCmd#0#(*os/exec.Cmd).StdoutPipe#0" : {
"From" : " (*github.com/example/runnner.Runner).RunCmd " ,
"FromIndex" : 0 ,
"To" : " (*os/exec.Cmd).StdoutPipe " ,
"ToIndex" : 0 ,
"ToIsMethod" : false ,
"ToIsSink" : true ,
"ToIsSignature" : false ,
"ToIsStatic" : true
}
} 즉, RunCmd 의 위치 0 에서 오염 된 에지 (이 경우 매개 변수는 수신자 runner.Runner 입니다. unner 자체)가 StdoutPipe 의 위치 0 (이 경우 매개 변수는 recevier exec.Cmd iteself)입니다.
오염 된 가장자리를 더 잘 보려면 이러한 매개 변수를 설정하여 NEO4J에로드 할 수 있습니다 (자세한 옵션은 러너 옵션 참조).
func main () {
runner := taint . NewRunner ( "../../internal..." )
runner . ModuleName = "gitlab.com/gitlab-org/gitlab-workhorse"
// parameters about neo4j
runner . PersistToNeo4j = true
runner . Neo4jURI = "bolt://localhost:7687"
runner . Neo4jUsername = "neo4j"
runner . Neo4jPassword = "password"
err := runner . Run ()
if err != nil {
log . Fatal ( err )
}
} 분석이 끝나면 NEO4J 데이터베이스에서 노드와 오염 모서리를 찾을 수 있습니다.
예를 들어, 우리는 gitlab.com/gitlab-org/[email protected]에서 Taint Analysis를 실행하며 RCE 취약성 CVE-2021-22225가 있습니다.
아래 쿼리를 사용하여 오염 경로를 찾습니다
MATCH (source:Source),(sink:Sink {name:"os/exec.CommandContext"}),p=(source)-[*7]->(sink) RETURN p
우리는 다음과 같은 그래프를 얻을 수 있습니다.
CVE-2021-22225와 같은 소스에서 싱크 os/exec.CommandContext 까지 두 개의 오염 경로가 나타납니다.
goot를 프레임 워크로 사용하려면 먼저 pkg/toolkits/scalar.FlowAnalysis Interface를 구현하는 두 개의 struct를 만듭니다.
// FlowAnalysis represents a flow analysis
type FlowAnalysis interface {
GetGraph () * graph. UnitGraph
IsForward () bool
Computations () int
FlowThrougth ( inMap * map [ any ] any , unit ssa. Instruction , outMap * map [ any ] any )
NewInitalFlow () * map [ any ] any
EntryInitalFlow () * map [ any ] any
Copy ( srcMap * map [ any ] any , dstMap * map [ any ] any )
MergeInto ( Unit ssa. Instruction , inout * map [ any ] any , in * map [ any ] any )
End ( universe [] * entry. Entry )
} 및 pkg/golang/switcher.Switcher 인터페이스별로
// Switcher represents a ssa instruction switcher
type Switcher interface {
CaseAlloc ( inst * ssa. Alloc )
CasePhi ( inst * ssa. Phi )
CaseCall ( inst * ssa. Call )
CaseBinOp ( inst * ssa. BinOp )
CaseUnOp ( inst * ssa. UnOp )
...
CaseGo ( inst * ssa. Go )
CaseDefer ( inst * ssa. Defer )
CaseSend ( inst * ssa. Send )
CaseStore ( inst * ssa. Store )
CaseMapUpdate ( inst * ssa. MapUpdate )
CaseDebugRef ( inst * ssa. DebugRef )
} 이 API에 대해 걱정하지 마십시오. 이를 구현하는 쉬운 방법은 pkg/toolkits/scalar.BaseFlowAnalysis 와 같은 Compose를 사용하는 것입니다.
// ConstantPropagationAnalysis represents a constant propagtion analysis
type ConstantPropagationAnalysis struct {
scalar. BaseFlowAnalysis
constantPropagationSwitcher * ConstantPropagationSwitcher
} 및 pkg/golang/switcher.BaseSwitcher
// ConstantPropagationSwitcher represents a constant propagtion switcher
type ConstantPropagationSwitcher struct {
switcher. BaseSwitcher
constanctPropagationAnalysis * ConstantPropagationAnalysis
inMap * map [ any ] any
outMap * map [ any ] any
} 이들은 특정 분석에서 신중하게 설계하는 데 필요한 핵심 방법에 집중할 수 있습니다.
프레임 워크로 goot를 사용하는 방법 과 사용 방법과 실행 방법에 대해 준비한 작은 예에서 분석을 실행하는 방법에 대한 자세한 내용을 배울 수 있습니다 constant propagation analysis
*map[any]any as flow and ssa.Instruction 을 단위로 사용하므로 유형 어설 션을 조심하십시오.