配置机器人 QQ机器人的基本架构 这里引用一个看到过的例子:
在一个餐馆中,你点了一盘菜。此时会发生什么事情呢?
1、服务员接受你点的菜
2、服务员把你点的菜告诉大厨
3、大厨进行一个烹饪
4、服务员把菜端到你桌上
在一个QQ机器人中,go-cqhttp就类似于一个服务员,负责接收消息、把消息传达给nonebot2、发送消息。而nonebot2 就相当于一个大厨,负责“思考”对消息该做出什么反应。
那么go-cqhttp如何将消息传达给nonebot2呢?
这里我们使用的是反向websocket连接:go-cqhttp会主动寻找nonebot2的程序,并将消息通过websocket推送给nonebot2。当然,如果你只是想要做出一个QQ机器人,你可以不需要深入了解该通信方式。
准备 我们需要:一个云服务器,nonebot2,go-cqhttp
由于nonebot2是基于python3.7+的,所以我们还需要配置一个python。
我推荐在服务器上执行命令前先使用sudo -i切换到管理员账户来避免一些麻烦
安装系统镜像&python 首先你需要一个云服务器,并安装系统镜像。我这里选用的是Ubuntu20.07系统镜像,因为Ubuntu20.07自带一个Python3.8.10,可以省去python的配置步骤。
这一步按理来说是可以一键完成的,起码腾讯云和阿里云都有一键安装的入口。
安装nonebot2 执行以下命令:
1 2 pip3 install nb-cli pip3 install nonebot-adapter-cqhttp 如果找不到库的话,可以试试换源:
1 2 pip3 install nb-cli -i https://pypi.org/simple pip3 install nonebot-adapter-cqhttp -i https://pypi.org/simple 安装go-cqhttp 下载go-cqhttp 在go-cqhttp的Release页面找到go-cqhttp_linux_386.tar.gz并下载。
或者直接点击这里下载。
这里下载的是适用于Linux的32位go-cqhttp,如果你是64位,请找到并下载go-cqhttp_linux_amd64.tar.gz
将go-cqhttp上传至服务器 这里使用宝塔Linux面板辅助上传。宝塔yyds。
这是宝塔官网,可以在上面找到对应系统镜像的安装脚本:https://www.bt.cn/download/linux.html
如果你和我一样使用Ubuntu,直接执行以下命令吧:
1 wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh 执行完成后在服务器上执行bt来配置用户名和密码。
本文基于C++、python语言基础学习.
基本 示例
1 2 3 4 5 package main import "fmt" func main() { fmt.Println("Hello, World!") } 1、当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected )
2、大括号不准换行,一行代表一个语句结束,没有分号。
3、标识符、注释规则与cpp相同。
4、变量类型:数字、字符串、布尔。
语法相关 变量相关 变量声明 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 //var v_name type //Example: var a string = "ABCD" var b, c int = 1, 2 //var v_name //Example: var d int // 初始值为0 var e string //初始值为"" //var v_name = value var f = true var g = 0 //自动判断变量类型 // v_name = value intVal := 1 //相当于: var intVal int intVal = 1 //这种结构只能在函数体中出现。 /*var( v_name1 type1 v_name2 type2 )*/ //Example: var ( a int b bool ) 函数内变量不允许声明但不使用
写在前面 好难,寄!
军训开始我就弃赛了,所以军训开始后才上的新题我一个都没有写。这里只有前面的几个水题wp。
其实回想了一下真的认真干过的题目就只有Re的生瓜蛋子和babyexception题,其他都是不会就摸鱼
Web 有人专挑php的题做,我不说是谁。
[Baby] Signin Burpsuite新手教程?抓包修改请求头的METHOD字段,然后进行一些GET、POST和修改Cookie得到flag.
CNSS{Y0u_kn0w_GET_and_POST}
[Baby]GitHacker 一个简单的git泄露板子题,使用GitExtract获得泄漏的git源码,在index.html.d54c93文件中看到flag。
CNSS{Ohhhh_mY_G0d_ur3_real_G1th4ck3r}
[Mid]BlackPage F12看到如下内容:
1 2 3 4 5 6 7 8 9 10 <?php $file = $_GET["file"]; $blacklist = "(**blacklist**)"; if (preg_match("/".$blacklist."/is",$file) == 1){ exit("Nooo,You can't read it."); }else{ include $file; } //你能读到 mybackdoor.php 吗? > 是一个文件包含漏洞的题,利用php://filter读取mybackdoor.php源码。
http://121.41.7.149:65002/?file=php://filter/read=convert.base64-encode/resource=mybackdoor.php
看到如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 <?php error_reporting(0); function blacklist($cmd){ $filter = "(\\<|\\>|Fl4g|php|curl| |0x|\\\\|python|gcc|less|root|etc|pass|http|ftp|cd|tcp|udp|cat|×|flag|ph|hp|wget|type|ty|\\$\\{IFS\\}|index|\\*)"; if (preg_match("/".
反汇编工作原理 1、基本反汇编算法 区分指令与数据,确认文件中包含代码和代码入口点的位置。 读取指令起始地址的值,查表将二进制操作码与汇编语言助记符对应起来。 格式化汇编语言并进行输出 继续反汇编下一条指令 2、如何识别反汇编起点、如何选择下一条指令、何时完成反汇编? 书中介绍了两种算法:线性扫描反汇编与递归下降反汇编
1.线性扫描反汇编 线性扫描法通过寻找一条指令结束、另一条指令开始的地方来确定需要反汇编的指令位置。具体方法为:假设程序中标注为代码的程序段内全部是机器语言指令,则从第一个字节开始逐条反汇编。这种算法并不会通过识别分支等非线性指令来了解程序的控制流。
线性扫描法的优点在于它能够完全覆盖程序的所有代码段,但其没有考虑到代码中可能混有数据。线性扫描法无法正确地将嵌入的数据与代码区分开来。
GNU调试器(gdb)、微软的WinDbg调试器和odjump的反汇编引擎均采用线性扫描算法。
2.递归下降反汇编 递归下降法强调控制流的概念。控制流根据一条指令是否被另一条指令引用来决定是否对其进行反汇编。
有以下几种指令:
1.顺序流指令 顺序流指令将执行权传递给下一条指令。
2.条件分支指令 当条件为真的时候修改指令指针使其指向分支目标,否则以线性模式执行指令。
递归下降法会反汇编以上两条路径。分支目标指令地址被添加到稍后进行反汇编的地址列表中,推迟其反汇编过程。
3.无条件分支指令 执行权传给一条指令,但这条指令不需要紧跟在无条件分支指令后面。
递归下降法会尝试确定无条件跳转的目标,但如果跳转指令的目标取决于一个运行时的值,这时使用静态分析无法确定跳转目标,将会带来麻烦。
4.函数调用指令 与无条件跳转指令相似,区别在于一旦跳转的函数执行完成,执行权将返还给紧跟在后面的指令。
从被调用函数返回的时候,如果程序运行出现异常,可能导致递归下降算法的失败。函数中的代码有可能会有意篡改函数的返回地址。这样在函数完成的时候,控制权将返回到反汇编器无法返回的地址。
5.返回指令 有时递归下降算法访问了所有的路径,而函数返回指令没有提供接下来将要执行的指令的信息。此时,若程序确实正在运行,则可以从运行时栈顶部获得一个地址,从这个地址开始恢复执行指令。但反汇编器不具备访问栈的能力,因此反汇编过程会突然终止。
递归下降算法具有区分代码与数据的强大能力。IDA是典型的递归下降反汇编器。
栈帧相关 1、栈帧是什么? 栈帧是在程序的运行时栈中分配的内存块,专门用于特定的函数调用。当函数被调用时,可能因为函数需要传参或是局部变量的使用而需要用到内存。编译器通过栈帧使得对函数参数和局部变量进行分配的过程对程序员透明。
2、函数调用的详细步骤 1. 函数调用方将调用函数所需要的任何参数放入调用约定指定的位置。 2. 调用方将控制权转交给被调用的函数。 3. 如有必要,被调用的函数会配置一个栈指针,并保存调用方希望保持不变的任何寄存器值。 4. 被调用的函数为局部变量分配空间。 5. 被调用的函数执行其操作。 6. 被调用的函数完成操作,为局部变量保存的栈空间被全部释放。 7. 将3.中保存的寄存器值恢复至原样。 8. 被调用的函数将控制权还给调用方。根据调用指令,可能清除程序栈中的一个或多个参数。 9. 调用方获得控制权,并对栈进行调整,以将程序栈指针恢复到1.之前的值。 3、调用约定相关 调用约定指定调用方放置函数所需参数的具体位置。调用约定可能要求将参数放置在寄存器、程序栈或寄存器和栈中。同时,在传递参数时,程序栈还需要决定被调用函数完成它的操作后,谁负责删除这些参数。
写在前面 第一次玩CTF属于是,萌新吓傻了。
Web 0x01 第一次冒险 按照网页提示操作,最后结合提示在cookie中得到一个字符串,使用base64解密得到flag
0x02 更简单的计算题 算出来发现提交不了?F12修改输入框的长度限制和提交按钮的disable状态,提交得到flag
0x03 卖菜刀 依照题目,使用工具中国菜刀,在网站根目录可以找到flag文件。
0x04 最好的语言? 这个题有点难,搞了好久。具体就是利用php的反序列化漏洞,即最后会将GET到的interesting参数反序列化。而我们可以利用这一点在interesting变量中加入代码让它执行达到目的。
class中的wakeup()函数会在对象被反序列化的时候执行,destruct()函数会在对象被销毁时执行。观察一下当a=‘1’,b=‘2’,c=‘3’时对象就会在被销毁时输出flag。(注意是字符类型的123)而wakeup()函数会把abc修改成数值类型的123。而众所周知,对象会在程序执行结束后被销毁。所以我们的目的就是:利用反序列化漏洞构造一个Flag类的参数t,并且绕过其反序列化时执行的wakeup()直接执行destruct()。
那么怎么绕过wakeup()呢?
百度搜索可以得知:在某些php版本中,如果表示对象属性个数的值大于真实的属性个数时就会跳过wakeup()的执行。写个代码看看对象序列化之后啥样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Flag { public $a = '1'; protected $b = '2'; private $c = '3'; function __construct() { $this->a = '1'; $this->b = '2'; $this->c = '3'; } } $t = new Flag(); echo serialize($t); 得到结果:
Hello,world!
让我看看blog行不行