python 无效的字符串或缓冲区长度 (0)_从shellcode学习到缓冲区溢出实战

本文为看雪论坛优秀文章

看雪论坛作者ID:techliu

目录

一、shellcode1.1 简介1.2 缓冲区溢出

  • 溢出示例
  • 规划缓冲区

1.3 字符串转16进制脚本1.4 几种技巧

  • 跳板技术
  • 抬高栈顶保护shellcode

二、windbg配置mona2.1 参考2.2 配置符号路径2.3 安装python2.4 配置windbg2.5 常用mona命令

  • 显示载入的模块
  • 查找机器码

2.6 在Immunity Debugger中使用mona三、Freefloat FTP Server 1.0 溢出漏洞分析3.1 简介3.2 参考3.3 分析工具3.4 Start

  • fuzzing

找到覆盖返回地址的偏移

  • 利用

3.5 End四、End

一、shellcode

>>>>1.1 简介

和Exploit的关系?犹如导弹研究者和利用导弹者。

Exploit负责将程序导向shellcode,shellcode又称为payload。通常缓冲区溢出漏洞中可利用shellcode技术。最关键的是如何让程序交出控制权给shellcode。

>>>>1.2 缓冲区溢出

缓冲区(Buffer)又称为缓存(Cache),是内存空间的一部分。简单理解,可以把它想象成一段栈空间。当一个程序在对缓冲区进行写操作时是很危险的,如果写入的数据超过缓冲区大小则会将缓冲区之外的数据覆盖,造成数据溢出。

溢出示例

shellcode就是利用了缓冲区存放,例如下面这段程序就存在溢出漏洞:

#include <stdio.h>
#include <windows.h>
#define PASSWORD "1234567"
int verify_password (char *password)
{
    int authenticated;
    char buffer[44];
    authenticated=strcmp(password,PASSWORD);
    strcpy(buffer,password);//over flowed here!
    return authenticated;
}
main()
{
    int valid_flag=0;
    char password[1024];
    FILE * fp;
    LoadLibrary("user32.dll");//prepare for messagebox
    if(!(fp=fopen("password.txt","rw+")))
    {
        exit(0);
    }
    fscanf(fp,"%s",password);
    valid_flag = verify_password(password);
    if(valid_flag)
    {
        printf("incorrect password!n");
    }
    else
    {
        printf("Congratulation! You have passed the verification!n");
    }
    fclose(fp);
}

在上面的程序中,verify_password函数中存在大小为44的缓冲区buffer,后面没用做长度校验,直接使用了strcpy进行了填充,导致缓冲区溢出。该程序可通过在password.txt中填充shellcode,通过OD动态调试发现buffer缓冲区之后存放了函数返回地址,只要再把该地址覆盖成shellcode的入口地址就能执行shellcode。

规划缓冲区

在填充shellcode的时候还要合理规划缓冲区,此处shellcode填充在返回地址之前,导致shellcode的大小被限制在44,所以shellcode可以填充在函数返回地址之后。缓冲区中被放的数据可以有以下几种:1. 填充物:一般是nop指令,函数返回地址只要落在该范围内就能顺序到达shellcode位置。2. 被覆盖的返回地址:可以是shellcode入口地址、跳转指令地址、近似到shellcode的nop填充物地址。3. shellcode机器码

摆放方式:

6cc11ae8f32962eb791b8ee52bcdf76a.png

>>>>1.3 字符串转16进制脚本

str_to_little_endian.py

溢出中的shellcode通常把静态数据(例如字符串)存储到栈中,例如存储“techliu”到栈中:

xor ebx, ebx
push ebx
push 0x0075696C
push 0x68636574

这是根据栈的存储特性以及小端序特性写入到内存中的,这样在内容中就能看到'techliu'的字符串,前两行是将字符串结束符NULL入栈,但是不能直接push 0,因为可能会发生shellcode截断。

而且push只能操作DWORD大小的数据,所以需要对字符串进行切分入栈。

在py脚本后直接跟转化的字符串即可,生成的16进制从下到上依次入栈。

脚本内容:

import struct
import sys
BLOCK = 4
if __name__ == '__main__':
  des_str = sys.argv[1]
  if not des_str:
      print("Not argv[1]!")
      exit(0)
  if isinstance(des_str, str):
      des_str = des_str.encode()
  # str_len = len(des_str);
 
  s
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值