- 博客(91)
- 收藏
- 关注
原创 Intel处理器虚拟化技术VT-x86下实现小型虚拟化框架(1)
我一直觉得,学习计算机中的一门新技术,一定要从历史去了解他的全貌。这样有利于我们了解事情的来龙去脉和发展的过程。一上来直接接触新兴事物,很容易陷入不知从何下手的困境。不了解历史发展,就不明白前人的一些操作。因此,这个系列的博客将详细完整记录VT(处理器虚拟化技术)的一些细节包括简单实现。单纯是对这门技术的兴趣。二.虚拟化技术的介绍以及历史虚拟化的诞生对计算机的发展是巨大的。好比如我们经常用的虚拟机VMware Workstation,VirtualBox等出名的虚拟化软件。都是基于这个技术去实现的。
2024-02-24 00:57:52
1091
原创 BUUCTF--mrctf2020_shellcode1
正在我想如何覆盖返回地址的时候,发现题目直接帮你搞好了。取buf的的地址(栈上)然后跳转到buf位置执行代码。主函数中无法反汇编,那么我们直接看汇编代码。其实很简单,通过系统调用执行puts函数,然后执行read函数。这是一题64位的shellocde题,没啥花招入门题。
2024-01-27 12:05:28
674
原创 BUUCTF--xor1
我们看到将用户输入做一个异或操作,然后和一个变量做比较。如果相同则输出Success。这里的知识点就是两次异或会输出原文。因此我们只需要把global再做一次异或就能解出flag。
2024-01-27 02:21:18
555
原创 BUUCTF--reverse21
但是这是假的,下面对这个flag做了一些加密。循环遍历这个flag字符串,当遍历到i或者r将其替换成1。我们将flag改了就行了。最后flag{{hack1ng_fo1_fun}}主函数流程,flag给了。
2024-01-26 23:29:37
412
原创 C++逆向分析--多态的本质
这篇我们延续上次的虚函数分析,来研究下多态的本质。有了上篇虚函数的知识,我们在正向开发学习的时候知道,多态的发生需要存在继承关系,并且子类重写父类方法,父类需要重写的方法是虚函数。这么几点要求。我一开始接触多态是在学习Java的时候。当时的多态搞的我是一脸懵逼。不是很理解是怎么回事。但是在C++中一切的不理解我们都可以直接去逆向分析剖析他的原理。(Java其实也可以太蠢了不会)我相信C++的学懂了,Java学起来理解起来会更加得心应手。这是大佬告诉我的。
2024-01-24 22:36:36
1371
原创 C++逆向分析--虚函数(多态的前置)
真正调用的其实是call eax这句汇编代码,我们看到他的硬编码是FF D0。说明他是个间接调用。将this指针的第一项放入eax,又将eax的第一项复制给edx,此时将this指针给ecx(如果是linux平台g++编译this指针是赋值给rdi的 _x64情况下)最后将edx的第一项赋值给eax。我们先来看一个例子,这次试验用的是windows平台下的VS编译器不同编译器的细节是不一样的原理大差不差。现在我们知道虚函数,如果是通过对象去调用,和普通成员方法没什么区别,但是如果通过指针或者引用去调用。
2024-01-23 19:49:43
2321
原创 C++多态语法剖析
C++的三大特性:封装,继承,多态。这三个特性中,我认为最难理解和最难学习的就是多态。这篇文章总结下多态的一些概念和语法。多态顾名思义就是多种形态的表现手法。也就是让我们的功能能够因人而异的变化。
2024-01-23 17:03:39
335
原创 C++逆向分析--继承的本质
继承是面向对象的三个特性之一。这篇文章我们从底层的角度去理解什么是继承。他的作用是什么。首先继承的出现是更好的避免代码的重复冗余。要理解一件事很重要,C++其实是C的延申。那么C++的出现是为了解决C语言上C++祖师爷认为不友好的事情,也为了简化代码的复杂度,将更多的事情交给编译器去做,而不是程序员自己本身。举个例子,C++在类的创建和释放的过程中,会自动调用构造函数和析构函数,这是上一篇文章提到的C语言没有这个功能。
2024-01-23 00:43:13
1227
原创 C++逆向分析New_Delete
在C语言中,我们是用malloc函数去开辟空间的,释放空间是free函数。而在C++中用的是New关键字,释放空间用的是Delete关键字。我们观察到,做了一些初始化后,最后还是调用C语言的malloc函数。因此验证了我们上述的New其实就是对malloc做的再一次封装。因为在C语言的malloc管理中,64位下的堆其实是有0x10大小的堆头的也就是16字节。单步到这,我们发现edi就是我们的malloc函数的参数。那么堆区是干嘛的呢?一个运行程序是一定有四个区域,分别是:代码区,数据区,栈区,堆区。
2024-01-21 16:34:09
831
原创 逆向分析C++类的本质
面向对象的语言中,类这种语言特性是最基本也是最重要的东西。这篇博客记录下从汇编角度去理解类的本质是什么。创建一个对象的本质又是什么。
2024-01-20 12:43:18
1445
原创 BUUCTF--get_started_3dsctf_20161
题目一进来有很多函数,盲猜是静态编译了。而且在函数堆中发现了个get_flag。信心慢慢的直接写代码返回get_flag地址。2.这题在main函数开始的时候没有压入ebp,因此计算溢出位置不用覆盖ebp。也就是说以前的old_ebp的位置变成了现在的返回地址。1.打远程的时候他将会判断参数是否合规,因此我们要构造get_flag的参数的正确性。这题我本来以为是简单的ret2text.结果还是中了小坑。4.构造垃圾数据不用b‘a',打不通。这题还有一种解法,我是看别的师傅wp才知道的。
2024-01-12 16:48:11
474
原创 BUUCTF--ciscn_2019_s_31
ret_rax_59->ret_400596->pop_rbx->pop_rbp->pop_r12->pop_r13->pop_r14->pop_r15->ret_400580->'a'*56(因为会再次pop_rbx到pop_r15)->pop_rdi->bin/sh参数地址->syscall参数。从上面我们可以看到buf的大小是16,但是write的大小有0x30,肯定是泄露了栈上的其他信息。输入一个字节都能触发段错误,并且还跟了一串不知道啥来的东西,盲猜是栈上的数据泄露。
2024-01-09 13:14:28
386
原创 BUUCTF--铁人三项(第五赛区)_2018_rop1
我这是打本地的代码,远程的话给了libc用libc,没给libc用LibcSearcher,个人感觉不太好用,很多时候找不到。漏洞点主要在vulnerable_function()函数中。1.第一次布局通过题目中的write,puts等函数将库函数地址泄露,并能返回到主程序。2.通过计算算出libc基地址进一步得到system地址。这题是一题标准的rop。3.找到libc中bin/sh的位置。4.第二次布局就是直接布置rop。
2024-01-08 12:52:27
543
原创 BUUCTF--actf_2019_babyheap1
因为题目不能改写got表,但是题目给了system函数地址和bin/sh。因此我们的利用就简单了。直接利用show的调用方式去调用system函数。想办法把索引堆释放并申请回来,在上面布局我们的system(bin/sh)题目提供增删查,没有改。逻辑跟我前面做的一题极为相似,就不过多分析。圈起来的是索引堆的内容。
2024-01-07 01:21:08
397
原创 BUUCTF--pwnable_start1
主要就2个功能,通过系统调用来执行读写功能,将字符串Let's start the CTF:输出,然后接收用户输入。也就是我们能刚好覆盖到返回地址,但是我的shellcode有0x18个字节。而且我们惊奇的发现,这两个值相差0x4,因此我们需要通过write函数将他泄露出来,紧着这我们的返回地址就有了,步骤shellocode就是要返回到布局的栈地址处执行。此时esp要索引到返回地址,将直接执行add esp,14h。存在栈溢出,那么这题的想法就是直接ret2shellcode了。
2024-01-06 17:45:19
379
原创 BUUCTF--gyctf_2020_borrowstack1
迁到什么地方呢,肯定就是这个bank所在的地方了。我们还需要考虑一些细节上的东西,首先我们需要知道libc的基地址,因此我们需要通过puts函数来泄露。后续的操作就很简单,通过泄露的puts函数地址,计算出libc的基地址,当程序再次回到主函数时,直接将栈上的返回地址覆盖成one_gadget拿到权限。接下来的操作基本都是pop,因此rsp是从低地址到高地址跑(每次pop,rsp+8),所以我们顺序布局就可以。old_rbp覆盖成我们的bss段,让rbp指过去,接着返回地址需要再调用一次leave。
2024-01-05 18:31:47
369
原创 BUUCTF--hitcontraining_heapcreator1
此时往chunk3这个用户堆写数据,将会写入free_got表里,这样我们可以将伪造的system的地址写入free_got表,一旦调用free,将会去执行system。2.接着修改chunk0的内容填入bin/sh作为后续system的参数,利用off-by-one并修改下一个索引chunk的大小为0x81(覆盖的是chunk1的索引堆)。这句其实可以这样解读read(0,对应索引堆里的那个堆地址,Size),现在他将变成这样read(0,&free_got,Size)。以此来达到我们的目的。
2024-01-05 01:30:19
430
原创 BUUCTF--ciscn_2019_n_31
这是一题32位的堆题,照常看看保护:没有开启PIE,接着进行黑盒测试:菜单题,扔进IDA看看代码逻辑:4这个功能是提供所谓的进阶版,当时我测试的时候以为是里面有后门还是什么的。结果发现是虚晃一枪,主要就是增加删除和展示。下面看看增加的代码功能:我自己理解的注释写在了上面,do_new函数总结如下:1.不管你是输入数字还是字符串内容,都会首先创建一个大小为0xc的chunk,用于存放两个函数指针。2.如果是数字只会创建一个0xc大小的chunk,值存放在两个函数指针的后面。3.
2024-01-04 17:23:22
390
原创 BUUCTF--ciscn_2019_s_91
一段汇编,因此,这题就是个ret2shellcode。这题没啥好讲的,主要是手写shellcode和调试布局。我们看看payload后布局时啥样的,为什么还要sub esp,40;经过测试发现了段错误,这肯定就是栈溢出了。的位置,那么e0-b8的大小等于0x28也就是10进制的40.接着再跳到。我已经将注释放上,可以看到,当执行到返回地址后,esp将指向。,此时,我们需要让他去到。
2024-01-03 21:56:45
359
原创 关于wiki的Unlink攻击理解--附例题BUUCTF-hitcontraining_bamboobox1
我们知道P的fd和bk都是我们自己构造的。我们假设程序通过溢出或者UAF修改了chunk2的fd和bk,我这里让chunk2的fd指向free的got表地址,bk指向一段内存中我们可读可写可执行的地方(也就是能布置shellcode的)。这样构造的目的是改写下一个chunk的标志位,触发fake_chunk能够进行unlink操作,并且在第二个chunk的数据域构造一个伪chunk。其实就是所谓的断链操作,让P的前一个chunk指向后一个chunk,然后P的后一个chunk指回P的前一个chunk。
2023-12-02 01:08:35
177
原创 BUUCTF-pwn-ciscn_2019_ne_51
我们看到strcpy是将src的内容复制到dest。我们前面看到src允许我们输入128个字节。而dest数组离ebp只有0x48个字节。32为程序没有canary没有PIE,应该是简单的栈溢出。程序上来是输入一个密码验证。随便输入下错误直接退出。那么我们需要构造的东西都有了,接着就是找溢出点。它会把我们的输入放入src这个数组中。主函数大致流程在此。当找不到/bin/sh的时候,可以用sh代替。这里就有一个小技巧了。
2023-11-29 22:56:29
154
原创 BUUCTF刷题之路-pwn-ciscn_2019_n_81
题查保护的时候吓了一跳,保护全开。大致看出var是个数组,当var[13]=17的时候就会得到system。
2023-11-29 21:28:03
161
原创 BUUCTF刷题之路--ciscn_2019_es_21
我们可以看到s数组在ebp-0x28的位置,但是我们最高只能输入0x30。我们看到数组s的起始位置是ecx的值传递的。ebp中的值是一个栈上的值(old_ebp),这个值对于我们栈迁移是有用的。栈迁移的基本原理其实就是栈的空间不够我们利用。下面的是system的参数,因为我们不能直接调用bin/sh字符串,因此我们布局的时候,需要传地址。既然第一次利用空间不够,那么我们何不把这个栈扩大也就是用整一个s数组的空间来构造rop呢。我们泄露的地址的作用是用来诱导esp指向我们的数组s开始的位置。
2023-11-27 12:24:59
91
原创 BUUCTF刷题之路-web-[GXYCTF2019]Ping Ping Ping1
最近才学习的nc反弹shell。想着是否能用nc反弹shell的办法。我在网上看到别的师傅有用base64编码绕过的。有兴趣的可以研究下。这个构造的意思是,我们创建2变量,并采用传参的方式来绕过直接写flag。发现没有回显,证明这个方法是不可用的。文件的输出让我们看到这是过滤规则。看来我们的猜测是正确的。因此我们要想另外的办法绕过flag这个字符。看样子是能够触发远程执行漏洞的。尝试下ping 127.0.0.1,如果有回显说明我们的想法是对的。回显告诉我们,可能flag这几个字符也被过滤了。
2023-11-26 14:21:49
383
原创 pwnable.kr--pwn游戏之fd
因此我们需要在执行的时候传入一个参数,使得它能触发system函数。就是在read这个函数的第一个参数,如果这个文件描述符为0则为标准输入输出,也就是从用户终端读取数据放入buf中。因此我们需要使fd为0。atoi这个函数会把我们传入的数据变成整数,因此我们输入的时候不能传入0x1234。我们还看到有两个文件,一个fd,一个fd.c。通过这题我们能学到ssh远程链接的一些操作以及scp从远程服务器复制文件的操作。大致告诉我们研究的可能是Linux下的文件描述符。那么在我本地的当前目录就会有这两个文件。
2023-11-16 15:28:44
194
原创 fastbins_Double Free调试
在我们程序第一次分配内存的时候,bins中是没有任何可以用的内存。此时我们在fastbins中会有三个chunk,因为libc没有再这里设置过硬的检查,并且这块空间在free的时候没有置为NULL,因此这片空间能够被当成正常的chunk在fastbins中链接。到目前为止,程序执行流程大致是glibc在malloc真正执行前,会先去检查是否有用户自定义的hook函数,如果有,就先行调用,如果没有就按正常的malloc执行。我们首先得知道,在fastbins中,被释放的chunk都是单链表链接起来的。
2023-11-12 18:16:27
112
原创 记录一次校园CTF--wp
那么利用就简单了,我们只需要想办法让金币大于9999999就能造成栈溢出并成功构造一次ret2text,现在关键问题是如何让金币达到9999999呢,在题目游戏中选项3捡垃圾一次是10块钱,不得不说出题人很会玩。这个v6参数就是我们输入想要输入的选项,而Vipfun这一后门函数的参数v8就是我们的金币数,一开始我懵了好久。1.做了一题很简单元神启动,题目中描述1+1等于几,我直接F12查看网页源代码得到出题人的1+1等于10,即可得到flags.四,是一个UAF堆,打本地的时候想岔了没做出来,晚点在复盘。
2023-11-08 21:27:38
264
原创 深入理解Windows句柄
因此我们现在了解,内核中的对象他们位于内核空间,在用户空间不能单纯用地址来引用他们,因此Windows使用句柄来管理和引用对象。当一个进程利用名称来创建或者打开一个对象的时,该句柄指向所创建或者打开的对象,例如,文件操作中,是使用句柄来表示的。每当应用程序打开或者创建一个文件的成功的时候,会返回一个句柄。以后应用程序都使用该句柄来标识该文件。如果有两个应用程序以共享的方式打开同一个文件。那么它们将得到两个句柄,并且这两个句柄的值并不相同,但是却都指向同一个文件,且都通过各自的句柄操作同一个文件。
2023-09-17 21:46:32
134
原创 Windows驱动开发(一)第一个驱动程序
在我们提供的卸载函数中,我们目前也只提供打印一句话的功能。后来我想明白了,在我们想要加载我们的驱动程序的时候,操作系统其实为我们做好了初始化,为我们创建一个驱动对象。首先我们需要了解,在操作系统中,是分两种权限的,一种是内核态,我们也称为0环,一种是用户态,称之为3环。而在我们的电脑中,驱动程序是运行在内核态的,这意味着和操作系统内核是在同一权限的,而普通的应用程序的权限是最低的。我第一次接触这段代码的时候非常陌生和惶恐,竟然没有一句看懂的,但是只要我们耐下性子来研究这个东西,没什么难的。
2023-09-14 00:49:55
487
原创 Windows探究TEB和PEB
在x86模式下FS寄存器是指向当前线程的TEB结构体的。GetProcessHeap是一个API函数,如果函数成功,则返回值是调用进程的堆的句柄。首先会获取TEB的地址,接着找到TEB偏移18h的位置找到ProcessHeap这个成员的值返回。我们只关注两个成员,一个是在偏移0x60处的ProcessEnvironmentBlock成员,一个就是第一个成员NtTib。我们知道在x64下gs指向的是TEB,在TEB偏移60的位置取得ProcessEnvionmentBlock,也就是PEB的地址。
2023-09-03 23:16:51
570
1
原创 判断网站是否开启CDN加速
由多个地段同时发起ping请求。通过CDN的原理我们知道,它是一种提速。如果多地ping延迟都很低多半是开启了CDN。如果有部分延迟较高多半是没有开启CDN。我们看到它跳转到xxxx.com去了,这说明csdn这个网页很可能开启了CDN加速的。我们可以在CMD中ping一下想要测试的网站。比如baidu.com。我们看到转向的还是baidu.com。这种情况下一般是没有做CDN加速。
2023-08-26 11:50:29
527
原创 手写操作系统--进入保护模式的开篇
低32位的16-31比特位与高32位的0-7和24-31共同组成了一个32位的线性地址(这个地址不是真实的物理地址是需要转换的)。低32位的0-15位和高32位的16-19位组成一个20位的界限,记录了这个段的长度。讲完了特权级我们回到段选择子中,看到第三个比特位TI,这是表示访问的是GDT还是LDT,如果为1访问的是GDT,如果为0访问的是LDT。为了兼容8086,A20线默认是关闭的,想要访问超过实模式下1M的内存,我们必须把这个A20线打开,有兴趣的可以查查这A20的历史,我也不是很懂。
2023-07-08 02:54:32
161
原创 手写操作系统--读写硬盘操作
在划分一下就会出现我们的扇区,每个扇区的大小是固定的,一般来说是512个字节。这个端口不同于网络协议中的端口,它是外部设备内部的寄存器,是用来提供一个通道给我们操控这个外部设备的。LBA模式也有2种,一种是用28位比特来表示一个扇区,一个是48位比特来表示一个扇区,分别成为LBA28,LBA48,我们只用LBA28模式就好了。效果图可以参考内核加载器那篇文章,用的就是此套函数将加载器加载到0x1000的内存位置,写硬盘逻辑刚好是相反的,目前还没用到,就没有实现此功能。有了上图的基础,我们就能用。
2023-07-07 16:17:13
1117
原创 手写操作系统--完善内核加载器之内存检测
注意: 在获取列表之后,可能希望对列表进行排序,合并相邻的相同类型范围,将任何重叠的区域更改为最严格的类型,并将任何无法识别的 "类型 "值更改为类型2。实际上,这个功能返回一个未排序的列表,可能包含未使用的条目,并且(在罕见/不稳定的情况下)可能返回重叠的区域。这一篇我们来完善内核加载器的功能,我们知道内存是很重要的区域,我们需要对内存有个大致的描述,哪些可用,那些不可用,内存有多大。代码完善后在内存检测开始前下了断点,效果图是这样的,首先看到内存中内核加载器的内容,在内核加载器下面是清一色的0。
2023-07-06 01:15:55
196
2
原创 手写操作系统--主引导扇区以及内核加载器
这个内核加载器并没有实现很多功能,只是模拟主引导扇区是否成功加载内核加载器。主引导扇区的功能主要是要将内核加载器加载到内存中。因此我们此次实验就模拟一个内核加载器,内核加载器的功能我们将慢慢完善。因为我的第一句代码是mov ax,0x0003,是占用3个字节,因此实际代码将会从0x7c02开始。3,调用硬盘读写功能,将硬盘中的第二个扇区开始的内核加载器写入内存0x1000的位置。屏幕输出了内核加载器的内容,并且确实加载进来了,因此实验成功。4,校检内核加载器的完备性,如果出现错误则跳转到输出错误语句。
2023-07-05 23:55:28
217
原创 汇编语言基础--IO输入输出解决光标问题
in指令 ---------------------------- out指令。我们之前在屏幕上输出数据的时候下标总是在前面,如何解决光标一直在前面的问题呢?想要控制光标位置,我们需要两个指令--输入输出指令来控制硬件。想要控制硬件,我们还需要往对应的端口上写上数据。一个是CRT 地址端口 0x3D4。一个是CRT 数据端口 0x3D5。0x0E 是光标位置的高八位。0x0F是光标位置的低八位。
2023-07-04 22:51:04
404
原创 汇编语言基础--内中断
里面放的其实是4个字节的地址(地址处放着对应的中断处理函数)。我们知道在8086实模式下,是通过cs:ip来找到要执行的指令。cs是2个字节,ip是2个字节,因此是4个字节。其中比较重要的有0号中断,有0x80中断,这就是Linux系统下的系统调用。是在386上才出现的。最后我在讲解下iret,其实他是中断返回指令。也就是中断函数执行完毕,将会把压入的cs,ip,flags弹出栈,接着执行下一条指令。我们看到在000-3FF的位置是放着中断向量表。执行到此处,我们的函数调用栈就完成了。
2023-07-04 19:06:35
174
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人