
GOOT هو إطار تحليل ثابت لـ GO. 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 (في هذه الحالة ، المعلمة هي exec.Cmd المتلقي. runner.Runner نفسه) لموضع 0 من StdoutPipe
لعرض حواف 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-2021-22225
باستخدام الاستعلام أدناه للعثور على مسارات taint
MATCH (source:Source),(sink:Sink {name:"os/exec.CommandContext"}),p=(source)-[*7]->(sink) RETURN p
يمكننا الحصول على رسم بياني مثل هذا: (العقد الحمراء عبارة
الذي يكشف عن مسارين taint من المصدر إلى ONS os/exec.CommandContext ، نفس CVE-2011-2225
لاستخدام GOOT كإطار عمل ، قم أولاً بإنشاء اثنين من الهياكل التي تنفذ pkg/toolkits/scalar.FlowAnalysis
// 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 )
} لا تقلق على واجهات برمجة التطبيقات هذه. هناك طريقة سهلة لتنفيذها وهي استخدام تكوين مثل 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 كوحدة ، لذا يرجى توخي الحذر من التأكيد على النوع