table of Contents
Thinkphp <= 5.0.10 reproduction buffer getshell
0x01 bit
First look at a scene using the cache function
The following cache file and then generates
You can see, the string abc stored directly to end with php cache files. Try to use \ n newline getshell
Grammar is wrong, comments about the garbage characters, successful getshell back.
0x02 tracking source
First follow up Cache :: set 18 rows () function
Follow self :: init ()
In this case self :: $ handler is null, the block into the true, since the above call is self :: init (), no parameters, so that the line 67 does not satisfy the conditions.
Line 69, to view the value of the configuration cache.type found by default File,
Therefore conditions are not satisfied, into the line 72. cache array above figure here as a parameter called self :: connect (). Follow connect method
Here a series of judging, based on the value of cache.type found File cache driven, corresponding to think \ cache \ driver \ File class 44 rows. Then instantiated in line 51, and return.
Back to the functions, but also directly return
Continue backtracking
Here's an example method calls the set return over. Follow think \ cache \ driver \ File set methods
It can be seen in the 142 line calls getCacheKey method.
After follow-up method getCacheKey found here since the default value options [ 'cache_subdir'] is true, so here the results directly after the first two parameters md5 encryption as the directory name, the remaining 30 bits as the cache file name. By then return after stitching .php.
Then continue back to the above configuration filename acquired, about to be serialized in the $ 146 value, then the line at 149 gzcompress its binary compression. Then splicing php tags before and after the 151 line data, and finally write the file in line 152.
The point here is that there are loopholes in the line 151 into the user-controllable data in the php tags.
0x03 audit idea
拿到源码后,找到Cache::set(name, value, expire),其中缓存文件名是跟name相关联的,因此可以看作是一个已知条件。漏洞的关键点就是value是否可控。
0x04 补丁
看一下修复之后的结果(v5.0.15)
这里在data之前加了一个exit()强制退出,基本杜绝了data执行php代码的可能。