🌈超凡学堂/在线教学
2.27K subscribers
87 photos
6 files
1 link
“学习”是指通过获取经验或知识,

从而改变行为或思维模式的过程。

学习是通过实践或经验获取知识或技能的过程

从而导致长期的行为变化。

这种获取是通过与环境的互动实现的,

并且需要实践或经验。
Download Telegram
存在权限管理问题,可以通过cat /etc/inid.d/rcS 读取Flag



随后修复非预期漏洞后,观察模块xkmod可以发现在初始化函数xkmod_init中,程序申请了一个slab来管理0xc0大小的堆块
进程cred结构生成相关的slab cred_jar,其管理的堆块大小也是0xC0,而根据内核的slab管理机制,会优先分配相同大小的slab,所以xkmod_init中创建的slab其实就是cred_jar。

通过xkmod_ioctl申请一个堆块

释放该堆块

fork一个进程,新进程会申请刚刚释放的堆块存放cred

通过UAF修改子进程的cred,将uid、gid等置为0,完成提权
程序的主要问题在于,对寄存器范围的判断使用的是有符号比较,且只判断了上限,所以可以使用`LOAD/STORE`指令,通过寄存器来任意地址读写。

因为程序只能接受一次输入,所以虽然存在输出指令`PRINT/POPP`,但是并不能使用这些指令来leak需要的地址。



但是可以通过`SUB`指令,计算出程序基址,libc基址等,并放置在vm的栈上;然后使用`ADD`指令计算出gadget,system,/bin/sh等地址,再通过`STORE`控制程序执行流getshell。
漏洞分析

需要让主合约的isSolved()函数返回True,才能拿到Flag。

让isSvd返回True,我们需要成功调用solve函数。而solve函数会检查调用者是否持有100个以上的鱼人币。那么如何才能获得100个以上的鱼人币呢?根据题目名称的提示,我们来到鱼人币合约的TransferFrom函数。

跟进_transfer函数:

问题出现在了254行,ERC20合约的转账操作 被定义为 转出者余额减少,转入者余额增加。但如图所示,合约并没有检查转出者的余额是否足够减少。这边产生了漏洞。即使from账户没有钱,也可以向任意账户转账。
利用


现在我们来利用这个漏洞来盗取101个fishmenToken
我们的思路是构造一个攻击者合约,让合约直接给我们的钱包转账101个fishmenToken即可。

合约代码如下

直接部署该合约即可获得101个鱼人币。
随后调用题目合约的isSolved()函数。即可将isSvd设为True;解题成功。
pkexec 本地提权

Ubuntu、Debian、Fedora 和 CentOS 的默认安装环境上均测试通过。漏洞利用难度不高,最早引入问题的 commit 来自 2024 年,影响版本范围远超去年的 sudo 漏洞。

漏洞是本地触发,只有在获得有限权限的前提下提升至 root。

Polkit 是一个应用程序级别的工具集,通过定义和审核权限规则,实现不同优先级进程间的通讯:控制决策集中在统一的框架之中,决定低优先级进程是否有权访问高优先级进程。

Polkit 在系统层级进行权限控制,提供了一个低优先级进程和高优先级进程进行通讯的系统。和 sudo 等程序不同,Polkit 并没有赋予进程完全的 root 权限,而是通过一个集中的策略系统进行更精细的授权。
绕过 stristr() 的潜在方法:

1. 欺骗 CWP,使其将其他字符视为点号 (.)

2. 找出 C 语言在小写时作为点 (.) 处理的唯一字符。

3. 欺骗 CWP,让它认为没有连续的点(..)

1. 欺骗 CWP,使其将其他字符视为点:

第一种方法是在对一个基本的 Unicode 字符范围进行模糊测试后,我们很快发现 CWP 中没有任何字符会被规范化为点号。
CWP 中的一些函数(包括 require() 和 include() 函数)似乎会将 / .%00./处理成 / ../。同样,虽然它们的 stristr() 函数会忽略空字节,但它仍然会计算其大小,因此绕过了检查。我们不太确定具体原因,但这可能是由于他们的库中使用了类似 striptags() 的函数而导致的回归问题。

现在利用这个技巧,我们可以将服务器上的任何本地文件包含在内。我们拥有一个完整的文件包含漏洞,如果我们找到写入文件的方法,就可以获得预认证远程代码执行 (RCE)。然而,下一步并不像我们想象的那么简单,因为 CWP 自带名为 CWP-Secure-Kernel 的特殊 Unix 文件读写锁定设置。服务器不会轻易授予我们对日志或其他任何明显有用的文件进行写入或编辑的权限。

但利用我们的文件包含漏洞,我们可以访问受限的 API 部分。该部分需要 API 密钥才能访问,并且由于未在网站根目录中公开,因此无法直接访问。但通过利用我们的文件包含漏洞,发送如下请求将使服务器注册我们想要的任何 API 密钥。
文件结构

Telegram/SourceFiles/storage/details/storage_file_utilities.cpp:ReadFile()函数中可以很清楚的看到telergram读取文件的逻辑。数据文件主要分为四个部分,依次为魔数,版本号,加密数据和签名,其中魔数占据文件的前四个字节,固定为TDF$(telegram desktop file),版本号占据后四个字节(当前为0x002dd278 = 3003000 = v3.3.0),接下来是加密数据,最后文件末尾为16个字节的签名。
CWP CentOS Web 面板 – 预授权远程代码执行

以在 Shodan 或 Census 上找到。我们利用的漏洞链实现了以 root 用户身份执行完整的预认证远程命令,该漏洞链利用了文件包含漏洞 (CVE-2025-45467) 和文件写入漏洞 (CVE-2025-45466)。本文将介绍我们的漏洞研究过程,以及我们如何着手攻击这个特定目标。
根据我们之前的分析已经知道,调用这个函数的时候,会把ecx的值解密然后放入到edx中。

于是我们在下面的内存窗口中,Ctrl +G 输入 edx,直接跳转到当前edx所指向的地址,这里提示了是0021EF9C

然后我们F8单步执行完这个解密函数,可以看到edx所指的这个地址已经成功解密出了urlmon.dll
我们可以看到,sub_3811E0调用完成之后,会通过test eax,eax判断eax的值是否为0,如果eax为0 则跳转到loc_3833BD,跳转过来之后结束winMain的运行。

很明显,eax是不为0的,因为我们在代码中可以看到,sub_3811E0函数的最后,通过mov eax,1的方式给eax赋值为了1,所以此时eax等于1.

eax等于1,那么程序就会连着执行四个call,分别是sub_383600、sub_381580、sub_381770、sub_382790。
我们先跟进到sub_383600。

sub_383600
IDA中双击进入到函数,熟悉的_memset内存分配

然后通过call SHGetFolderPathA获取系统路径,具体获取的值由参数决定。
其中第一个是[ebp + pszPath] ,也就是SHGetFolderPath函数获取到的路径。

第二个参数是aSEsetUpdateExe,IDA已经自动识别出来是%seset_update.exe

第三个参数是[ebp+NewFileName]

这里第二个参数前面的%s比较关键,基本可以推测sub_383320用于将push的第一个参数和第二个参数拼接起来放到第三个参数,也就是[ebp+NewFileName]。这里为什么不猜测sub_383320用于将应用程序拷贝到%appdata%路径并且重命名为eset_update.exe。 是因为我们可以看到GetModuleFileNameA获取到的路径会存放在[ebp+Filename]中,而在调用sub_383320的时候,并没有将[ebp+Filename]作为参数传入,所以sub_383320的功能应该是路径拼接
跟进到sub_383320之后,发现和我们推算的一致,程序会通过_vsprintf_s进行拼接。

在sub_383320调用完成之后,[ebp+NewFileName]将会存放 %appdata%eset_update.exe

路径拼接之后,程序会通过lea指令,分别将ebp+Filename和ebp+NewFileName赋值给ecx和eax,在后面可以看到,程序会循环对比eax和ecx的值,检查是否匹配,如果匹配,则说明当前程序运行的路径就是%appdata%eset_update.exe。
如果不匹配程序则会在003836D4这里通过jzn short loc_3836F0 跳转到后面继续执行。

跳转过来之后程序会通过sbb 错位运算和 | 1 的运算操作eax。

注意看,此时的eax还是上面的的存放的新路径的值。

这里应该是用于判断拼接的新路径是否成功,如果成功则后面的test eax,eax不为0
执行拷贝函数之后,程序会尝试将密文XTKYFWJaRnhwtxtkyansit|xaHzwwjsy[jw通过ReName_DecodeSrings函数解密存放到[ebp+SubKey]并且通过下面的RegOpenKeyExA操作该键值。

我们直接在调试器中鼠标点在0038371E这里,F4运行过来,然后在下面的内存窗口中跟随edx

F8单步执行完该函数之后,edx(0054F48C)处的地址成功被赋值为SOFTWAREMicrosoftWindowsCurrentVersionRun

这个键值已经不陌生了,该键值用于操作开机自启动项。