首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

PWN栈溢出漏洞。

国内的CTF比赛中,PWN题最常见考点就是缓冲区溢出漏洞,而缓冲区溢出代表就是栈溢出漏洞。 0x01 基础知识 栈是一种先进后出的数据结构,从高地址向低地址增长的内存结构。...一次函数调用中,函数调用栈中将被依次压入:函数实参、返回地址、EBP。如果函数有局部变量,接下来就在栈中开辟相应的空间以构造变量。 ?...0x02漏洞原理 栈溢出漏洞是由于使用了不安全的函数,如C中的 read(fd, buf, nbytes)、gets(s)等,通过构造特定的数据使得栈溢出,从而导致程序的执行流程被控制。...当程序代码如下int main(int argc, char **argv) { char s[12]; gets(s); return 0; } 栈空间如下: ?...main(int argc, char **argv) { vulnerable(); return 0; } gets() 是一个危险函数,因为它不检查输入字符串的长度,而是以回车来判断是否输入结束

98221

PWN栈溢出漏洞。

国内的CTF比赛中,PWN题最常见考点就是缓冲区溢出漏洞,而缓冲区溢出代表就是栈溢出漏洞。 0x01 基础知识 栈是一种先进后出的数据结构,从高地址向低地址增长的内存结构。...一次函数调用中,函数调用栈中将被依次压入:函数实参、返回地址、EBP。如果函数有局部变量,接下来就在栈中开辟相应的空间以构造变量。 ?...0x02漏洞原理 栈溢出漏洞是由于使用了不安全的函数,如C中的 read(fd, buf, nbytes)、gets(s)等,通过构造特定的数据使得栈溢出,从而导致程序的执行流程被控制。...当程序代码如下int main(int argc, char **argv) { char s[12]; gets(s); return 0; } 栈空间如下: ?...main(int argc, char **argv) { vulnerable(); return 0; } gets() 是一个危险函数,因为它不检查输入字符串的长度,而是以回车来判断是否输入结束

1K51
您找到你想要的搜索结果了吗?
是的
没有找到

从根上理解,一个 Redis 字符串为什么要设计的这么复杂!

需要注意的是,sds 依然遵循了 C 语言字符串以 \0 结尾的惯例,这么做是为了方便复用 C 语言字符串原生的一些API,换言之就是 C 语言中会以碰到的第一个 \0 字符当做当前字符串对象的结尾,...sds 空间分配策略 C 语言中因为字符串内部没有记录长度,所以如果扩充字符串的时候非常容易造成「缓冲区溢出(buffer overflow)」。...C 语言避免缓存区溢出和内存泄露完全依赖于人为,很难把控,但是使用 sds 就不会出现这两个问题,因为当我们操作 sds,其内部会自动执行「空间分配策略」,从而避免了上述两种情况的出现。...同样的,如果是操作 int 编码的字符串之后,「导致 long 类型无法存储int 类型不再是整数或者长度超过 2 的 63 次方减 1 )」,也会将 int 编码修改为 raw 编码。...PS:「需要注意的是,编码一旦升级(int-->embstr-->raw),即使后期再把字符串改为符合原编码能存储的格式,编码也不会回退。」

52220

C语言书籍——A陷阱之处

双引号引起来的字符串中,注释符号/*属于字符串的一部分;注释中出现的双引号“”又属于注释的一部分。...因为p和q所指向的是同一块内存,所以p指向的内存中存储的当然也是字符串’xyz'。 五、空指针并非空字符串 C语言中将一个整数转换为一个指针,最后得到的结果都取决于具体的C编译器实现。...2、一个操作数是有符号整数,另一个是无符号整数,那么有符号整数会被转换为无符号整数,“溢出”也不可能发生。 3、当两个操作数都是有符号整数,“溢出”就有可能发生,而且“溢出”的结果是术定义的。...当一个运算的结果发生“溢出,作出任何假设都是不安全的。...严格说来,我们前面的最简单的C程序应该像下面这样编写代码: int main() { //语句 return 0; }

8610

扒掉“缓冲区溢出”的底裤

文章原题《缓冲区溢出》 ? 1 引言 “缓冲区溢出”对现代操作系统与编译器来讲已经不是什么大问题,但是作为一个合格的 C/C++ 程序员,还是完全有必要了解它的整个细节。...而缓冲区溢出则是指当计算机向缓冲区内填充数据位数超过了缓冲区本身的容量,溢出的数据覆盖合法数据上。...常量区(文字常量区):数据段,存放常量字符串,程序结束后有系统释放。...int)value1; } 算术溢出,该程序即使接受用户输入的时候对a、b的赋值做安全性检查,a+b 依旧可能溢出: #include int main() { int a...; int b; int c=a*b; return 0; } 数组索引不在合法范围内 enum {TABLESIZE = 100}; int *table = NULL; int insert_in_table

1.1K20

Redis原理

C 字符串和 SDS 之间的区别, 并说明 SDS 比 C 字符串适用于 Redis 的原因。...除了获取字符串长度的复杂度高之外, C 字符串不记录自身长度带来的另一个问题是容易造成缓冲区溢出(buffer overflow)。...C 字符串不记录自身的长度, 所以 strcat 假定用户执行这个函数, 已经为 dest 分配了足够多的内存, 可以容纳 src 字符串中的所有内容, 而一旦这个假定不成立时, 就会产生缓冲区溢出...举个例子, 如果我们持有一个值为 "Redis" 的 C 字符串 s , 那么为了将 s 的值改为 "Redis Cluster" , 执行: strcat(s, " Cluster"); 之前, 我们需要先使用内存重分配操作...embstr 编码的字符串对象执行命令, 产生的效果和 raw 编码的字符串对象执行命令产生的效果是相同的, 但使用 embstr 编码的字符串对象来保存短字符串值有以下好处: embstr 编码将创建字符串对象所需的内存分配次数从

41320

LeetCode 刷题记录(二)

: 321 Input: -123 Output: -321 Input: 120 Output: 21 如果执行环境只能存储得下 32 位有符号整数,那么其数值范围为 (最高位为符号位),翻转如果溢出请返回...) -> int: rev = 0 if x <= (-2**31): # 判断负数的例外情况(最小负数不能取绝对值) return 0...:前面一个字符可有可无 \d:一个数字(\D 表示非数字字符) +:前面一个字符的一个或多个 * 是 python 的解包操作,本例中将含有匹配后的字符串的列表转换为字符串,注意 int(*[]) =...回溯法通常用最简单的递归结构来实现,反复重复上述的步骤后可能出现两种情况: 找到了可能存在的正确答案 尝试了所有可能的分步方法后宣告该问题没有答案 对于本题,回溯法的流程如下: 如果只有 '.'...for (int c = 1; c < n; c++) { j = c - 1; if (s.charAt(i) == p.charAt(

44720

本地缓冲区溢出分析

溢出是缓冲区溢出中最为常见的一种攻击手法,其原理是,程序在运行时栈地址是由操作系统来负责维护的,我们调用函数,程序会将当前函数的下一条指令的地址压入栈中,而函数执行完毕后,则会通过ret指令从栈地址中弹出压入的返回地址...main(int argc,char *argv[]) { geting(argv[1]); return 0; } 直接保存为overflow.c然后执行 cl /Zi /GS- overflow.c...重新运行程序,然后输入一个超长字符串,这里我就输入一串 lysharkAAAAAAAAABBBB 上方截图可知,程序的返回地址已被BBBB等字母霸占了,当程序执行ret指令返回,程序会在堆栈中取出42424242...我们手动将堆栈中的 424242 替换为 0x76c2fb75 注意该地址应该反写,如下所示: 当程序运行时,首先会ret返回,而程序返回会在堆栈中将 0x76c2fb75 这个内存地址回写到 EIP...\Users\> cl /c /GS- /EHsc ntdll.cpp C:\Users\> link /dll ntdll.obj 接着我们通过缓冲区溢出漏洞,实现调用 ntCheck函数是,让其弹出

68620

深入浅出Redis-redis底层数据结构(上)

C 语言使用这种简单的字符串表示方式,并不能满足Redis 对字符串安全性、效率以及功能方面的要求 2.3.1 获取字符串长度(SDS O(1)/C 字符串 O(n))      传统的C 字符串 使用长度为...2.3.2 杜绝缓冲区溢出     C 字符串 不记录字符串长度,除了获取的时候复杂度高以外,还容易导致缓冲区溢出。      ...2.3.3 减少修改字符串带来的内存重分配次数   C语言字符串进行字符串的扩充和收缩的时候,都会面临着内存空间的重新分配问题。    1....字符串拼接会产生字符串的内存空间的扩充,拼接的过程中,原来的字符串的大小很可能小于拼接后的字符串的大小,那么这样的话,就会导致一旦忘记申请分配空间,就会导致内存的溢出。    2....2.3.7 总结 C 字符串 SDS 获取字符串长度的复杂度为O(N) 获取字符串长度的复杂度为O(1) API 是不安全的,可能会造成缓冲区溢出 API 是安全的,不会造成缓冲区溢出 修改字符串长度N

1.4K80

整形溢出概述

漏洞实例:合约Internet Node Token (INT)  合约地址:https://cn.etherscan.com/address/0x0b76544f6c413a555f309bf76260d1e02377c02a...0x6aac8cb9861e42bf8259f5abdc6ae3ae89909e11#code 漏洞位置:L45 image.png 漏洞危害:管理员执行了一个正常向某个地址进行发币的操作,实际已经暗中将自身账户的余额修改为了一个极大的数...可想而知,如果合约的owner不校验溢出问题的情况下向某一地址铸币,那么该地址如果发生溢出,那么代币数量将会发生变化,时而出现减少的情况(因为发生溢出)。...a, int256 b) internal pure returns (int256) { return a + b; } } 文末总结 整型溢出问题发生的根源还是在于合约的开发者开发合约未考虑到...“整型溢出”问题,作为审计人员的我们在看到合约也要保持清醒,对于存在疑惑的地方应该采用“调试、验证”的方法去排除疑虑,而且在审计的过程中也要十分的认真、细心才可以,不要放过任何一个有可能存在问题的地方

1.3K00

C# .NET面试系列一:基础语法

255; // 修改为 byte 范围内的值请注意,处理字符,需要确保其值 byte 类型的范围内。...C#中,当你对byte类型的变量进行算术运算,而结果超过了byte类型能够表示的最大值(即255),就会发生溢出溢出的行为取决于它发生的上下文。...C#中,默认情况下,对于溢出的处理方式是相同类型的变量上进行赋值,会将溢出的部分进行包装(wrap around)。这意味着如果超过了byte的最大值,它会回到最小值。...即使进行简单的操作,也要确保变量的类型是一致的,否则会引发类型错误。C#、Java、C++ 等是强类型语言的代表。...总体来说,强类型语言大型项目和对类型安全性要求较高的场景中通常受青睐。

17510

整形溢出概述

漏洞实例:合约Internet Node Token (INT) 合约地址: https://cn.etherscan.com/address/0x0b76544f6c413a555f309bf76260d1e02377c02a...漏洞危害:用户提币之后,无法得到对应数额的ETH; 漏洞原理:sellPrice被修改为精心构造的大数后,可导致amount sellPrice的结果大于整数变量(uint256)最大值,发生整数溢出...漏洞危害:管理员执行了一个正常向某个地址进行发币的操作,实际已经暗中将自身账户的余额修改为了一个极大的数; 漏洞原理:distributeBTR()函数的本意是管理员给指定地址发放一定数额的token...从上面的结果我们可以发现确实发生了溢出!可想而知,如果合约的owner不校验溢出问题的情况下向某一地址铸币,那么该地址如果发生溢出,那么代币数量将会发生变化,时而出现减少的情况(因为发生溢出)。.../Link_Platform__LNK_/mint%20integer%20overflow.md 文末总结 整型溢出问题发生的根源还是在于合约的开发者开发合约未考虑到“整型溢出”问题,作为审计人员的我们在看到合约也要保持清醒

1.2K20

缓冲区溢出漏洞

调用函数它的汇编代码大致上是这样的 ;调用函数 push buf call msg_display ;函数调用完成后平衡堆栈 add esp, 4 ;函数中的汇编代码 ;保留原始的ebp,release...0的随机字符 + jmp esp指令的地址+shellcode 这样最后执行完函数中的操作返回时会将eip的值改成jmp esp的指令所在的地址,CPU就会执行esp所指向的位置的指令,而这个位置正是攻击者通过溢出手段所提供的攻击代码...,主函数中我们利用了这个漏洞,传入了一个超长的字符串,其中shellcode是一个开启command part对应的机器码,主函数中我们首先定义了一个非法的字符串,然后将字符串的弟16个字符赋值为shellcode...通过缓冲区溢出的方式将栈中保存的eip的值修改为0x0c0c0c0c,然后堆中分配200M的内存,将这200M分为200分,每份1M,都填充为、\0x90\0x90\0x90…….\0x90 + shellcode...0x0c0c0c0c,那么很可能会跳转到这段代码上面,测试的时候可以使用dll注入的方式,制造一个缓冲区溢出漏洞,然后触发它就可以实现这个。

2K20

9.回文数

例:121是 -121不是 2、解题思路 思路一: 最初想到是使用java语言,直接将int型变量转为字符串,然后将字符串倒序,比较两个字符串是否相同,若相同则输出true,反之为false...} } } 思路二(C语言): 1、由回文数的特性可知,负数均不是回文数,故判断若x为负数直接输出false; 2、对于正数则用一个变量记录x的逆序数 3、比较两个数是否相等,相等则输出...true;反之false 4、默认0为回文数 bool isPalindrome(int x){ long sum=0; //将x的逆序数定义为long类型,防止运行过程中因溢出而导致的错误...,由于将sum变量定义为int类型,导致LeetCode运行时出现溢出错误,无法通过。...后尝试将sum变量改为long类型,成功通过编译。 但在解题过程中,未考虑时间复杂度和空间复杂度。

12210

Redis源码分析(一)——Redis数据结构-字符串SDS

SDS简介 Redis中使用的字符串均为『简单动态字符串』(Simple Dynamic String),简称SDS。 SDS是C字符串的基础上进行了一些包装,使得它符合Redis的使用场景。...Redis中,C字符串只用在一些无需修改的地方,如日志打印;其他需要使用字符串的地方基本上使用的都是SDS。 2....数据结构 struct sdshdr{ int len; int free; char buf[]; }; len:buf数组中字符串的实际使用量。 free:buf数组中空闲量。...3.1 获取字符串长度效率高 C语言字符串是不记录字符串长度的,所以每次获取字符串长度,都要对字符数组进行一次遍历,那么时间复杂度就为O(n)。...而SDS中采用len记录当前字符串的长度,所以统计字符串长度的时间复杂度为O(1),因此效率高于C字符串。 3.2 避免了缓冲区溢出 3.2.1 什么是『缓冲区溢出』?

78640

Redis 存储原理(1)

key是字符串,但是Redis没有直接使用C的字符数组,而是存储自定义的SDS中。 value既不是直接作为字符串存储,也不是直接存储SDS中,而是存储redisObject中。...为什么Redis要用SDS实现字符串C语言本身没有字符串类型(只能用字符数组char[]实现)。 1、使用字符数组必须先给目标变量分配足够的空间,否则可能会溢出。...3、C字符串长度的变更会对字符数组做内存重分配。...c字符串 SDS embstr 只读 获取字符串长度的复杂度为O(N) 获取字符串长度的复杂度为O(1) API是不安全的,可能会造成缓冲区溢出 API是安全的,不会早晨个缓冲区溢出 修改字符串长度N次必然需要执行...int和embstr什么时候转化为raw? 当int数据不再是整数,或大小超过了long的范围(2^631=9223372036854775807),自动转化为embstr。

1.2K20

C++入门指南及实战 第三步 基本变量

C++编程中,内置了一些基本数据类型用来存储一些不同类型的值。有字符类型 char 用以存储字符,如a、b、c、d、-、=、1、2、4、3、>、?...以上介绍并不完全的介绍完C++中的类型,还有许多并未列出,只列出了一部分的常用类型。 C++中当内置的类型不能满足开发需求,也可以自定义,自己创建一个类型。...如有一个变量 a,c++中整形是用int表示,那么使用整形对变量a进行描述则可以写为:int a。 整形 以上的简介中,已知整形是使用int表示,整形中还分为短整形、长整形以及整形。...} 结果如下: 此时应该存储的值为最大存储值,应该装满了,不能网上装了,这时我们把65535改为65536: short int a=65536; 这时数据将会溢出结果如下: 现在我们把存储数据再一次进行更改...std; int main(){ char a='c'; cout<<a; return 0; } 结果如下: 在此注意,单个的符号数字才叫字符,组合成的为字符串

54110
领券