系统版本对LM和NTLM的支持
NTLM 认证
简介
NTLM是NT LAN Manager的缩写,NTLM是指telnet的一种验证身份方式,即问询/应答身份验证协议
认证流程
进行一个嫌弃自己的字好丑
这就是我理解的并且画的流程图
用户登录客户端,进行本地认证
客户端首先在本地将当前用户的密码加密为HTLM Hash
确认双方协议版本,客户端向服务器明文发送自己的账号
服务器返回一个十六位随机数,也就是图中的challenge
客户端需要使用本地的NTLM Hash来加密这个challenge并发回给服务器,也就是图中的response
服务器将明文的用户名、challenge、response发给域控制器(DC
域控制器用这个用户名在SAM密码管理库中找此用户对应的NTLM Hash
用这个NTLM Hash来加密服务器发过来的与发给用户端一样的challenge,与服务器端传过来的response进行对比,如果相同,那么就认证成功
本地认证
Windows不会储存用户的明文密码,而是将明文密码加密后储存在SAM中
本地认证的过程中,用户登录时,系统会自动将用户输入的明文 ...
该协议涉及的攻击手段如下
理解协议过程所画的草稿图
鉴于我画的图丑晕了,于是在笔记中还是使用别人的图吧
未引入TGS前的认证流程
客户端向KDC发起对sessionkey的请求,KDC使用数据库中存储的该客户端的密码对sessionkey进行加密,同时向客户端请求的服务器发送同样的sessionkey,但使用服务器端的密码进行加密,然后客户端再使用sessionkey向服务器进行认证
在这个流程中我们可以发现一些问题
.A向KDC申请sessionkey,KDC同时向A和B发送sessionkey,如果由于网络等原因导致B在A向它请求认证时还没有收到sessionkey就会导致认证失败,所以可以尝试在返回给A使用client password加密的sessionkey的时候将本该发给B的信息一同发送给A,再由A向B请求验证的时候一同发送给B
.A提出SessionKey的申请时,KDC凭什么就生成了SessionKey给了A,也就是说,KDC缺乏对A的认证,所以在分发SessionKey之前,KDC需要增加对A的认证,解决办法就是,将KDC机构分成两部分:
AS:Authe ...
fault的
开端
依稀记得今年的开始是刷题,彼时的我刚进入智邮普创一月有余,仍然在刷题积累的阶段,每周要交的周报便是最大的苦恼,周报内容是否完善,是否有收获,是否有质量,这三点便组成了我唯一的苦恼,现在说起来倒有些好笑,最开始的我竟然因为周报而烦恼过哈哈哈哈。在进入minink后有多了每周需要上交的刷题wp,,紧接着就是打N junior,对当时的我确实是一个不小的打击,从觉得自己学了很多到逐渐意识到自己甚至冰山一角都没有触及的过程是比较痛苦的,这就是我在今年遭受的第一次打击。周报与N junior,组成了我今年的开端。
责任
若要说起我今年学到最多的东西,很显然是责任,或者确切些说是如何成为一个大人。
去年刚从高中的大门走出,觉得大学里很多事情都很复杂,总是想躲到师傅身后,让他去替我做所有的决定,然后好逃避自己应该有的责任。从大一下学期开始,无论是与没见过的人打交道,亦或是和同级之间的交往合作,总是让我觉得压力倍增,好在我拥有实验室同级的鼓励和安慰以及师傅时不时的指导,在处理很多事情的时候也有人可以给我一些建议,一切的一切都让我觉得不那么孤单。
到了大二,成为了智邮普创 ...
[HGAME Week]饭卡的uno
发现是hex文件,于是尝试直接拖到ida里逆向分析,发现直接可以拿到flag
[HGAME Week]Help marvin
发现附件是一个.sr文件,在查找下发现了pulseview这个工具,于是尝试进行一个利用,结合提示的SPI,猜测是使用spi协议来解析这段
SPI协议
链接:https://zhuanlan.zhihu.com/p/
.用单独的数据线和单独的时钟信号来保证发送端和接收端的数据同步
.产生始终的一侧称为主机,另一侧为从机,总是只有一个主机
.数据采集在时钟信号上升沿或下降沿进行
时钟是一个震荡信号,它告诉接收端在确切的时机对数据线上的信号进行采样
主机发送到从机时:主机产生相应的时钟信号,然后数据一位一位地将从MOSI信号线上进行发送到从机;
主机接收从机数据:如果从机需要将数据发送回主机,则主机将继续生成预定数量的时钟信号,并且从机会将数据通过MISO信号线发送;
具体如图所示
SPI总线包括条逻辑线,定义如下:
MISO:Master input s ...
TransformedMap
这是除yso中的LazyMap之外的另一种TransformedMap的链子
环境配置就不说了,网上太多教程了(实话说这环境配好好久了,每次调一半就开摆,这次一定一定不能摆了)
我们先从Transformer这个接口看起,来查找它的实现类
我们在直奔主题前看到这个东西
ChainedTransformer
这个代码我们瞅一眼它的transform方法
它的功能很显而易见就是实现了一个链式递归调用,将前一个的输出作为后一个的输入,gadget也是需要这样的东西来帮助自动调用链的
好了,我们现在直接进入主题
InvokerTransformer
很显然可以知道它继承了serializable,我们再去看看它的transform方法
显然它在用反射来动态调用我们输入的对象和方法,这些全是我们自己可控的,这一听就是个很危险的东西,专业点说就是任意方法调用
我们尝试用这个方法弹计算器(典!
// Runtime.getRuntime().exec("calc.exe");
但我们刚才的目的是要试试这个方法来实现任意方法调用, ...
为什么我不看CC,而是选择在看完CC之后去看CC,是因为它和CC的LazyMap有关系,所以我们将CC拉前头看
这里是因为发现了一个TiedMapEntry的类,发现它的hashcode方法(注意这里和URLDNS链不同的是URLDNS链用的是HashMap里的hashcode方法,而这里是需要通过HashMap中的readObject来调用TiedMapEntry中的hashcode方法,二者本质上不同)
我们先去看TiedMapEntry的构造方法
传完赋值
我们再去看看HashMap的readObject方法中是对key还是value调用hash
这里很显然是对key进行了hash操作,说到这可能有点不明白这个hash和hashcode方法有什么关系,我们再去跟踪一手就能看出来
其实它调用了key的hashcode方法,而这个key显然可控,所以我们需要将东西放到key里而不是value里
成功了,但是还记得URLDNS中的put方法中也有hash么
我们去看看它的hash方法
喵,眼熟了,所以说我们根本没有走我们设想的路,它直接通过hashMap的put方 ...
呜呜呜maven构建的好快,我猫猫都没看完
CC了喵,加油喵
直接看yso的吧
PriorityQueue.readObjet->TransformingComparator.compare->CC.InstantiateTransformer 之后
TransformingComparator
我们先分析一下cc和cc中不同之处的关键
点,就是这个compare方法,二者有什么不一样
CC中
CC中
二者所实现的接口不同,CC实现了Serializable接口而CC中没有
所以我们开始写代码咯
TemplatesImpl templates = new TemplatesImpl(); Class templatesClazz = templates.getClass(); Field nameField = templatesClazz.getDeclaredField("_name"); ...
终于!!!绕了一大圈终于过来力!!!
CC它其实是没有走TrAXFilter的这里
的实例化,而是尝试用InvokerTransformer去调用了
我们使用invokerTransformer方法调用代码如下
InvokerTransformer invokerTransformer = new InvokerTransformer<>("newTransformer",new Class[],new Object[]);
后面的就还和CC一样
但当我运行的时候说没有这个类,所以我考虑是template没有传进去
最后看了别人的说要在add那里加上templates,而且第一个必须是templates
我进行了一个调试
当我们还是用add和的时候我们跟进去看看
走到heapify
compare方法
找到原因了,因为它需要在这里调用它的method,而我们传的是数字,所以这里变成了这样
而当我们将和改成template后我们追到这里看看吧
compare方法
我们会发现这里加载到 ...
pre
CC和我们刚才调试的CC有一些不同,CC和CC我们可以知道命令执行的方式是Runtime.getRuntime().exec但众所周知Java还可以通过加载任意类来进行恶意行为
CC是基于这个的,所以我今天也花了不少时间来重新学习动态类加载,在初步学习之后的基础上,开始调试CC
根据动态类加载的学习我们可以知道利用点通常在defineClass中,它是从字节码中加载
这个链子鉴于之前学习动态类加载的时候对加载器包括defineClass有相关调试,我就不在这个笔记中过多赘述了
TemplatesImpl
本质问题出在这里
我们一路一路往上头找,找到了
newTransformer->getTransletInstance->defineTransletClasses->defineClass
所以我们开始调试,看看这样的调用链需要满足什么条件
首先是这里
因为它直接进行了判定,所以我们看看它的构造函数有没有对它赋值
我们发现是对它的_class不有赋值,这样我们才能进到defineTransletClasses里,然后我们继续跟进
发现by ...
我们尝试编写Person类如下
各类方法调用情况
无参方法
有参方法
静态方法
赋值
==所以说Java的类在初始化的时候就会调用静态代码块==
获取类
所以class关键字只对Java类进行加载,并不会进行初始化
==类在实例化的时候会调用构造代码块==
动态加载类
Class.forName()
我们跟进去看看
这里没有,我们可以看看它重载的另一种方法
它是否初始化的值是在这里确定的
也就是说它默认是初始化了的
我们尝试使用这个重载方法进行观察
代码如下
ClassLoader cl = ClassLoader.getSystemClassLoader(); Class.forName("Person",false,cl);
这样就被认为是没有初始化后的
输出如下
在这里我们用了一个类加载器,那么如果我们使用这个类加载器去加载类,也就是用它的loadClass方法,它是否会对类进行初始化呢
我们发现输出为空,那么很明显loadClass方法不会对类进行初始化
我们来瞅瞅类加载的具体实现
我们直接打断点调到loadClass方法里
...