0%

[RWCTF2021]wp

好像也一个题不会来着,其实算是个复现吧。。。
以及寒假+过年摸了好久的鱼。。。

Hack into Skynet

最多解的web,是一个加了一个迷之AI的pgsql注入

#!/usr/bin/env python3

import flask
import psycopg2
import datetime
import hashlib
from skynet import Skynet

app = flask.Flask(__name__, static_url_path='')
skynet = Skynet()

def skynet_detect():
    req = {
        'method': flask.request.method,
        'path': flask.request.full_path,
        'host': flask.request.headers.get('host'),
        'content_type': flask.request.headers.get('content-type'),
        'useragent': flask.request.headers.get('user-agent'),
        'referer': flask.request.headers.get('referer'),
        'cookie': flask.request.headers.get('cookie'),
        'body': str(flask.request.get_data()),
    }
    _, result = skynet.classify(req)
    return result and result['attack']

@app.route('/static/<path:path>')
def static_files(path):
    return flask.send_from_directory('static', path)

@app.route('/', methods=['GET', 'POST'])
def do_query():
    if skynet_detect():
        return flask.abort(403)

    if not query_login_state():
        response = flask.make_response('No login, redirecting', 302)
        response.location = flask.escape('/login')
        return response

    if flask.request.method == 'GET':
        return flask.send_from_directory('', 'index.html')
    elif flask.request.method == 'POST':
        kt = query_kill_time()
        if kt:
            result = kt 
        else:
            result = ''
        return flask.render_template('index.html', result=result)
    else:
        return flask.abort(400)

@app.route('/login', methods=['GET', 'POST'])
def do_login():
    if skynet_detect():
        return flask.abort(403)

    if flask.request.method == 'GET':
        return flask.send_from_directory('static', 'login.html')
    elif flask.request.method == 'POST':
        if not query_login_attempt():
            return flask.send_from_directory('static', 'login.html')
        else:
            session = create_session()
            response = flask.make_response('Login success', 302)
            response.set_cookie('SessionId', session)
            response.location = flask.escape('/')
            return response
    else:
        return flask.abort(400)

def query_login_state():
    sid = flask.request.cookies.get('SessionId', '')
    if not sid:
        return False

    now = datetime.datetime.now()
    with psycopg2.connect(
            host="challenge-db",
            database="ctf",
            user="ctf",
            password="ctf") as conn:
        cursor = conn.cursor()
        cursor.execute("SELECT sessionid"
           "  FROM login_session"
           "  WHERE sessionid = %s"
           "    AND valid_since <= %s"
           "    AND valid_until >= %s"
           "", (sid, now, now))
        data = [r for r in cursor.fetchall()]
        return bool(data)

def query_login_attempt():
    username = flask.request.form.get('username', '')
    password = flask.request.form.get('password', '')
    if not username and not password:
        return False

    sql = ("SELECT id, account"
           "  FROM target_credentials"
           "  WHERE password = '{}'").format(hashlib.md5(password.encode()).hexdigest())
    user = sql_exec(sql)
    name = user[0][1] if user and user[0] and user[0][1] else ''
    return name == username

def create_session():
    valid_since = datetime.datetime.now()
    valid_until = datetime.datetime.now() + datetime.timedelta(days=1)
    sessionid = hashlib.md5((str(valid_since)+str(valid_until)+str(datetime.datetime.now())).encode()).hexdigest()

    sql_exec_update(("INSERT INTO login_session (sessionid, valid_since, valid_until)"
           "  VALUES ('{}', '{}', '{}')").format(sessionid, valid_since, valid_until))
    return sessionid

def query_kill_time():
    name = flask.request.form.get('name', '')
    if not name:
        return None

    sql = ("SELECT name, born"
           "  FROM target"
           "  WHERE age > 0"
           "    AND name = '{}'").format(name)
    nb = sql_exec(sql)
    if not nb:
        return None
    return '{}: {}'.format(*nb[0])

def sql_exec(stmt):
    data = list()
    try:
        with psycopg2.connect(
                host="challenge-db",
                database="ctf",
                user="ctf",
                password="ctf") as conn:
            cursor = conn.cursor()
            cursor.execute(stmt)
            for row in cursor.fetchall():
                data.append([col for col in row])
            cursor.close()
    except Exception as e:
        print(e)
    return data

def sql_exec_update(stmt):
    data = list()
    try:
        with psycopg2.connect(
                host="challenge-db",
                database="ctf",
                user="ctf",
                password="ctf") as conn:
            cursor = conn.cursor()
            cursor.execute(stmt)
            conn.commit()
    except Exception as e:
        print(e)
    return data

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=8080)
阅读全文 »

hxpctf2021复现

还是蹭的科恩的车,虽然菜狗很努力的看了一天半,但真的菜,不会就是不会,所以仍然内容主题是复现(以及hxp这把所有web的dockerfile都非常复杂,进行了究极权限控制)
(这把在misc里面有一个log4j的题)

Log 4 sanity check

log4j题,签到难度。给了附件,class直接反汇编出来,就是nc上去输一个字符串然后直接log4j打印一下触发

究极dockerfile

阅读全文 »

bytectf2021final复现

菜狗并没有打进ByteCTF2021 final,但是在比赛结束之后环境并没有立即关闭,感谢rmb神仙带我,让我进行复现呜呜

seo

一个前端写的还挺好看的站,有一些乱七八糟的功能,写了好几个api,实际上有用的只有一个词库里面的任意文件下载,然后下/api/ip.php,有一个curl的ssrf
这个ssrf还把请求的结果base64一下再返回,真的是很贴心的配合gopher的操作,就是接下来的操作并不是非常的人性化,扫网段找服务?先读/etc/hosts确定机器的网段是172.73.23.0/24,然后我也不知道扫什么服务就硬扫全网段?有点离谱
rmb神仙说先扫gopherus里面常见的能打的服务,扫全端口肯定不现实,所以是扫整个网段内的特定端口,比如redis,mysql之类的,因此可以在172.73.23.100:3306上扫到一个mysql。(我还是觉得离谱)

看了下wm的wp,读了/proc/net/arp,能够迅速的发现172.73.23.100的存在

阅读全文 »

[HITCON2021]web

科恩究极联队katzebin出动,在坐了两天牢后顺利偷学神仙思路
web都是台湾神仙Orange出的题,有的题目有些迷之脑洞,有的题目又比较的有意思,但总而言之,我都不会嘻嘻

One-bit-man

可以修改WordPress中源码的一个bit来制造RCE
目前的想法就是可能有什么危险的配置项,直接把0变成1之类的,但是简单搜索了一下好像并没有搜到什么有用的数据

看wp完成,原来是直接修改登录处的判断,能使用任意密码登录WordPress,而WordPress以管理员身份登进去之后可以自由rce
是我完全不懂了呜呜,早知如此何必当初

阅读全文 »

拟态&L3H&深育&湖湘&西湖&N1

拟态决赛和L3H打不过,深育杯错过了没打,湖湘杯。。。妄图最后一个小时通过关积分榜的方式反抗诸神黄昏,然后直接打到诸神全灭,经典
西湖论剑做了一天牢,三个究极CMS审计血克我这种垃圾,唯一一个有希望的模板渲染也跑偏了。。。N1CTF也看了一眼题,除了签到只有一个看懂了呢

慢慢的看wp进行复现或者事后诸葛亮

拟态决赛

除了拟态环境N连外,还有两个题看了一下,都是做到最后一步做不出来了。。猛男落泪.jpg
黑盒看不懂,白盒要钱没人一起就没试过。总的来说是没体验到什么东西了

阅读全文 »