Skip to content

第一次

约 4494 字大约 15 分钟

2024-7-12

2024年7月7日 周日

汇编语言

看了三章的内容,记录新指令和注意的点

  1. 标志寄存器 PSW

    • abc 和 sbb 用于进行更大位数的运算

    • cmp 相当于减法,不保存值,比较大小

    • 六个条件转移指令,满足条件就 jmp

    • 串传送指令 movsb、movsw + 两个 df 设置指令 cld(正)、std(负)

      rep 次数由 cx 寄存器中的值决定

    • pushf 和 popf 将标志寄存器的值压栈

  2. 内中断

    • 8086 cpu 中断向量表存放位置 0000:03FF,最后 256 字节是空的

    • 中断处理程序编写 & iret 指令

      在栈中弹出 CS:IP 的值以及弹出寄存器的值

      1. 保存用到的寄存器

      2. 处理中断

      3. 恢复用到的寄存器

      4. 用 iret 指令返回

    • 中断特殊情况:ss 和 sp 最好是连续设置

  3. int 指令

    • 指令的格式为:int n n为中断类型码
    • Bios中断例程
    • DOS中断例程

CTF

一直以来都想入CTF的大门,但是今天算真正看 Wiki ,了解了赛制还有方向什么的,最关键的是这个平台上提供了很多学习资源,可以补全自己的技能树

修改博客

之前的博客文件结构有些问题,重新配置了文件路径,并且美化了一下,不过要想真正的做到自己修改还是得学前端,抽空再说吧

2024年7月8日 周一

汇编语言

  • 端口
    1. 在 PC 系统中,CPU 最多可以定位 64KB 个不同的端口,地址范围为 0~65535

    2. 对端口读写不能使用 mov、push、pop 等内存读写指令,只能使用 in 和 out

      注意

      只能使用 ax 或 al 来存放从端口中读入的数据或要发送到端口中的数据。访问 8 位端口时使用 al,访问 16 位端口时用 ax。

    3. CMOS RAM 芯片

      • 包含一个实时钟和128存储单元的 RAM 存储器
      • 靠电池供电,所以 RAM 中的信息不丢失
      • 内部时钟占用 0~0dh 单元来保存时间信息,其余大部分单元用于保存系统配置信息,供系统启动时 BIOS 程序读取
      • CPU 通过该芯片内部 70h(地址端口)、71h(数据端口) 两个端口读写 CMOS RAM
    4. shl 和 shr 指令

      如果移动位数大于 1 时,必须将移动位数放在 cl 中

      • shl 逻辑左移指令
      • shr 逻辑右移指令

修改博客

今天仔细看了下中文排版的规矩,有所启发,于是花费时间把将近四个月前写的东西重新排版了一下,当时对于 markdown 还不熟练。再然后就是修改一些小错误。之前 vitepress 的官方文档我也就看了我需要看的部分,今天也是把能看懂的都看了一遍,安装了别人做好的主题样式,并且使用了一些新的 markdown 拓展语法,跟之前的十分简陋相比,现在已经丰富很多了

2024年7月9日 周二

今天汇编语言终于结束了。今天阅读官方文档添加了友情链接的功能,并且添加了几个链接,我感觉我有点蠢前前后后又搞了一个半小时。然后就是修改文章格式,我现在还在纠结要不要把周记专门分出来一栏,分成一周一周的,从第一周开始一个一个添加 md 文件。

汇编语言

  1. 外中断

    • CPU 通过端口和外部设备进行联系

      • 两种外中断

        • 可屏蔽中断

          IF=1,CPU 在执行完当前指令后响应中断,IF=0,则不响应可屏蔽中断

          • sti:设置 IF=1

          • cli:设置 IF=0

        • 不可屏蔽中断

          [!IMPORTANT] 请注意

          不可屏蔽中断是 CPU 必须响应的外中断。

          对于 8086CPU,不可屏蔽中断的中断类型码固定为 2。

  2. PC 机键盘处理

    • 输入

      扫描码被送入 60h 端口。按键再松开会产生扫描码。断码 = 通码 + 80h。

      • 通码:按键产生

      • 断码:松开产生

      • 引发 9 号中断:中断类型码为 9

      • 执行 9 号中断

        在 BIOS 键盘缓冲区中,一个输入用一个字单元存放,高位字节扫描码,低位字节字符码

        0040:17 单元存储键盘状态字节

    • 直接定址表

      • 开头讲了一种新的定义段的方式,更加简便

        data segment
           a db 1,2,3,4,5,6,7,8
           b dw 0
        data ends
      • 空间换时间

  3. 使用 BIOS 进行键盘输入和磁盘读写

    • int 9 和 int 16h 是相互配合的

    • int 9 中断例程对键盘输入的处理

      • I/O 接口
      • 60h 端口
      • 数据缓冲寄存器
      • 内存-键盘缓冲区
    • int 16h 中断例程读取键盘缓冲区。以下给出 0 号功能:

      1. 检测键盘缓冲区中是否有数据
      2. 没有则继续做第 1 步
      3. 读取缓冲区第 1 个字单元中的键盘输入
      4. 将读取的扫描码送入 ah,ASCII 码送入 al
      5. 将已读取的键盘输入从缓冲区删除
    • 字符串的输入

      1. 字符的输入和删除——栈
      2. 输入回车后,字符串输入结束
      3. 在输入的同时需要显示这个字符串
      4. 程序的处理过程
        • 调用 int 16h 读取键盘输入
        • 如果是字符,进入字符栈,显示字符栈中的所有字符;继续执行调用
        • 如果是退格键,从字符栈中弹出一个显示字符栈中的所有字符;继续执行调用
        • 如果是 Enter 键,向字符栈中压入0,返回
    • 应用 int 13h 中断例程对磁盘进行读写

      入口参数比较多,我就打算把这块作以了解,以后用到

博客修改

[!TIP] 痛定思痛

最后仔细想了想为了更好的管理以及更好地查阅文档,上面的考虑是完全有必要的,于是我又花了一个半小时新增了几个文件结构,重新写了导航栏和侧边栏,使得条理更加清晰

2024年7月10日 周三

《安全之路:避开路由器陷阱》

谷歌机翻 + 英语原文混着看

概念

这里列出的概念都是我不太熟悉的

  1. 僵尸网络(Botnet):由大量被黑客控制的被感染计算机组成的分布式网络系统。这些被感染的计算机被称为"僵尸"(Bot)。
  2. 硬编码凭证(hardcoded credentials):将用户名、密码等敏感信息直接写入程序代码或配置文件中,而不是通过动态方式从安全存储中获取。主要就是硬编码这个词的理解
  3. UPnP(Universal Plug and Play):是一种网络协议,允许设备在局域网内自动发现和相互连接,无需人工干预。UPnP会主动公开设备信息,本身也可能存在安全漏洞
  4. RCE(Remote Code Execution):是一种严重的安全漏洞,它允许攻击者在远程系统上执行任意代码。RCE漏洞通常是由于软件开发中的安全编码问题导致的。
  5. Telnet:基于文本的远程登录协议,它允许用户通过网络连接远程计算机并进行交互式操作。不加密通信。
  6. NVRAM:非易失性随机访问存储器,指断电后仍能保持数据的一种RAM
  7. HNAP(Home Network Administration Protocol):用于管理家庭网络设备的协议。它可以让管理员或用户通过Web浏览器或专用应用程序来轻松配置和管理家庭网络设备。过时的专有协议
  8. SOAP (Simple Object Access Protocol) :一种基于 XML 的消息传输协议,用于在分布式环境中进行信息交换。它主要用于实现基于 Web 服务的应用程序之间的通信。
  9. XML(Extensible Markup Language):一种标记语言,用于描述数据的结构。它被设计用于传输和存储数据,并且易于被人类和机器读取和理解。
  10. Lua:一种轻量级、可嵌入的脚本语言。适合嵌入式设备的脚本语言,在自定义网络设备和物联网设备中有着广泛的应用前景。

指令 & 函数

  1. iptables 命令:Linux操作系统中一个强大的网络防火墙和数据包过滤工具。它允许管理员控制进出系统的网络流量,并根据预定义的规则对数据包进行过滤和转发处理。

  2. system 函数:

    int main(int argc, char** argv)
    {
      setuid(geteuid());//将程序的有效用户ID设置为当前进程的有效用户ID
      system(argv[1]);//接收参数为字符串指针。如果发生错误,则返回值为 -1,否则返回命令的状态。
      return 0;
    }
  3. snprintf 函数:

    int snprintf ( char * str, size_t size, const char * format, ... );
    //str:目标字符串,用于存储格式化后的字符串的字符数组的指针。
    //size:字符数组的大小。
    //format:格式化字符串。
    //...:可变参数,可变数量的参数根据 format 中的格式化指令进行格式化
    //返回值是输出到 str 缓冲区中的字符数,不包括字符串结尾的空字符 \0
  4. execve 函数: exec系列的系统调用是把当前程序替换成要执行的程序,而fork用来产生一个和当前进程一样的进程(虽然通常执行不同的代码流)。通常运行另一个程序,而同时保留原程序运行的方法是,fork+exec。

    int execve(const char *filename, char *const argv[ ], char *const envp[ ]);
    //filename:文件路径程+序名
    //argv[ ]:利用数组指针来传递执行文件,并且需要以空指针(NULL)结束
    //envp[ ]:传递给执行文件的新环境变量数组

    [!IMPORTANT]注意

    这里的第二个参数 argv 中,argv[0] 通常是可执行程序的路径或文件名,从 argv[1] 开始是传递给可执行程序的参数。参数数组最后一个元素必须是 NULL(或 0 ),用于标记参数数组的结尾。

    execve("/bin/iptables", { "/bin/iptables", "-A", "INPUT", "-s", ip_addr_to_block, "-j", "DROP", 0 }, 0);

    形如这样的调用中没有空格分隔命令在 Linux 也是可以执行的

  5. strncmp 函数:用于比较两个字符串的前 n 个字符是否相等

    int strncmp(const char *str1, const char *str2, size_t n)
    //str1:要进行比较的第一个字符串。
    //str2:要进行比较的第二个字符串
    //n:要比较的最大字符数
  6. argc 以及 argv:使用 argc 和 argv 是 C 语言中处理命令行参数的标准方式,它为程序提供了一种简单而强大的方式来获取用户输入

  7. sprintf 函数:发送格式化输出到 str 所指向的字符串

    int sprintf(char *str, const char *format, ...)
    sprintf(cmd, "ping %s", ip_addr);//这个直接上实例
    //将字符串 ping %s 格式化,将 ip_addr 变量的值替换到格式化字符串中
    //最后用字符串 cmd 来存储格式化的字符串 ping %s
  8. os.system 函数:

    [!warning]这是 Python 中的函数

    类似于上面 C 语言中的 system 函数

  9. eval:一个把字符串当作表达式执行而返回一个结果的函数

漏洞类别

身份验证绕过

身份验证绕过漏洞对攻击者来说很有价值,因为它打开了的攻击面。

  1. CVE-2021-32030:报告了华硕 GT-AC2900 路由器上的身份验证绕过问题

    • 问题

      当你要登录管理员面板时,客户端发出 asus_token 给后端服务器,后端服务器收到请求后,会从路由器的 NVRAM 读取的 ifttt_token 进行比较验证管理员身份,但是如果 ifttt_token 为空,asus_token 也为空,就会直接验证成功。

    • 解决

      这是由程序员没有考虑边界情况引起的,应该有确保 ifttt_token 函数不为空的函数,先确保 ifttt_token 不为空再与客户端提供的 asus-token 进行比较验证。为了更安全也可以增加 asus_token 是否为空的判断。。

  2. CVE-2020-8864:报告了 D-Link DIR-882、DIR-878 和 DIR-867 路由器上的身份验证绕过漏洞

    • 问题

      下面的函数用来比较验证,如果攻击者输入为空,那么 strlen 函数返回 0,这下比较前 0 个字符,这根本不用比 strncmp 函数自动返回 0 身份验证直接就成功了。

      strncmp(db_password, attacker_provided_password, strlen(attacker_provided_password));
    • 解决

      将 db_password 作为strlen 的参数传递给 strncmp 函数。

  3. CVE-2020-8863:D-Link 多路由器 HNAP PrivateLogin 身份验证算法错误实现身份验证绕过漏洞。

    • 问题

      通过 HNAP 进行身份验证时,服务器通常会根据用户的密码生成 PrivateKey。但是,当攻击者在登录请求中提供额外的 PrivateLogin 元素时,会发生一些不同的情况。服务器会使用 Username 元素的值来生成 PrivateKey,而不是用户密码。所以密码随意填写都能过。

命令注入
  1. 根本原因

    利用命令语法和设计缺陷进行攻击。

  2. 使用 shell 理由:省事。

  3. 预防

    并非所有操作都需要通过 shell 命令执行,因此请避免这样做,除非必要。

    • 避免 system 命令

      这一类函数都别用:system、popen、os.system、subprocess.Popen 等。

    • 使用参数列表运行可执行文件

      使用这类函数:execve、subprocess.Popen、subprocess.run、subprocess.call等

      [!important]注意

      fork + exec

    • Lua

      为了防止开发人员制作容易受到命令注入攻击的命令字符串,开发团队可以创建一个类似 execve 的函数,但是:

      [!important]注意

      1. 用单引号将每个参数括起来:防止命令替换

      2. 转义每个参数中的单引号:防止不会关闭参数前面的单引号

    • 在 shell 脚本中避免使用 eval

      即使外部调用过程安全,最终执行的脚本代码仍可能被利用,造成系统被攻击或信息泄露等安全问题

shell 脚本

没专门学过,原来用 Linux 都是现学现卖,不过上面那篇文章有点看不懂了,故而选择上菜鸟教程好好看一看 shell 的内容😂😂😂

2024年7月12日 周五

昨天有点小事,就只学了两个小时,由于时间太短就不写了。

《安全之路:避开路由器陷阱》

概念

  1. ASLR(Address Space Layout Randomization):操作系统安全技术,用于增强系统的抗攻击能力
  2. PIE(Position Independent Executable):是一种代码编译技术,通常与 ASLR(Address Space Layout Randomization)结合使用,以提高系统的安全性。
  3. RELRO(Relocation Read-Only):是一种针对 ELF 可执行文件和动态链接库的安全强化技术。它的主要目的是减少程序中可被攻击者利用的攻击面。
  4. Stack Canary:用于检测和防范栈溢出攻击的安全技术。
  5. NX(No-eXecute):内存保护技术,用于防止缓冲区溢出攻击。
  6. ASLR (Address Space Layout Randomization) :一种计算机安全技术,用于在程序加载时随机化进程地址空间布局,以降低利用内存中的漏洞进行攻击的风险。

函数

  1. strcat 函数:

    char *strcat(char *dest, const char *src)
    //dest:指向目标数组,该数组包含了一个 C 字符串,且足够容纳追加后的字符串。
    //src:指向要追加的字符串,该字符串不会覆盖目标字符串。
  2. memcpy 函数:

    void *memcpy(void *str1, const void *str2, size_t n)
    //str1:指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
    //str2:指向要复制的数据源,类型强制转换为 void* 指针。
    //n:要被复制的字节数。
  3. memset 函数:

    void *memset(void *str, int c, size_t n)
    //str:指向要填充的内存区域的指针。
    //c:要设置的值,通常是一个无符号字符。
    //n:要被设置为该值的字节数。

漏洞类别续

缓冲区溢出
  1. 原因

    用 C 语言编程常见问题,栈溢出覆盖。在路由器中,使用复制内存内容的函数时通常会观察到此错误。

  2. 预防

    • 使用有界函数进行复制

      [!important]注意

      在使用像 strncpy 或 memcpy 这样的函数时,应引入用户独立输入的 length 参数来决定要复制的长度,而且要基于目标缓冲区分配的大小来决定 length 的值。

    • 将缓冲区大小作为函数参数传递

      当存在多重函数调用的时候,跟踪和管理缓冲区大小就变得很复杂(特别是当它们被动态分配时)。

      [!important]注意

      使用 strncpy 函数时,需要特别注意目标缓冲区的大小,并确保在复制操作后手动添加空字符来确保字符串的正确终止,同时避免越界访问。

      使用 strncat 函数追加时,确保目标缓冲区有足够的空间来容纳要追加的字符串及其终止符。

    • 避免使用库函数,创建并使用自己常见的库函数

格式字符串错误

printf 函数,现代 C 编译器不是使用

printf("%s", username);

形式,都是会报错的,所以无需担心

shell 脚本

今天早上有课,下午有个小考试,其实今天的东西还没学完,目前就是这些先提交上去

公告板

持续建设中