• 要写脚本,编程不好不要紧--浅谈CTF中脚本的编写方法


    1. 脚本在CTF比赛中的作用

    CTF夺旗赛中往往分为杂项(MISC)、密码(CRYPTO)、WEB、逆向(REVERSE)和PWN。
    
    • 1

    在目前的比赛中,各种工具起到的作用在不断下降,一击必杀拿到flag很少见了。往往需要根据题目临时编制脚本,进行调试、爆破、破解算法才能顺利解题。
    多以参加CTF比赛一定要有自己写脚本的能力。

    2. 编程技术不好,怎么办

    往往很多同学会说编程技术不好是不是要重新学开发才可以。其实大可不必,脚本不是web开发或是网络编程,不需要那么高的要求。
    就像你英语不好,但置身国外怎么办,你要拿英语书从头学吗?当然不是,想尽办法,只要能让对方get到你的意思就行。努力去说去沟通,慢慢就会了。脚本编制也依然,需要用到什么,就搞懂哪里,多写多练,慢慢就能上手。到那时再系统学编程也为时不晚。

    下面我就简单举例介绍下脚本是怎么一步步根据题目写出来的。 有编程基础的同学,可能一看就会,基础薄弱的同学,不要紧,get到思路勤加练习是最重要的。CTF中根据线索和源码找到解题思路和实操能力才是最重要的。

    主要以python脚本为主

    代码中的函数不认识怎么办,百度搜索看下很快就能掌握这个函数的用法,仅此而已,学以致用是脚本的关键。

    3. 脚本编制简单举例

    3.1杂项题目:一个充满0、1的TXT文件

    拿到题目,是个txt文件,里面写满了0和1。
    请添加图片描述

    有点想法了是不是,杂项中经常考二维码,大家已经习惯了使用工具去分析。难道此题另辟蹊径,不直接提供二维码,反而需要自行构建?以CTF各种反人类的出题方式,可能性很高呢。可如何构建,下面就来一步步分析,分析完脚本也就出来了。

    1. 首先,构建二维码就要知道二维码的边长(正方形哦),所以python脚本就要读取txt文件,获取文件的大小,再开方不就得到了边长吗?
    import math
    
    # 1.判断二维码数据是否可用
    f = open('txt文件路径', 'r')
    s = f.read()
    print(len(s))
    # 开平方根,如果二进制大小能整除,证明是正方形,得出宽、高  x=y=260
    print(math.sqrt(len(s)))
    
    # 结果是260,解题思路正确的概率飙升到80%
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1. 不管题目,绘制二维码本质上就是要在边长为260的画布上画图 吗?这就要用上python大名鼎鼎的库PIL了。

    记住PIL库创建画布的代码套路,永远都这样,就记住下面几行代码就行,套路都一样的。

    from PIL import Image
    x = 260
    y = 260
    image_new = Image.new('RGB', (x,y), (0,0,0)) # RGB模式,边长均为260,黑色(0,0,0)\白色(255,255,255)
    image_new.show()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述
    3. 那下一步是什么,结合题目 线索就是0,1。那简单啊,(反正复杂的也不会,哈哈)二维码就两个颜色白色和黑色,随机吧核心逻辑就是判断是0还是1, 0就将该橡塑上黑色(0,0,0),1就上白色(255,255,255)

    还是老样子,PIL库如何对不同像素上色呢,使用函数putpixel,代码记套路。哪里不会就百度哪里。循环语句和文件读取语法,如果真是小白,这个可以百度学习python相关内容,自学时间3h吧。不要学太深,能看懂脚本的程度就可以。

    # 3. 区分0或1分别上色黑或白,修复完整二维码
    idx = 0    # idx表示txt文件中数据序号,第一个数据为0号,对应坐标点(0,0)  下一个1号对用坐标点(1,0)
    for y in range(0, 260):   # 就是平面坐标(x,y)初中几何的知识,只不过用代码写出来
        for x in range(0, 260):
            data = s[idx]  
            if data == '0': # 假如txt中第一个数据为0,对应坐标点(0,0),就给他上黑丝(黑色)
                img_new.putpixel((x,y),(0,0,0)) 
            elif data == '1':
                img_new.putpixel((x,y),(255,255,255))
            idx += 1
    img_new.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1. 汇总以上3个步骤,完整脚本和结果如下。
    import math
    from PIL import Image
    
    # 1.判断二维码数据是否可用
    f = open('txt文件路径', 'r')
    s = f.read()
    print(len(s))
    # 开平方根,如果二进制大小能整除,证明是长方形,得出宽、高  x=y=260
    print(math.sqrt(len(s)))
    
    # 2. 测试每个像素点上色(全白、全黑)
    x = 260
    y = 260
    img_new = Image.new('RGB', (x,y), (0,0,0)) # RGB模式,边长均为260,黑色(0,0,0)\白色(255,255,255)
    # image_new.show()
    
    # 3. 区分0或1分别上色黑或白,修复完整二维码
    idx = 0
    for y in range(0, 260):
        for x in range(0, 260):
            data = s[idx]
            if data == '0':
                img_new.putpixel((x,y),(0,0,0))
            elif data == '1':
                img_new.putpixel((x,y),(255,255,255))
            idx += 1
    img_new.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    请添加图片描述
    大家放心扫码吧,不是我的收款码~

    3.2 加密题目:标准凯撒爆破脚本

    基础知识:凯撒密码是一种最简单且最广为人知的加密 技术,它属于替代加密,明文中的所有字母都在字母表上向后(或 向前)按照一个固定数目进行偏移后被替换成密文。
    举例如下:
    原始字母表 ABCDEFGHIGKLMNOPQRSTUVWXYZ key=3 每个字母右移3位
    新的字母表 DEFGHIGKLMNOPQRSTUVWXYZABC
    若明文M=“HEASON”
    则密文C = “KHDVRQ” 解密同理左移3位即可
    所谓的密钥就是上面的key,他只有25中可能(key=1就是自己去掉这个)。所以写个脚本遍历出所有结果,看到那个字段有意义,其实就完成破解了。

    from string import ascii_letters
    str1 = 'ComeChina'
    str2 = str1.lower()
    num = 1
    table = ascii_letters
    for i in range(26):
        print("{}:  ".format(num), end='')
        for temp in str2:
            if temp not in table:
                print(chr(ord(temp)), end="")
            elif ((ord(temp)+num)>ord('z')):
                print(chr((ord(temp)+num)-26), end='')
            else:
                print(chr((ord(temp)+num)), end='')
        num += 1
        print("")
    # 结果会输出26种全部结果,其中有个flag
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    如果你看不懂这段代码,我想不是脚本多难,而是

    1. 你可能不知道ascii码的相关知识 就是脚本中的ord函数。本质上就是将一个字符转换成唯一的十进制数,方便运算。每个字符均会对应一个十进制数。后面chr就是反过来,将十进制数转换为对应字符。动手网上搜下ascii就能了解了,自学时长20min吧
    2. 前文说了循环结构需要学下。不会的函数百度下,瞬间就会明了。

    3.3 加密题目:变异凯撒脚本

    有了上面一题的铺垫,此题就好理解了。变异凯撒不是固定key,而是key有规律变化,如本例题,第一个字符,key=5加密。后面每个字符,key都增加1再进行加密,依次类推。
    脚本如下,设置个初始key=5,然后在循环中,处理完一个字符,就增加1即可。

    key = 5  # 初始key值
    result = ""
    content = "afZ_r9VYfScOeO_UL^RWUc"  # 密文
    for i in range(len(content)):
        ori = ord(content[i]) + key
        result += chr(ori)
        key += 1
    print(result)
    
    # 输出结果 flag{Caesar_variation}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.4 逆向题目

    本文不关心逆向解题方法,只关注脚本。所以逆向的脚本反而最简单,原伪代码中算法都写好了,脚本反着写就行。
    省略掉逆向题目的前期分析,直接上伪代码
    在这里插入图片描述
    注意第32行,是伪代码的算法。我们编制的脚本很简单,既然要破解,那就把算法反过来运算,不就行了?

    # 1.原始24位字符串
    key1 = 'xIrCj~
    flag = ""
    
    # 2. 获取每位的ascii值,(x^6)-1  注意异或运算优先级低于加减
    for i in range(0, len(key1)):
        flag += chr((ord(key1[i])^6) - 1) # 注意:异或运算优先级低于加减,所以要写成(ord()^6)-1
    
    #3. 倒序输出
    print(flag)
    print(flag[::-1]) # 逆序输出
    
    # }NsDkw9sy3qPto4UqNx{galf
    # flag{xNqU4otPq3ys9wkDsN}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    脚本很简单吧,简单到令人发指。

    4. 总结

    所以,CTF比赛中脚本的编制,没有大家想象的那么难。真正难得地方是思路,是找到破题点。

    如果基础较弱,在日常CTF学习中,遇到不明白的函数,随遇随学,多记套路用法即可。不断练习已经理解的脚本,不断重温新学的函数,写的多,自然就入门了。等真正有时间,再系统学习一门编程语言即可。
    个人经验,为了学习而学习,永远学不好。为了一个目标,用“偷懒”的办法,学以致用,不断巩固练习,效果反而好。

  • 相关阅读:
    pytorch无法使用cuda
    102个Python练手项目;『机器学习』优质内容社区;『基于事件的机器人视觉』课程推荐;『迁移学习导论』书籍代码;前沿论文 | ShowMeAI资讯日报
    微信小程序会议OA系统
    Java @Override 注解
    apollo 8.0 系统安装与实践
    【java算法专场】双指针(上)
    TI的单芯片毫米波雷达传感器配置命令是如何传递到DSP和ARM核的?(串口程序代码走读)
    java lambda之方法句柄&invokedynamic指令
    FreeRTOS移植
    MLX90363KDC 3轴X,Y,Z 磁力计位置传感器IC
  • 原文地址:https://blog.csdn.net/eason612/article/details/126202413