程序设计

程序设计

引入

我们说,攻防都是相对的,一个好的攻击者它是知道怎么进攻的,那它也懂怎么防;一个好的防守者它是懂防守的,它可以去进攻。找程序漏洞,可以,但还是要多探究一个为什么,当一个工具猴子又什么乐趣,“虽说码头薯条”,但要去当一个聪明的猴子才更有竞争力;知识,还是要知其然并知其所以然,为了更好地理解,还是先回顾程序设计。

0x01 基本概念

什么是程序设计;

程序是用某种语言写出的一些语句。

人有人的语言,机器有机器的语言,机器语言,0101对吧,但是这样设计程序很复杂;汇编程序是一种机器语言翻译程序,汇编语言如mov,add,但是还是比较难;再来一个 编译程序去翻译 汇编语言,这种 高级语言比起 汇编语言更直观,比如C、C++

中文都是有语法的,那C++这种语言自然有其语法。

还有一种是伪代码,就是只体现出其逻辑,但是不能直接运行。

所以总结起来就是,机器->汇编->高级语言(C、C++);这其实是一种简化,由难->易,但本质上还是遵循底层语言的,计算机执行的还是机器语言。

控制结构

好,我们已经知道这种语言了。我们写作的时候,是不是将就倒叙、插叙手法,剪视频还将就蒙太奇呢,这种就是 顺序,我们不可能一直从头到尾讲,所以为了控制语句的执行顺序,就有了控制结构,if..else;while/for之类的

变量、运算符、函数,这些基本概念也都知道了吧

全局思想:主要是讲到反汇编的汇编语言部分,x86的寄存器啊,指令啊这种汇编知识;总之就是,C语言代码在发挥作用之前都是先编译成机器指令

之后讲到了:

字符串

有符号、无符号类型

指针;就传递内存块的开始地址

强制类型转换;临时改变一个变量的数据类型的方法;它强大的地方还是在于和指针搭配的时候,每个指针都要求有一个数据类型的

变量作用域;局部呢,还是全局

存储器分段

每一段都是一块专用存储区,这五个段就是(text,data,bss,heap,stack),就是代码段、数据段、全局变量/静态变量、堆,栈,程序运行的时候,哪部分会存入相应的段呢,这里就不记了

程序构建

文件访问;2 ways:文件描述符和文件流

数据结构;线性表,链表。。。

结构:一般指结构体,类啊,封装了很多变量

函数指针

伪随机数

总结:以上这些只是为了说明那么多构成,是为了确保程序是遵照某个规则的。但是呢,有些东西可以打破规则,就是漏洞。

0x02 漏洞篇

一般与内存破坏有关,控制目标程序的执行流程,欺骗程序去执行一段植入内存的恶意代码。我记得上学时工程逆向这门课有过演示

一、缓冲区溢出

典型的例子就是,给某个变量分配的内存不够存完输入的数据,那当把10字节的数据输入,存给8字节的缓冲区,那不崩溃啦,而且还会造成数据覆盖。

一般就是比如有一个exe文件,你打开,它要密码,你又不知道,那你逆向工具,改一下内容,使得溢出后,无需正确密码也可访问。

例子1-溢出原理

image-20231103112310738

这个直接运行的话,只能输出

1
2
3
4
Before:
buffer_2 is at 000000000062FE00 and contains 'two'
buffer_1 is at 000000000062FE10 and contains 'one'
value is at 000000000062FE1C and 5 (0x00000005)

先输出成exe文件

咦,为什么这两个地址之间差的是16字节,而不是8字节;编译器的内存对齐吗?

那,它实际上数组应该是8字节大小,但是,我输入了10字节的值,没有把buffer_1内容覆盖掉

算了,这样搞的话,输入17字节的数据试试

argv[]是存储命令行参数的

看,当命令行参数为17字节的时候,将这个值赋值给buffer_2,造成溢出,导致之后的buffer_1内容被占了

呐,只要足够大,也把value的内容占据了

image-20231103115046826

例子2-绕过密码

原理

数组越界后就有可能破坏栈中相邻变量的值

image-20231103122355283

看主函数,它调用了密码检查函数,判断是否通过;两个密码二选一,即可通过

生成exe文件后,尝试一下

然后,看看溢出会怎么样,输入30字节绕过了

调试下

1
2
PS E:\VS project\py\Debug> gdb -q ./auth_overflow
Reading symbols from ./auth_overflow...done.

list 1就可以了,一次十行,要看后续代码,回车就可以

设置断点,第9行和第16行,并输入参数为那30字节的值

在执行到断点9的时候,password都还是未知数呢,而auth_flag也是空值,显示password_buffer之后的28个字节内容,auth_flag的值见红框处

明显可以看到password_buffer的位置在auth_flag之前

gdb调试处,gdb x命令

image-20231103123955695

x/x x表示显示十六进制数据

x/s s表示显示字符

x/16xw 是显示16个地址的的数据,16进制显示,w代表数据单位为单词

接下来,执行到第二个断点处,auth_flag的值是0x39,十六进制转化为十进制的值是3*16+9=57,ascii码值对应的字符为9

数字09对应的ASCII码(十进制)为“48”57

大写字母AZ对应的ASCII码(十进制)为“65”“90”

小写字母az对应的百ASCII码(十进制)为”97”“122”

password_buffer的值,溢出到了auth_flag中,看下图,90

image-20231103124624879

x/4cb 4个地址的数据, c是字符,b代表字节byte

x/dw d十进制,w是单词,0x3039的十进制就是12345

溢出后,check_这个函数的返回值就是12345,而不是0,所以判断通过;

auth_flag是执行控制点,它的内容被覆盖,导致绕过

image-20231103130348549

然后,看一下,如果把password_buffer和auth_flag的声明交换位置呢,看9行和10行处

这样的话,内存中,auth_flag的位置在password_buffer之前,那么password_buffer溢出,怎样也影响不了auth_flag;

!!!!!!!!但是,这里有问题,更改语句声明位置,内存位置不变

按理说,局部变量,存储在栈中,那么J和K,J先声明,那么J的地址高;否则K的地址高

还是和编译器有关系咯?

按理说,如果内存位置上,auth_flag的位置在password_buffer之前,那么无论如何也不会溢出绕过的

bash篇

bash shell和Perl

二、其它段溢出

基于堆的溢出

函数指针的溢出

三、格式化字符串

0x03 网络

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2023-2025 是羽泪云诶
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信