1.05x.从渗透靶场开始
2.从源码层面带你实现一个自动注入注解
3.Kali Linux下Dirb工具web网站目录爆破指南
05x.从渗透靶场开始
在渗透测试领域中,白帽黑客和黑帽黑客的行为截然不同。白帽黑客的首要任务是识别并修复系统中的安全漏洞,而不是为了入侵和破坏。他们需要遵循一套严格的原则,确保所有渗透行为在合法的源码之门范围内进行。为了方便学习和实践,白帽黑客通常会搭建自己的靶场环境,在此环境中,他们可以安全地测试和验证各种渗透方法。
靶场环境的搭建通常包含以下步骤。首先,安装一套包含PHP、MySQL等组件的服务器环境,如phpstudy。接着,配置数据库管理工具,dpmc 源码可以使用phpstudy自带的phpMyAdmin或选择安装Navicat。之后,下载并解压一个漏洞测试项目,如著名的“Damn Vulnerable Web Application”(简称DVWA)。配置dvwa的配置文件以指定数据库信息和密钥,完成数据库的初始化,并登录靶场以开始测试。
DVWA是一个包含了OWASP Top所有攻击漏洞的测试平台,提供了从暴力破解到跨站脚本等多种测试场景。搭建过程简单明了,通过安装、配置和启动DVWA项目,即可在安全的环境下对各种漏洞进行测试和学习。
除了DVWA,还有其他类似的靶场平台,如“bwapp”和“sql-labs”。rmdown源码这些平台提供了更多样化的漏洞类型和测试场景,帮助渗透测试者全面提高技能。其中,“bwapp”提供了超过个漏洞供测试,而“sql-labs”专注于SQL注入测试,涵盖了多种注入方式,如报错注入、盲注等。
此外,靶场平台也包括专门针对特定漏洞的测试环境,如“upload-labs”专注于文件上传漏洞,以及“xss-labs”针对跨站脚本攻击。这些平台不仅提供了实战练习的机会,还允许用户直接查看源代码和测试结果,从而更好地理解漏洞和修复方法。
对于在线靶场,传经源码虽然它们通常需要注册和付费,但为学习者提供了额外的资源和实践机会。注册后,学习者可以获得墨币等虚拟货币,用于访问这些在线平台上的各种靶场和测试环境,进一步扩展自己的技能。
综上所述,搭建和使用靶场环境是渗透测试学习过程中的重要环节。通过实践和探索不同的靶场平台,学习者能够系统地掌握渗透测试的技能和策略,为未来的职业发展打下坚实的基础。
从源码层面带你实现一个自动注入注解
首先,需要了解到的是。SpringBean的生命周期在生命周期中。注入bean属性的位置是在以下代码:populateBean位置中
那么我们在项目中使用注解产生一个bean的时候必定会经过以下代码进行一个bean的创建流程
/**省略代码**///开始初始化bean实例对象ObjectexposedObject=bean;try{ //<5>对bean进行填充,将各个属性值注入,sqliteman源码其中,可能存在依赖于其他bean的属性populateBean(beanName,mbd,instanceWrapper);//<6>调用初始化方法exposedObject=initializeBean(beanName,exposedObject,mbd);}catch(Throwableex){ if(exinstanceofBeanCreationException&&beanName.equals(((BeanCreationException)ex).getBeanName())){ throw(BeanCreationException)ex;}else{ thrownewBeanCreationException(mbd.getResourceDescription(),beanName,"Initializationofbeanfailed",ex);}}/**省略代码**/在生命周期中populateBean进行填充bean数据。把其他依赖引入进来
BeanPostProcessor是一个bean创建时候的一个钩子。
以下代码是循环调用实现了BeanPostProcessor子类InstantiationAwareBeanPostProcessor#postProcessProperties方法
Spring在以下代码中有自动注入的拓展点。关键就是实现InstantiationAwareBeanPostProcessor#postProcessProperties
/**省略代码**/for(BeanPostProcessorbp:getBeanPostProcessors()){ if(bpinstanceofInstantiationAwareBeanPostProcessor){ InstantiationAwareBeanPostProcessoribp=(InstantiationAwareBeanPostProcessor)bp;//对所有需要依赖检查的属性进行后处理PropertyValuespvsToUse=ibp.postProcessProperties(pvs,bw.getWrappedInstance(),beanName);if(pvsToUse==null){ //从bw对象中提取PropertyDescriptor结果集//PropertyDescriptor:可以通过一对存取方法提取一个属性if(filteredPds==null){ filteredPds=filterPropertyDescriptorsForDependencyCheck(bw,mbd.allowCaching);}pvsToUse=ibp.postProcessPropertyValues(pvs,filteredPds,bw.getWrappedInstance(),beanName);if(pvsToUse==null){ return;}}pvs=pvsToUse;}}/**省略代码**/我们展开来讲一下@Autowired的实现是怎么样的吧:
实现类为AutowiredAnnotationBeanPostProcessor.java
从上面可以得知,填充bean的时候。时调用了方法ibp.postProcessPropertyValues()
那么AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues()则会被调用
调用findAutowiringMetadata获取class以及父类带有@Autowired或者@Value的属性或者方法:
/**省略代码**/publicPropertyValuespostProcessProperties(PropertyValuespvs,Objectbean,StringbeanName){ //获取所有可以注入的元数据InjectionMetadatametadata=findAutowiringMetadata(beanName,bean.getClass(),pvs);try{ //注入数据metadata.inject(bean,beanName,pvs);}catch(BeanCreationExceptionex){ throwex;}catch(Throwableex){ thrownewBeanCreationException(beanName,"Injectionofautowireddependenciesfailed",ex);}returnpvs;}privateInjectionMetadatafindAutowiringMetadata(StringbeanName,Class<?>clazz,@NullablePropertyValuespvs){ //缓存名字获取StringcacheKey=(StringUtils.hasLength(beanName)?beanName:clazz.getName());InjectionMetadatametadata=this.injectionMetadataCache.get(cacheKey);//获取是否已经读取过这个class类的InjectionMetadata有的话直接从缓存中获取出去if(InjectionMetadata.needsRefresh(metadata,clazz)){ synchronized(this.injectionMetadataCache){ //双重检查metadata=this.injectionMetadataCache.get(cacheKey);if(InjectionMetadata.needsRefresh(metadata,clazz)){ if(metadata!=null){ metadata.clear(pvs);}//构建自动注入的元数据metadata=buildAutowiringMetadata(clazz);this.injectionMetadataCache.put(cacheKey,metadata);}}}returnmetadata;}privateInjectionMetadatabuildAutowiringMetadata(finalClass<?>clazz){ if(!AnnotationUtils.isCandidateClass(clazz,this.autowiredAnnotationTypes)){ returnInjectionMetadata.EMPTY;}List<InjectionMetadata.InjectedElement>elements=newArrayList<>();Class<?>targetClass=clazz;do{ finalList<InjectionMetadata.InjectedElement>currElements=newArrayList<>();//循环targetClass的所有field并执FieldCallback逻辑(函数式编程接口,传入的是一个执行函数)ReflectionUtils.doWithLocalFields(targetClass,field->{ //获得字段上面的Annotation注解MergedAnnotation<?>ann=findAutowiredAnnotation(field);if(ann!=null){ //判断是否为静态属性如果是,则不进行注入if(Modifier.isStatic(field.getModifiers())){ if(logger.isInfoEnabled()){ logger.info("Autowiredannotationisnotsupportedonstaticfields:"+field);}return;}//注解是否为必须依赖项booleanrequired=determineRequiredStatus(ann);currElements.add(newAutowiredFieldElement(field,required));}});//循环targetClass的所有Method并执MethodCallback逻辑(函数式编程接口,传入的是一个执行函数)ReflectionUtils.doWithLocalMethods(targetClass,method->{ MethodbridgedMethod=BridgeMethodResolver.findBridgedMethod(method);if(!BridgeMethodResolver.isVisibilityBridgeMethodPair(method,bridgedMethod)){ return;}MergedAnnotation<?>ann=findAutowiredAnnotation(bridgedMethod);if(ann!=null&&method.equals(ClassUtils.getMostSpecificMethod(method,clazz))){ //判断是否为静态方法如果是,则不进行注入if(Modifier.isStatic(method.getModifiers())){ if(logger.isInfoEnabled()){ logger.info("Autowiredannotationisnotsupportedonstaticmethods:"+method);}return;}//判断静态方法参数是否为0if(method.getParameterCount()==0){ if(logger.isInfoEnabled()){ logger.info("Autowiredannotationshouldonlybeusedonmethodswithparameters:"+method);}}booleanrequired=determineRequiredStatus(ann);PropertyDescriptorpd=BeanUtils.findPropertyForMethod(bridgedMethod,clazz);currElements.add(newAutowiredMethodElement(method,required,pd));}});//数据加到数组最前方父类的的注解都放在靠前的位置elements.addAll(0,currElements);//如果有父类则设置targetClass为父类。如此循环targetClass=targetClass.getSuperclass();}while(targetClass!=null&&targetClass!=Object.class);returnInjectionMetadata.forElements(elements,clazz);}/**省略代码**/真正注入数据的是metadata.inject(bean,beanName,pvs);
调用的是InjectionMetadata#inject方法
publicvoidinject(Objecttarget,@NullableStringbeanName,@NullablePropertyValuespvs)throwsThrowable{ Collection<InjectedElement>checkedElements=this.checkedElements;//带有注解的方法或者属性列表Collection<InjectedElement>elementsToIterate=(checkedElements!=null?checkedElements:this.injectedElements);if(!elementsToIterate.isEmpty()){ for(InjectedElementelement:elementsToIterate){ element.inject(target,beanName,pvs);}}}循环调用之前加入的带有注解的方法或者属性构建的对象AutowiredFieldElement#inject,AutowiredMethodElement#inject
/***属性上有注解构建的处理对象*/privateclassAutowiredFieldElementextendsInjectionMetadata.InjectedElement{ privatefinalbooleanrequired;privatevolatilebooleancached;@NullableprivatevolatileObjectcachedFieldValue;publicAutowiredFieldElement(Fieldfield,booleanrequired){ super(field,null);this.required=required;}@Overrideprotectedvoidinject(Objectbean,@NullableStringbeanName,@NullablePropertyValuespvs)throwsThrowable{ //获取属性名Fieldfield=(Field)this.member;Objectvalue;//Bean不是单例的话,会重复进入注入的这个操作,if(this.cached){ try{ value=resolvedCachedArgument(beanName,this.cachedFieldValue);}catch(NoSuchBeanDefinitionExceptionex){ //Unexpectedremovaloftargetbeanforcachedargument->re-resolvevalue=resolveFieldValue(field,bean,beanName);}}else{ //首次创建的时候进入该方法value=resolveFieldValue(field,bean,beanName);}if(value!=null){ //属性如果不为public的话,则设置为可访问ReflectionUtils.makeAccessible(field);field.set(bean,value);}}@NullableprivateObjectresolveFieldValue(Fieldfield,Objectbean,@NullableStringbeanName){ //构建DependencyDescriptor对象DependencyDescriptordesc=newDependencyDescriptor(field,this.required);desc.setContainingClass(bean.getClass());//注入bean的数量。有可能字段上是一个ListSet<String>autowiredBeanNames=newLinkedHashSet<>(1);Assert.state(beanFactory!=null,"NoBeanFactoryavailable");//获得beanFactory类型转换类TypeConvertertypeConverter=beanFactory.getTypeConverter();Objectvalue;try{ //查找依赖关系value=beanFactory.resolveDependency(desc,beanName,autowiredBeanNames,typeConverter);}catch(BeansExceptionex){ thrownewUnsatisfiedDependencyException(null,beanName,newInjectionPoint(field),ex);}synchronized(this){ if(!this.cached){ ObjectcachedFieldValue=null;if(value!=null||this.required){ cachedFieldValue=desc;//填入依赖关系registerDependentBeans(beanName,autowiredBeanNames);//判断如果注入依赖是只有一个if(autowiredBeanNames.size()==1){ StringautowiredBeanName=autowiredBeanNames.iterator().next();if(beanFactory.containsBean(autowiredBeanName)&&beanFactory.isTypeMatch(autowiredBeanName,field.getType())){ cachedFieldValue=newShortcutDependencyDescriptor(desc,autowiredBeanName,field.getType());}}}this.cachedFieldValue=cachedFieldValue;this.cached=true;}}returnvalue;}}/***方法上有注解构建的处理对象*/privateclassAutowiredMethodElementextendsInjectionMetadata.InjectedElement{ privatefinalbooleanrequired;privatevolatilebooleancached;@NullableprivatevolatileObject[]cachedMethodArguments;publicAutowiredMethodElement(Methodmethod,booleanrequired,@NullablePropertyDescriptorpd){ super(method,pd);this.required=required;}@Overrideprotectedvoidinject(Objectbean,@NullableStringbeanName,@NullablePropertyValuespvs)throwsThrowable{ //检查属性是不会在之前就已经注入过了。如果主如果则不进行二次覆盖if(checkPropertySkipping(pvs)){ return;}Methodmethod=(Method)this.member;Object[]arguments;if(this.cached){ try{ arguments=resolveCachedArguments(beanName);}catch(NoSuchBeanDefinitionExceptionex){ //Unexpectedremovaloftargetbeanforcachedargument->re-resolvearguments=resolveMethodArguments(method,bean,beanName);}}else{ //首次创建的时候进入该方法arguments=resolveMethodArguments(method,bean,beanName);}if(arguments!=null){ try{ //属性如果不为public的话,则设置为可访问ReflectionUtils.makeAccessible(method);//调用方法并传入参数method.invoke(bean,arguments);}catch(InvocationTargetExceptionex){ throwex.getTargetException();}}}@NullableprivateObject[]resolveCachedArguments(@NullableStringbeanName){ Object[]cachedMethodArguments=this.cachedMethodArguments;if(cachedMethodArguments==null){ returnnull;}Object[]arguments=newObject[cachedMethodArguments.length];for(inti=0;i<arguments.length;i++){ arguments[i]=resolvedCachedArgument(beanName,cachedMethodArguments[i]);}returnarguments;}@NullableprivateObject[]resolveMethodArguments(Methodmethod,Objectbean,@NullableStringbeanName){ //获取方法上有几个参数intargumentCount=method.getParameterCount();Object[]arguments=newObject[argumentCount];DependencyDescriptor[]descriptors=newDependencyDescriptor[argumentCount];Set<String>autowiredBeans=newLinkedHashSet<>(argumentCount);Assert.state(beanFactory!=null,"NoBeanFactoryavailable");TypeConvertertypeConverter=beanFactory.getTypeConverter();for(inti=0;i<arguments.length;i++){ //方法参数,从方法参数中取出i构造MethodParameter对象MethodParametermethodParam=newMethodParameter(method,i);DependencyDescriptorcurrDesc=newDependencyDescriptor(methodParam,this.required);currDesc.setContainingClass(bean.getClass());descriptors[i]=currDesc;try{ //获取方法中i参数的内容Objectarg=beanFactory.resolveDependency(currDesc,beanName,autowiredBeans,typeConverter);if(arg==null&Kali Linux下Dirb工具web网站目录爆破指南
在本文中,我们将详细介绍如何在Kali Linux下使用DIRB工具进行Web网站目录爆破。
路径遍历攻击,也称为目录遍历,允许攻击者访问存储在Web根文件夹之外的文件和目录。通过使用“ ..”序列或其他路径操纵方法,攻击者可以访问包括应用程序源代码、配置文件和重要系统文件在内的任意文件和目录。
以下是本次攻击的目标和工具:
目标:BWAPP实验室,DVWA实验室
攻击者工具:Kali Linux
什么是DIRB?DIRB是一个Web内容扫描程序,用于查找现有的(和/或隐藏的)Web对象。它通过发起基于字典的攻击并分析响应来工作,并带有一组易于使用的预配置攻击词表。DIRB主要用于Web应用程序审核,特别是在安全性相关的测试中。
DIRB是Kali Linux内置的工具。在终端中输入特定命令,可以获取软件包中包含的工具的概述。
利用多个单词表进行目录遍历时,可以更改默认的wordlist_files common.txt,并选择另一个单词列表进行目录遍历。查看所有可用的单词表,选择合适的单词表进行攻击。
在此攻击中,common.txt被设置为目录遍历的默认单词列表。使用特定命令启动攻击,DIRB使用common.txt文件返回在目标URL中找到的枚举目录。
列举具有特定扩展名列表的目录时,可以使用dirb扫描的-X参数。此参数接受文件扩展名,然后在目标服务器或计算机上搜索给定的扩展名文件。
为了记录维护、更好的可读性和将来参考,可以将dirb扫描的输出保存到文件中。使用dirb扫描的参数-o可以将输出保存在文本文件中。
在扫描过程中,可以忽略不必要的状态码,如NOT FOUND代码。使用dirb扫描的参数-N可以实现此功能。
在默认扫描中,某些页面会生成警告。使用dirb扫描的-w参数可以避免这些警告,继续深入扫描。
在不同情况下,可能需要将扫描延迟一段时间,以避免泛洪。使用dirb扫描的-z参数可以设置延迟时间。
默认情况下,dirb扫描以递归方式扫描目录。但在某些情况下,可以使用-r参数将Dirb设置为不递归扫描。
dirb扫描会跳过 Not Found错误消息。要查找这些页面,可以使用dirb扫描的-v参数。
通过将–X参数与具有特定扩展名(例如.php)的目标URL一起使用,可以枚举所有具有.php扩展名的文件或目录。通过将–H参数与特定扩展名一起使用(例如.php与目标URL一起),可以枚举用php命名的所有文件或目录。
在运行dirb工具时,可能需要在URL的末尾添加一个正斜杠(/)。使用-t参数可以避免在网址上强制使用结尾的“/”。
在需要HTTP授权的情况下,可以使用dirb的帮助下绕过这种身份验证。使用以下命令,将显示测试的状态码:目标URL上的测试和授权凭证。
使用–p选项可以将代理网址用于所有请求。在Web浏览器中浏览目标网络IP时,如果显示了“禁止访问错误”,则表示该网页是在某些代理后面运行。通过启用代理参数,可以使用dirb扫描代理后面的网页。
2024-11-30 06:10
2024-11-30 06:07
2024-11-30 05:51
2024-11-30 05:21
2024-11-30 04:58
2024-11-30 04:45
2024-11-30 04:20
2024-11-30 04:16