
Goot เป็นกรอบการวิเคราะห์แบบคงที่สำหรับการเดินทาง Goot นั้นง่ายต่อการเรียนรู้ง่ายต่อการใช้งานและขยายได้สูงช่วยให้คุณสามารถพัฒนาการวิเคราะห์ใหม่ ๆ ได้อย่างง่ายดาย
ปัจจุบัน GOOT ให้ส่วนประกอบการวิเคราะห์ที่สำคัญต่อไปนี้ (และการวิเคราะห์เพิ่มเติมกำลังจะมาถึง):
Intall 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 ในไดเรกทอรีเดียวกันซึ่งมีข้อมูลการผ่านการพ่ายแพ้ของฟังก์ชั่นทั้งหมดในโครงการของคุณ
คุณสามารถดูคีย์ fmt.Sprintf ถือวัตถุค่า
{
"fmt.Sprintf" : {
"Recv" : null ,
"Results" : [
[ 0 , 1 ]
],
"Params" : [
[ 0 , 1 ],
[ 1 ]
]
}
}นี่หมายถึงสามสิ่ง
นอกจากนี้คุณจะได้รับ taintgraph.json ในไดเรกทอรีเดียวกัน
คุณสามารถดูไฟล์ JSON มีขอบ taint จากพารามิเตอร์การโทรหนึ่งไปยังพารามิเตอร์การโทรอื่น
{
"(*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
}
} ซึ่งหมายความว่ามีขอบ taint จากตำแหน่ง 0 ของ RunCmd (ในกรณีนี้พารามิเตอร์คือตัวรับสัญญาณ runner.Runner เอง) ไปยังตำแหน่ง 0 ของ StdoutPipe (ในกรณีนี้พารามิเตอร์คือ recevier exec.Cmd iteself ด้วย) ด้วย)
หากต้องการดูขอบ taint ได้ดีขึ้นคุณสามารถโหลดไปยัง 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 )
}
} เมื่อการวิเคราะห์สิ้นสุดลงคุณสามารถค้นหาโหนดและขอบ taint ในฐานข้อมูล Neo4J ของคุณ
ตัวอย่างเช่นเราทำการวิเคราะห์ Taint บน gitlab.com/gitlab-org/[email protected], ซึ่งมีช่องโหว่ RCE CVE-20121-22225
การใช้แบบสอบถามด้านล่างเพื่อค้นหาเส้นทางที่ Taint
MATCH (source:Source),(sink:Sink {name:"os/exec.CommandContext"}),p=(source)-[*7]->(sink) RETURN p
เราสามารถรับกราฟได้เช่นนี้: (โหนดสีแดงคืออ่างล้างจานโหนดสีน้ำตาลเป็นฟังก์ชันภายในและโหนดสีเขียวเป็นแหล่งที่มา)
ซึ่งเผยให้เห็นสองเส้นทางที่น่าเบื่อจากแหล่งที่มาเพื่อจม os/exec.CommandContext เช่นเดียวกับ CVE-20121-22225
หากต้องการใช้ Goot เป็นเฟรมเวิร์กให้สร้างสองโครงสร้างที่ใช้งาน pkg/toolkits/scalar.FlowAnalysis Interface
// 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
// 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 เช่นการไหลและ ssa.Instruction เป็นหน่วยดังนั้นโปรดระวังการยืนยันประเภท