.markdown-body pre,.markdown-body pre>code.hljs{color:#333;background:#f8f8f8}.hljs-comment,.hljs-quote{color:#998;font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-subst{color:#333;font-weight:700}.hljs-literal,.hljs-number,.hljs-tag .hljs-attr,.hljs-template-variable,.hljs-variable{color:teal}.hljs-doctag,.hljs-string{color:#d14}.hljs-section,.hljs-selector-id,.hljs-title{color:#900;font-weight:700}.hljs-subst{font-weight:400}.hljs-class .hljs-title,.hljs-type{color:#458;font-weight:700}.hljs-attribute,.hljs-name,.hljs-tag{color:navy;font-weight:400}.hljs-link,.hljs-regexp{color:#009926}.hljs-bullet,.hljs-symbol{color:#990073}.hljs-built_in,.hljs-builtin-name{color:#0086b3}.hljs-meta{color:#999;font-weight:700}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}
目前使用的是iris v1.12.0-alpha2,可以自动解析RequestBody成对象注入到参数中
iris的注入分成两个部分:
- 依赖源列表准备
全局依赖是通过 mvcApp.Register(dependencies ...interface{})
注入的,全局依赖在注册的时候只是保存依赖列表,接收到请求以后才进行注入
注册流程:
- 请求时注入依赖
包括 iris.Context
在内的单个请求范围内的数据,mvcApp.Register()
如果是传入函数的,会在接收请求到请求以后再执行函数进行注入
依赖注入是在接收到请求的时候开始执行的,跟踪依赖注入要从请求处开始看
请求过程
core.router.router.go.Router.buildMainHandlerWithFilters()#router.mainHandler
router.mainHandler = func(w http.ResponseWriter, r *http.Request) {
ctx := cPool.Acquire(w, r)
filterExecuted := false
for _, f := range sortedFilters { // from subdomain, largest path to shortest.
// fmt.Printf("Sorted filter execution: [%s] [%s]\n", f.Subdomain, f.Path)
// 匹配路由
if f.Matcher.Match(ctx) {
// fmt.Printf("Matched [%s] and execute [%d] handlers [%s]\n\n", ctx.Path(), len(f.Handlers), context.HandlersNames(f.Handlers))
filterExecuted = true
// execute the final handlers chain.
ctx.Do(f.Handlers)
break // and break on first found.
}
}
// 没有匹配的路由,进
if !filterExecuted {
// If not at least one match filter found and executed,
// then just run the router.
router.requestHandler.HandleRequest(ctx)
}
// 释放iris上下文
cPool.Release(ctx)
}
路由匹配会调用默认的
router.api_builder.go.defaultPartyMatcher
func defaultPartyMatcher(ctx *context.Context, p Party) bool {
subdomain, path := splitSubdomainAndPath(p.GetRelPath())
// 变量前的路径,eg: /users/{uid} 得到/users
staticPath := staticPath(path)
hosts := subdomain != ""
if p.IsRoot() {
// ALWAYS executed first when registered
// through an `Application.UseRouter` call.
return true
}
if hosts {
// Note(@kataras): do NOT try to implement something like party matcher for each party
// separately. We will introduce a new problem with subdomain inside a subdomain:
// they are not by prefix, so parenting calls will not help
// e.g. admin. and control.admin, control.admin is a sub of the admin.
if !canHandleSubdomain(ctx, subdomain) {
return false
}
}
// this is the longest static path.
return strings.HasPrefix(ctx.Path(), staticPath)
}
这里可以看出,仅匹配路径不匹配方法,方法将在后面对请求进行操作的时候判断
匹配到路由之后,iris上下文开始调用中件间
context.context.go.Context.Do
// Do sets the "handlers" as the chain
// and executes the first handler,
// handlers should not be empty.
//
// It's used by the router, developers may use that
// to replace and execute handlers immediately.
func (ctx *Context) Do(handlers Handlers) {
if len(handlers) == 0 {
return
}
ctx.handlers = handlers
handlers[0](ctx)
}
这个方法比较简单,就是从第一个开始调用中间件,之后就是中间件自行遍历调用
context.context.go.Context.Next
// Next calls the next handler from the handlers chain,
// it should be used inside a middleware.
func (ctx *Context) Next() {
if ctx.IsStopped() {
return
}
nextIndex := ctx.currentHandlerIndex + 1
handlers := ctx.handlers
if n := len(handlers); nextIndex == n {
atomic.StoreUint32(&ctx.proceeded, 1) // last handler but Next is called.
} else if nextIndex < n {
ctx.currentHandlerIndex = nextIndex
handlers[nextIndex](ctx)
}
}
如果有下一个则执行,没有下一步,那活也干完了,不管是全局中间件还是单个请求中间件都是这两个方法的形式在触发链式调用,从单个请求实际上也是以一个handler形式存在于这个链的底部,即为 Router.buildMainHandlerWithFilters.Handlers
请求上下文调用
core.router.router.go.Router.buildMainHandlerWithFilters#f.handlers
f.Handlers = append(f.Handlers, func(ctx *context.Context) {
// 上下文是复用的,数据需要重置
// set the handler index back to 0 so the route's handlers can be executed as expected.
ctx.HandlerIndex(0)
// execute the main request handler, this will fire the found route's handlers
// or if error the error code's associated handler.
router.requestHandler.HandleRequest(ctx)
})
router.requestHandler.HandleRequest便是单个请求的起点,iris在这里判断路由是否完全符合,方法是否正确
core.router.handler.go.routerHandler.HandlerRequest
func (h *routerHandler) HandleRequest(ctx *context.Context) {
method := ctx.Method()
path := ctx.Path()
config := h.config // ctx.Application().GetConfigurationReadOnly()
if !config.GetDisablePathCorrection() {
... 禁用路径校正,重定向等代码省略
}
// 再次匹配路由,此时的匹配会从最近的party开始,并且会对参数进行判断
for i := range h.trees {
t := h.trees[i]
if method != t.method {
continue
}
if h.hosts && !canHandleSubdomain(ctx, t.subdomain) {
continue
}
// 带参数的路径判断,路由树的遍历
n := t.search(path, ctx.Params())
if n != nil {
ctx.SetCurrentRoute(n.Route)
ctx.Do(n.Handlers)
// found
return
}
// not found or method not allowed.
break
}
... 404 或其他重定向的处理
ctx.StatusCode(http.StatusNotFound)
}
单个请求还是要跑自己的中间件,通常jwt、casbin等会在这里调用
单个请求的中间件链第一个跟最后一个比较特殊,第一个略过看最后一个,依赖的注入和请求结果将在这里进行分发
hero.handler.go.makeHandler#Func2
return func(ctx *context.Context) {
inputs := make([]reflect.Value, numIn)
// bindings是在iris.Application初始化的时候就已经准备好了,handler在注册到iris.Application的时候通过getBindingsForFunc初始化了
for _, binding := range bindings {
input, err := binding.Dependency.Handle(ctx, binding.Input)
if err != nil {
if err == ErrSeeOther {
continue
}
c.GetErrorHandler(ctx).HandleError(ctx, err)
// return [13 Sep 2020, commented that in order to be able to
// give end-developer the option not only to handle the error
// but to skip it if necessary, example:
// read form, unknown field, continue without StopWith,
// the binder should bind the method's input argument and continue
// without errors. See `mvc.TestErrorHandlerContinue` test.]
}
// If ~an error status code is set or~ execution has stopped
// from within the dependency (something went wrong while validating the request),
// then stop everything and let handler fire that status code.
if ctx.IsStopped() {
return
}
inputs[binding.Input.Index] = input
}
// 调用controller的业务逻辑
outputs := v.Call(inputs)
// 请求结果分发处理
if err := dispatchFuncResult(ctx, outputs, resultHandler); err != nil {
c.GetErrorHandler(ctx).HandleError(ctx, err)
}
}
篇头说过,注入模块有两部分,一部分是一开始的初始化,一部分是请求处理时的注入,这里的是注入。 Register的东西都被封装成Dependency,而注入是Dependency.Handle的执行,最终的注入有两种: 实例对象和函数注入
通过函数注入
hero.dependency.go.fromDependencyFunc
handler := func(ctx *context.Context, _ *Input) (reflect.Value, error) {
inputs := make([]reflect.Value, numIn)
// 函数入参的处理
for _, binding := range bindings {
// 每个注入里面所需要的参数依然还是注入对象,直到不需要从外面传参数或者是静态注入
input, err := binding.Dependency.Handle(ctx, binding.Input)
if err != nil {
if err == ErrSeeOther {
continue
}
return emptyValue, err
}
inputs[binding.Input.Index] = input
}
// 调用函数
outputs := v.Call(inputs)
if firstOutIsError {
return emptyValue, toError(outputs[0])
} else if secondOutIsError {
return outputs[0], toError(outputs[1])
}
// 从这里可以看出,Register的函数允许两个参数,一个是返回值,一个是error,返回值也就是我们要注入的对象,
return outputs[0], nil
}
这里会递归 Dependency.Handle
以便使每个函数的参数都能得到正确的入参,但这里也可以得到一个结论是 mvcApp.Register(func (val B) A)
mvcApp.Register(func (val A) B)
这是不允许的,但如果真的进行了这样的操作会发生什么事情?第一个注入函数由于B没有在它的注入列表中,也没地方生成,所以它需要从用户的RequestBody中获取,为什么会这样需要去看一下iris初始化handler注入源列表是怎样做的
静态注入的获取比较简单,因为经过了封装了,于是只有一行代码:
hero.dependency.go.fromStructValue
handler := func(*context.Context, *Input) (reflect.Value, error) {
return v, nil
}
RequestBody注入
hero.binding.go.payloadBinding
Handle: func(ctx *context.Context, input *Input) (newValue reflect.Value, err error) {
wasPtr := input.Type.Kind() == reflect.Ptr
if serveDepsV := ctx.Values().Get(context.DependenciesContextKey); serveDepsV != nil {
if serveDeps, ok := serveDepsV.(context.DependenciesMap); ok {
if newValue, ok = serveDeps[typ]; ok {
return
}
}
}
if input.Type.Kind() == reflect.Slice {
newValue = reflect.New(reflect.SliceOf(indirectType(input.Type)))
} else {
newValue = reflect.New(indirectType(input.Type))
}
ptr := newValue.Interface()
err = ctx.ReadBody(ptr)
if !wasPtr {
newValue = newValue.Elem()
}
return
}
经过handler的循环和递归,对函数的注入就完成了。但此时心中有个疑惑是 Controller 的属性又是在什么时候被赋值的?
再次调试发现,注入的列表中会对Controller进行注入,是bindings的一份子(第1个),对它的处理是在struct中
对controller的处理
hero.struct.go.Struct.Acquire
// Acquire returns a struct value based on the request.
// If the dependencies are all static then these are already set-ed at the initialization of this Struct
// and the same struct value instance will be returned, ignoring the Context. Otherwise
// a new struct value with filled fields by its pre-calculated bindings will be returned instead.
func (s *Struct) Acquire(ctx *context.Context) (reflect.Value, error) {
if s.Singleton {
ctx.Values().Set(context.ControllerContextKey, s.ptrValue)
return s.ptrValue, nil
}
ctrl := ctx.Controller()
if ctrl.Kind() == reflect.Invalid ||
ctrl.Type() != s.ptrType /* in case of changing controller in the same request (see RouteOverlap feature) */ {
ctrl = reflect.New(s.elementType)
ctx.Values().Set(context.ControllerContextKey, ctrl)
elem := ctrl.Elem()
for _, b := range s.bindings {
input, err := b.Dependency.Handle(ctx, b.Input)
if err != nil {
if err == ErrSeeOther {
continue
}
s.Container.GetErrorHandler(ctx).HandleError(ctx, err)
if ctx.IsStopped() {
// return emptyValue, err
return ctrl, err
} // #1629
}
// 注入数据到struct
elem.FieldByIndex(b.Input.StructFieldIndex).Set(input)
}
}
return ctrl, nil
}
至此已经完成了注入了,但是对于注入很重要的bindings又是如何初始化的?
依赖源列表准备
mvcApp.Register方法内的的NewDependency
hero.dependency.NewDependency
// NewDependency converts a function or a function which accepts other dependencies or static struct value to a *Dependency.
//
// See `Container.Handler` for more.
func NewDependency(dependency interface{}, funcDependencies ...*Dependency) *Dependency {
if dependency == nil {
panic(fmt.Sprintf("bad value: nil: %T", dependency))
}
if d, ok := dependency.(*Dependency); ok {
// already a *Dependency.
return d
}
v := valueOf(dependency)
if !goodVal(v) {
panic(fmt.Sprintf("bad value: %#+v", dependency))
}
dest := &Dependency{
Source: newSource(v),
OriginalValue: dependency,
}
if !resolveDependency(v, dest, funcDependencies...) {
panic(fmt.Sprintf("bad value: could not resolve a dependency from: %#+v", dependency))
}
return dest
}
func resolveDependency(v reflect.Value, dest *Dependency, funcDependencies ...*Dependency) bool {
return fromDependencyHandler(v, dest) || // 本来就是DependencyHandler的拷贝封装
fromStructValue(v, dest) || // 静态注入
fromFunc(v, dest) || // 函数注入,第一个入参是context,且入参为1或2个
len(funcDependencies) > 0 && fromDependentFunc(v, dest, funcDependencies) // 函数注入
}
binding的获取
不管是func还是struct,除了自身的逻辑,还会调用这个函数来获取到他所需要的bindings
hero.binding.go.getBindingsFor
func getBindingsFor(inputs []reflect.Type, deps []*Dependency, paramsCount int) (bindings []*binding) {
// Path parameter start index is the result of [total path parameters] - [total func path parameters inputs],
// moving from last to first path parameters and first to last (probably) available input args.
//
// That way the above will work as expected:
// 1. mvc.New(app.Party("/path/{firstparam}")).Handle(....Controller.GetBy(secondparam string))
// 2. mvc.New(app.Party("/path/{firstparam}/{secondparam}")).Handle(...Controller.GetBy(firstparam, secondparam string))
// 3. usersRouter := app.Party("/users/{id:uint64}"); usersRouter.ConfigureContainer().Handle(method, "/", handler(id uint64))
// 4. usersRouter.Party("/friends").ConfigureContainer().Handle(method, "/{friendID:uint64}", handler(friendID uint64))
//
// Therefore, count the inputs that can be path parameters first.
shouldBindParams := make(map[int]struct{})
totalParamsExpected := 0
if paramsCount != -1 {
for i, in := range inputs {
if _, canBePathParameter := context.ParamResolvers[in]; !canBePathParameter {
continue
}
shouldBindParams[i] = struct{}{}
totalParamsExpected++
}
}
startParamIndex := paramsCount - totalParamsExpected
if startParamIndex < 0 {
startParamIndex = 0
}
lastParamIndex := startParamIndex
getParamIndex := func() int {
paramIndex := lastParamIndex
lastParamIndex++
return paramIndex
}
bindedInput := make(map[int]struct{})
for i, in := range inputs { //order matters.
_, canBePathParameter := shouldBindParams[i]
prevN := len(bindings) // to check if a new binding is attached; a dependency was matched (see below).
for j := len(deps) - 1; j >= 0; j-- {
d := deps[j]
// Note: we could use the same slice to return.
//
// Add all dynamic dependencies (caller-selecting) and the exact typed dependencies.
//
// A dependency can only be matched to 1 value, and 1 value has a single dependency
// (e.g. to avoid conflicting path parameters of the same type).
if _, alreadyBinded := bindedInput[j]; alreadyBinded {
continue
}
match := matchDependency(d, in)
if !match {
continue
}
if canBePathParameter {
// wrap the existing dependency handler.
paramHandler := paramDependencyHandler(getParamIndex())
prevHandler := d.Handle
d.Handle = func(ctx *context.Context, input *Input) (reflect.Value, error) {
v, err := paramHandler(ctx, input)
if err != nil {
v, err = prevHandler(ctx, input)
}
return v, err
}
d.Static = false
d.OriginalValue = nil
}
bindings = append(bindings, &binding{
Dependency: d,
Input: newInput(in, i, nil),
})
if !d.Explicit { // if explicit then it can be binded to more than one input
bindedInput[j] = struct{}{}
}
break
}
// 遍历了所有的传进来的依赖源都无法找到对应的依赖源,判断为需要解析
if prevN == len(bindings) {
// int string等基础类型可以为path参数,优先进行判断
if canBePathParameter {
// no new dependency added for this input,
// let's check for path parameters.
bindings = append(bindings, paramBinding(i, getParamIndex(), in))
continue
}
// 都不是就从RequestBody获取
// else add builtin bindings that may be registered by user too, but they didn't.
if isPayloadType(in) {
bindings = append(bindings, payloadBinding(i, in))
continue
}
}
}
return
}
Controller中路由的解析
application.Handler -> application.handler -> c := newControllerActivator -> c.activite() -> c.parseMethods(); c.parseHTTPErrorHandler() -> parseMethod -> ControllerActivitor.Handle
mvc.mvc.go.Application.handle
func (app *Application) handle(controller interface{}, options ...Option) *ControllerActivator {
// initialize the controller's activator, nothing too magical so far.
// 这里会保存下controller的一些信息,请求来的时候可以利用这些信息反射生成controller对象
c := newControllerActivator(app, controller)
// check the controller's "BeforeActivation" or/and "AfterActivation" method(s) between the `activate`
// call, which is simply parses the controller's methods, end-dev can register custom controller's methods
// by using the BeforeActivation's (a ControllerActivation) `.Handle` method.
if before, ok := controller.(interface {
BeforeActivation(BeforeActivation)
}); ok {
before.BeforeActivation(c)
}
for _, opt := range options {
if opt != nil {
opt.Apply(c)
}
}
// 解析路由,注册到iris.app中,这时候会生成新的router
c.activate()
if after, okAfter := controller.(interface {
AfterActivation(AfterActivation)
}); okAfter {
after.AfterActivation(c)
}
// 添加到 mvcApplication的Controllers列表
app.Controllers = append(app.Controllers, c)
return c
}
iris初始化和请求:
小结
- iris mvc对
Party
进行封装,往Party
调用Handler()
注册Controller
的时候会被转换APIBuilder
,生成Router列表,每个Router会包含有其路径信息、controller、上级信息、中间件等 - 调用
app.Listen
的时候将iris对APIBuilder
进行处理,router的一些信息会得到补充(如mainHandler
),iris.New()
的时候生成的Router
做为树的顶点,将会被设置成请求到来时的处理服务 - 请求到来的时候,从根Router开始进行匹配找到最能符合路径的Router,Router再进行处理,到业务逻辑前还会再进行一次路径匹配和请求方式匹配来找到最终的业务逻辑处理器
- 依赖注入的依赖源是一个有序列表,后面注册的依赖可以引用之前注册的依赖,但不能引用之后注册的依赖,当引用尚未注册的依赖可能会导致空指针或请求解析异常
- iris最核心的应该是中间件,在iris的请求处理中,都是通过不同的中间件完成,包括依赖注入、参数解析、请求处理等
黑客/网络安全学习路线
对于从来没有接触过黑客/网络安全的同学,目前网络安全、信息安全也是计算机大学生毕业薪资相对较高的学科。
大白也帮大家准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
这也是耗费了大白近四个月的时间,吐血整理,文章非常非常长,觉得有用的话,希望粉丝朋友帮忙点个**「分享」「收藏」「在看」「赞」**
网络安全/渗透测试法律法规必知必会****
今天大白就帮想学黑客/网络安全技术的朋友们入门必须先了解法律法律。
【网络安全零基础入门必知必会】什么是黑客、白客、红客、极客、脚本小子?(02)
【网络安全零基础入门必知必会】网络安全专业术语全面解析(05)
【网络安全入门必知必会】《中华人民共和国网络安全法》(06)
【网络安全零基础入门必知必会】《计算机信息系统安全保护条例》(07)
【网络安全零基础入门必知必会】《中国计算机信息网络国际联网管理暂行规定》(08)
【网络安全零基础入门必知必会】《计算机信息网络国际互联网安全保护管理办法》(09)
【网络安全零基础入门必知必会】《互联网信息服务管理办法》(10)
【网络安全零基础入门必知必会】《计算机信息系统安全专用产品检测和销售许可证管理办法》(11)
【网络安全零基础入门必知必会】《通信网络安全防护管理办法》(12)
【网络安全零基础入门必知必会】《中华人民共和国国家安全法》(13)
【网络安全零基础入门必知必会】《中华人民共和国数据安全法》(14)
【网络安全零基础入门必知必会】《中华人民共和国个人信息保护法》(15)
【网络安全零基础入门必知必会】《网络产品安全漏洞管理规定》(16)
网络安全/渗透测试linux入门必知必会
【网络安全零基础入门必知必会】什么是Linux?Linux系统的组成与版本?什么是命令(01)
【网络安全零基础入门必知必会】VMware下载安装,使用VMware新建虚拟机,远程管理工具(02)
【网络安全零基础入门必知必会】VMware常用操作指南(非常详细)零基础入门到精通,收藏这一篇就够了(03)
【网络安全零基础入门必知必会】CentOS7安装流程步骤教程(非常详细)零基入门到精通,收藏这一篇就够了(04)
【网络安全零基础入门必知必会】Linux系统目录结构详细介绍(05)
【网络安全零基础入门必知必会】Linux 命令大全(非常详细)零基础入门到精通,收藏这一篇就够了(06)
【网络安全零基础入门必知必会】linux安全加固(非常详细)零基础入门到精通,收藏这一篇就够了(07)
网络安全/渗透测试****计算机网络入门必知必会****
【网络安全零基础入门必知必会】TCP/IP协议深入解析(非常详细)零基础入门到精通,收藏这一篇就够了(01)
【网络安全零基础入门必知必会】什么是HTTP数据包&Http数据包分析(非常详细)零基础入门到精通,收藏这一篇就够了(02)
【网络安全零基础入门必知必会】计算机网络—子网划分、子网掩码和网关(非常详细)零基础入门到精通,收藏这一篇就够了(03)
网络安全/渗透测试入门之HTML入门必知必会
【网络安全零基础入门必知必会】什么是HTML&HTML基本结构&HTML基本使用(非常详细)零基础入门到精通,收藏这一篇就够了1
【网络安全零基础入门必知必会】VScode、PhpStorm的安装使用、Php的环境配置,零基础入门到精通,收藏这一篇就够了2
【网络安全零基础入门必知必会】HTML之编写登录和文件上传(非常详细)零基础入门到精通,收藏这一篇就够了3
网络安全/渗透测试入门之Javascript入门必知必会
【网络安全零基础入门必知必会】Javascript语法基础(非常详细)零基础入门到精通,收藏这一篇就够了(01)
【网络安全零基础入门必知必会】Javascript实现Post请求、Ajax请求、输出数据到页面、实现前进后退、文件上传(02)
网络安全/渗透测试入门之Shell入门必知必会
【网络安全零基础入门必知必会】Shell编程基础入门(非常详细)零基础入门到精通,收藏这一篇就够了(第七章)
网络安全/渗透测试入门之PHP入门必知必会
【网络安全零基础入门】PHP环境搭建、安装Apache、安装与配置MySQL(非常详细)零基础入门到精通,收藏这一篇就够(01)
【网络安全零基础入门】PHP基础语法(非常详细)零基础入门到精通,收藏这一篇就够了(02)
【网络安全零基础入门必知必会】PHP+Bootstrap实现表单校验功能、PHP+MYSQL实现简单的用户注册登录功能(03)
网络安全/渗透测试入门之MySQL入门必知必会
【网络安全零基础入门必知必会】MySQL数据库基础知识/安装(非常详细)零基础入门到精通,收藏这一篇就够了(01)
【网络安全零基础入门必知必会】SQL语言入门(非常详细)零基础入门到精通,收藏这一篇就够了(02)
【网络安全零基础入门必知必会】MySQL函数使用大全(非常详细)零基础入门到精通,收藏这一篇就够了(03)
【网络安全零基础入门必知必会】MySQL多表查询语法(非常详细)零基础入门到精通,收藏这一篇就够了(04)
****网络安全/渗透测试入门之Python入门必知必会
【网络安全零基础入门必知必会】之Python+Pycharm安装保姆级教程,Python环境配置使用指南,收藏这一篇就够了【1】
【网络安全零基础入门必知必会】之Python编程入门教程(非常详细)零基础入门到精通,收藏这一篇就够了(2)
python入门教程python开发基本流程控制if … else
python入门教程之python开发可变和不可变数据类型和hash
【网络安全零基础入门必知必会】之10个python爬虫入门实例(非常详细)零基础入门到精通,收藏这一篇就够了(3)
****网络安全/渗透测试入门之SQL注入入门必知必会
【网络安全渗透测试零基础入门必知必会】之初识SQL注入(非常详细)零基础入门到精通,收藏这一篇就够了(1)
【网络安全渗透测试零基础入门必知必会】之SQL手工注入基础语法&工具介绍(2)
【网络安全渗透测试零基础入门必知必会】之SQL注入实战(非常详细)零基础入门到精通,收藏这一篇就够了(3)
【网络安全渗透测试零基础入门必知必会】之SQLmap安装&实战(非常详细)零基础入门到精通,收藏这一篇就够了(4)
【网络安全渗透测试零基础入门必知必会】之SQL防御(非常详细)零基础入门到精通,收藏这一篇就够了(4)
****网络安全/渗透测试入门之XSS攻击入门必知必会
【网络安全渗透测试零基础入门必知必会】之XSS攻击基本概念和原理介绍(非常详细)零基础入门到精通,收藏这一篇就够了(1)
网络安全渗透测试零基础入门必知必会】之XSS攻击获取用户cookie和用户密码(实战演示)零基础入门到精通收藏这一篇就够了(2)
【网络安全渗透测试零基础入门必知必会】之XSS攻击获取键盘记录(实战演示)零基础入门到精通收藏这一篇就够了(3)
【网络安全渗透测试零基础入门必知必会】之xss-platform平台的入门搭建(非常详细)零基础入门到精通,收藏这一篇就够了4
【网络安全渗透测试入门】之XSS漏洞检测、利用和防御机制XSS游戏(非常详细)零基础入门到精通,收藏这一篇就够了5
****网络安全/渗透测试入门文件上传攻击与防御入门必知必会
【网络安全渗透测试零基础入门必知必会】之什么是文件包含漏洞&分类(非常详细)零基础入门到精通,收藏这一篇就够了1
【网络安全渗透测试零基础入门必知必会】之cve实际漏洞案例解析(非常详细)零基础入门到精通, 收藏这一篇就够了2
【网络安全渗透测试零基础入门必知必会】之PHP伪协议精讲(文件包含漏洞)零基础入门到精通,收藏这一篇就够了3
【网络安全渗透测试零基础入门必知必会】之如何搭建 DVWA 靶场保姆级教程(非常详细)零基础入门到精通,收藏这一篇就够了4
【网络安全渗透测试零基础入门必知必会】之Web漏洞-文件包含漏洞超详细全解(附实例)5
【网络安全渗透测试零基础入门必知必会】之文件上传漏洞修复方案6
****网络安全/渗透测试入门CSRF渗透与防御必知必会
【网络安全渗透测试零基础入门必知必会】之CSRF漏洞概述和原理(非常详细)零基础入门到精通, 收藏这一篇就够了1
【网络安全渗透测试零基础入门必知必会】之CSRF攻击的危害&分类(非常详细)零基础入门到精通, 收藏这一篇就够了2
【网络安全渗透测试零基础入门必知必会】之XSS与CSRF的区别(非常详细)零基础入门到精通, 收藏这一篇就够了3
【网络安全渗透测试零基础入门必知必会】之CSRF漏洞挖掘与自动化工具(非常详细)零基础入门到精通,收藏这一篇就够了4
【网络安全渗透测试零基础入门必知必会】之CSRF请求伪造&Referer同源&置空&配合XSS&Token值校验&复用删除5
****网络安全/渗透测试入门SSRF渗透与防御必知必会
【网络安全渗透测试零基础入门必知必会】之SSRF漏洞概述及原理(非常详细)零基础入门到精通,收藏这一篇就够了 1
【网络安全渗透测试零基础入门必知必会】之SSRF相关函数和协议(非常详细)零基础入门到精通,收藏这一篇就够了2
【网络安全渗透测试零基础入门必知必会】之SSRF漏洞原理攻击与防御(非常详细)零基础入门到精通,收藏这一篇就够了3**
**
****网络安全/渗透测试入门XXE渗透与防御必知必会
【网络安全渗透测试零基础入门必知必会】之XML外部实体注入(非常详细)零基础入门到精通,收藏这一篇就够了1
网络安全渗透测试零基础入门必知必会】之XXE的攻击与危害(非常详细)零基础入门到精通,收藏这一篇就够了2
【网络安全渗透测试零基础入门必知必会】之XXE漏洞漏洞及利用方法解析(非常详细)零基础入门到精通,收藏这一篇就够了3
【网络安全渗透测试零基础入门必知必会】之微信XXE安全漏洞处理(非常详细)零基础入门到精通,收藏这一篇就够了4
****网络安全/渗透测试入门远程代码执行渗透与防御必知必会
【网络安全渗透测试零基础入门必知必会】之远程代码执行原理介绍(非常详细)零基础入门到精通,收藏这一篇就够了1
【网络安全零基础入门必知必会】之CVE-2021-4034漏洞原理解析(非常详细)零基础入门到精通,收藏这一篇就够了2
【网络安全零基础入门必知必会】之PHP远程命令执行与代码执行原理利用与常见绕过总结3
【网络安全零基础入门必知必会】之WEB安全渗透测试-pikachu&DVWA靶场搭建教程,零基础入门到精通,收藏这一篇就够了4
****网络安全/渗透测试入门反序列化渗透与防御必知必会
【网络安全零基础入门必知必会】之什么是PHP对象反序列化操作(非常详细)零基础入门到精通,收藏这一篇就够了1
【网络安全零基础渗透测试入门必知必会】之php反序列化漏洞原理解析、如何防御此漏洞?如何利用此漏洞?2
【网络安全渗透测试零基础入门必知必会】之Java 反序列化漏洞(非常详细)零基础入门到精通,收藏这一篇就够了3
【网络安全渗透测试零基础入门必知必会】之Java反序列化漏洞及实例解析(非常详细)零基础入门到精通,收藏这一篇就够了4
【网络安全渗透测试零基础入门必知必会】之CTF题目解析Java代码审计中的反序列化漏洞,以及其他漏洞的组合利用5
网络安全/渗透测试**入门逻辑漏洞必知必会**
【网络安全渗透测试零基础入门必知必会】之一文带你0基础挖到逻辑漏洞(非常详细)零基础入门到精通,收藏这一篇就够了
网络安全/渗透测试入门暴力猜解与防御必知必会
【网络安全渗透测试零基础入门必知必会】之密码安全概述(非常详细)零基础入门到精通,收藏这一篇就够了1
【网络安全渗透测试零基础入门必知必会】之什么样的密码是不安全的?(非常详细)零基础入门到精通,收藏这一篇就够了2
【网络安全渗透测试零基础入门必知必会】之密码猜解思路(非常详细)零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之利用Python暴力破解邻居家WiFi密码、压缩包密码,收藏这一篇就够了4
【网络安全渗透测试零基础入门必知必会】之BurpSuite密码爆破实例演示,零基础入门到精通,收藏这一篇就够了5
【网络安全渗透测试零基础入门必知必会】之Hydra密码爆破工具使用教程图文教程,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之暴力破解medusa,零基础入门到精通,收藏这一篇就够了7
【网络安全渗透测试零基础入门必知必会】之Metasploit抓取密码,零基础入门到精通,收藏这一篇就够了8
****网络安全/渗透测试入门掌握Redis未授权访问漏洞必知必会
【网络安全渗透测试零基础入门必知必会】之Redis未授权访问漏洞,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之Redis服务器被攻击后该如何安全加固,零基础入门到精通,收藏这一篇就够了**
**
网络安全/渗透测试入门掌握**ARP渗透与防御关必知必会**
【网络安全渗透测试零基础入门必知必会】之ARP攻击原理解析,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之ARP流量分析,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之ARP防御策略与实践指南,零基础入门到精通,收藏这一篇就够了
网络安全/渗透测试入门掌握系统权限提升渗透与防御关****必知必会
【网络安全渗透测试零基础入门必知必会】之Windows提权常用命令,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之Windows权限提升实战,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之linux 提权(非常详细)零基础入门到精通,收藏这一篇就够了
网络安全/渗透测试入门掌握Dos与DDos渗透与防御相关****必知必会
【网络安全渗透测试零基础入门必知必会】之DoS与DDoS攻击原理(非常详细)零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之Syn-Flood攻击原理解析(非常详细)零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之IP源地址欺骗与dos攻击,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之SNMP放大攻击原理及实战演示,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之NTP放大攻击原理,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之什么是CC攻击?CC攻击怎么防御?,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之如何防御DDOS的攻击?零基础入门到精通,收藏这一篇就够了
网络安全/渗透测试入门掌握无线网络安全渗透与防御相关****必知必会
【网络安全渗透测试零基础入门必知必会】之Aircrack-ng详细使用安装教程,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之aircrack-ng破解wifi密码(非常详细)零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之WEB渗透近源攻击,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之无线渗透|Wi-Fi渗透思路,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之渗透WEP新思路Hirte原理解析,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之WPS的漏洞原理解析,零基础入门到精通,收藏这一篇就够了
网络安全/渗透测试入门掌握木马免杀问题与防御********必知必会
【网络安全渗透测试零基础入门必知必会】之Metasploit – 木马生成原理和方法,零基础入门到精通,收藏这篇就够了
【网络安全渗透测试零基础入门必知必会】之MSF使用教程永恒之蓝漏洞扫描与利用,收藏这一篇就够了
网络安全/渗透测试入门掌握Vulnhub靶场实战********必知必会
【网络安全渗透测试零基础入门必知必会】之Vulnhub靶机Prime使用指南,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之Vulnhub靶场Breach1.0解析,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之vulnhub靶场之DC-9,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之Vulnhub靶机Kioptrix level-4 多种姿势渗透详解,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之Vulnhub靶场PWNOS: 2.0 多种渗透方法,收藏这一篇就够了
网络安全/渗透测试入门掌握社会工程学必知必会
【网络安全渗透测试零基础入门必知必会】之什么是社会工程学?定义、类型、攻击技术,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之社会工程学之香农-韦弗模式,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之社工学smcr通信模型,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之社会工程学之社工步骤整理(附相应工具下载)收藏这一篇就够了
网络安全/渗透测试入门掌握********渗透测试工具使用******必知必会**
2024版最新Kali Linux操作系统安装使用教程(非常详细)零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之渗透测试工具大全之Nmap安装使用命令指南,零基础入门到精通,收藏这一篇就够了
2024版最新AWVS安装使用教程(非常详细)零基础入门到精通,收藏这一篇就够了
2024版最新burpsuite安装使用教程(非常详细)零基础入门到精通,收藏这一篇就够了
2024版最新owasp_zap安装使用教程(非常详细)零基础入门到精通,收藏这一篇就够了
2024版最新Sqlmap安装使用教程(非常详细)零基础入门到精通,收藏这一篇就够了
2024版最新Metasploit安装使用教程(非常详细)零基础入门到精通,收藏这一篇就够了
2024版最新Nessus下载安装激活使用教程(非常详细)零基础入门到精通,收藏这一篇就够了
2024版最新Wireshark安装使用教程(非常详细)零基础入门到精通,收藏这一篇就够了
觉得有用的话,希望粉丝朋友帮大白点个**「分享」「收藏」「在看」「赞」**
黑客/网络安全学习包
资料目录
-
成长路线图&学习规划
-
配套视频教程
-
SRC&黑客文籍
-
护网行动资料
-
黑客必读书单
-
面试题合集
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享
1.成长路线图&学习规划
要学习一门新的技术,作为新手一定要先学习成长路线图,方向不对,努力白费。
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图&学习规划。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享
2.视频教程
很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,其中一共有21个章节,每个章节都是当前板块的精华浓缩。
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享
3.SRC&黑客文籍
大家最喜欢也是最关心的SRC技术文籍&黑客技术也有收录
SRC技术文籍:
黑客资料由于是敏感资源,这里不能直接展示哦!
4.护网行动资料
其中关于HW护网行动,也准备了对应的资料,这些内容可相当于比赛的金手指!
5.黑客必读书单
**
**
6.面试题合集
当你自学到这里,你就要开始思考找工作的事情了,而工作绕不开的就是真题和面试题。
更多内容为防止和谐,可以扫描获取~
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
****************************CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享