精华内容
下载资源
问答
  • CTime的格式控制串是什么
  • 什么是格式化字符攻击?

    千次阅读 2014-10-28 17:23:34
    格式化字符漏洞同其他许多安全漏洞一样由于程序员的懒惰造成的。当你正在阅读本文的时候,也许有个程序员正在编写代码,他的任务:打印输出一个字符或者把这个拷贝到某缓冲区内。他可以写出如下的代码: ...

      格式化字符串漏洞同其他许多安全漏洞一样是由于程序员的懒惰造成的。当你正在阅读本文的时候,也许有个程序员正在编写代码,他的任务是:打印输出一个字符串或者把这个串拷贝到某缓冲区内。他可以写出如下的代码:

      printf(“%s”,str);

      但是为了节约时间和提高效率,并在源码中少输入6个字节,他会这样写:

      printf(str);

      为什么不呢?干嘛要和多余的printf参数打交道,干嘛要花时间分解那些愚蠢的格式?printf的第一个参数无论如何都会输出的!程序员在不知不觉中打开了一个安全漏洞,可以让攻击者控制程序的执行,这就是不能偷懒的原因所在。

      为什么程序员写的是错误的呢?他传入了一个他想要逐字打印的字符串。实际上该字符串被printf函数解释为一个格式化字符串(formatstring)。函数在其中寻找特殊的格式字符比如“%d”。如果碰到格式字符,一个变量的参数值就从堆栈中取出。很明显,攻击者至少可以通过打印出堆栈中的这些值来偷看程序的内存。但是有些事情就不那么明显了,这个简单的错误允许向运行中程序的内存里写入任意值。

      Printf中被忽略的东西

      在说明如何为了自己的目的滥用printf之前,我们应该深入领会printf提供的特性。假定读者以前用过printf函数并且知道普通的格式化特性,比如如何打印整型和字符串,如何指定最大和最小字符串宽度等。除了这些普通的特性之外,还有一些深奥和鲜为人知的特性。在这些特性当中,下面介绍的对我们比较有用:

      *在格式化字符串中任何位置都可以得到输出字符的个数。当在格式化字符串中碰到“%n”的时候,在%n域之前输出的字符个数会保存到下一个参数里。例如,为了获取在两个格式化的数字之间空间的偏量:

      intpos,x=235,y=93;

      printf(“%d%n%d\n”,x,amp;pos,y);

      printf(“Theoffsetwas%d\n”,pos);

      *%n格式返回应该被输出的字符数目,而不是实际输出的字符数目。当把一个字符串格式化输出到一个定长缓冲区内时,输出字符串可能被截短。不考虑截短的影响,%n格式表示如果不被截短的偏量值(输出字符数目)。为了说明这一点,下面的代码会输出100而不是20:

      charbuf[20];

      intpos,x=0;

      snprintf(buf,sizeofbuf,“%.100d%n”,x,amp;pos);

      printf(“position:%d\n”,pos);

      简单的例子

      除了讨论抽象和复杂的理论,我们将会使用一个具体的例子来说明我们刚才讨论的原理。下面这个简单的程序能满足这个要求:

      /*

      *fmtme.c

      *Formatavalueintoafixed-sizebuffer

      */

      #includeint

      main(intargc,char**argv)

      {

      charbuf[100];

      intx;

      if(argc!=2)

      exit(1);

      x=1;

      snprintf(buf,sizeofbuf,argv[1]);

      buf[sizeofbuf-1]=0;

      printf(“buffer(%d):%s\n”,strlen(buf),buf);

      printf(“xis%d/%#x@ %p)\n”,x,x,amp;x);

      return0;

      }

      对这个程序有几点说明:第一,目的很简单:将一个通过命令行传递值格式化输出到一个定长的缓冲区里。并确保缓冲区的大小限制不被突破。在缓冲区格式化后,把它输出。除了把参数格式化,还设置了一个整型值随后输出。这个变量是随后我们攻击的目标。现在值得我们注意的是这个值应该始终为1。

      本文中所有的例子都是在x86BSD/OS4.1机器上完成。如果你到莫桑比克执行任务超过20年时间可能会对x86不熟悉,这是一个little-endian机器。这决定在例子中多精度数字的表示方法。在这里使用的具体数值会因为系统的差异而不同,这些差异表现在不同体系结构、操作系统、环境甚至是命令行长度。经过简单调整,这些例子可以在其他x86平台上工作。通过努力也可以在其他体系结构的平台上工作。

      用Format攻击

      现在是我们戴上黑帽子开始以攻击者方式思考问题的时候了。我们现在手头有一个测试程序。知道这个程序有一个漏洞并且了解程序员是在哪里犯错误的(直接把用户输入的命令行参数作为snprintf的格式化参数)。我们还拥有关于printf函数深入的知识,知道如何运用这些知识。让我们开始修补我们的程序吧。

      从简单的开始,我们通过简单的参数调用程序。看这儿:

      %./fmtme“helloworld”

      buffer(11):helloworld

      xis1/0x1@ 0x804745c)

      现在这儿还没有什么特别的事情发生。程序把我们输入的字符串格式化输出到缓冲区里,然后打印出它的长度和数值。程序还告诉我们变量x的值是1(以十进制和十六进制分别显示),x的存储地址是0x804745c。接下来我们试着使用一些格式指令。在下面的例子中我们打印出在格式化字符串之上栈堆中的整型数值:

      %./fmtme“%x%x%x%x”

      buffer(15):1f3110313133

      xis1/0x1@ 0x804745c)

      对这个程序的快速分析可以揭示在调用snprintf函数时程序堆栈的规划:

      AddressContentsDescription

      fp+8Bufferpointer4-byteaddress

      fp+12Bufferlength4-byteinteger

      fp+16amp;n

    展开全文
  • 格式化字符漏洞利用时计算的偏移到底是什么? 我们平时在自己做题或者是看大佬们的wp时都会看见这种说法 说法一: 说法二: 相信有不少半路出家的小白都和我一样都只是知其然不知其所以然,那这里所说的“偏移”...

    格式化字符串漏洞利用时计算的偏移到底是什么?

    我们平时在自己做题或者是看大佬们的wp时都会看见这种说法

    说法一:
    在这里插入图片描述

    说法二:

    请添加图片描述
    相信有不少半路出家的小白都和我一样都只是知其然不知其所以然,那这里所说的“偏移”到底是什么意思呢?

    我们结合这道题来详细讲一讲这些个偏移量所具体代表的意思

    先来看伪代码

    //main函数
    void __fastcall __noreturn main(int a1, char **a2, char **a3)
    {
      int v3; // [rsp+24h] [rbp-Ch] BYREF
      unsigned __int64 v4; // [rsp+28h] [rbp-8h]
    
      v4 = __readfsqword(0x28u);
      sub_4009FF();
      puts("Welcome to the battle ! ");
      puts("[Great Fairy] level pwned ");
      puts("Select your weapon ");
      while ( 1 )
      {
        while ( 1 )
        {
          Menu();
          __isoc99_scanf("%d", &v3);
          if ( v3 != 2 )
            break;
          sub_4008EB();
        }
        if ( v3 == 3 )
        {
          puts("Bye ");
          exit(0);
        }
        if ( v3 == 1 )
          sub_400960();
        else
          puts("Wrong!");
      }
    }
    
    //显示开始菜单
    int Menu()
    {
      puts("1. Stack Bufferoverflow Bug ");
      puts("2. Format String Bug ");
      return puts("3. Exit the battle ");
    }
    
    //分支2
    unsigned __int64 sub_4008EB()
    {
      char buf[136]; // [rsp+0h] [rbp-90h] BYREF
      unsigned __int64 v2; // [rsp+88h] [rbp-8h]
    
      v2 = __readfsqword(0x28u);
      memset(buf, 0, 0x80uLL);
      read(0, buf, 0x7FuLL);
      printf(buf);
      return __readfsqword(0x28u) ^ v2;
    }
    

    从伪代码中可知这道题需要先使用格式化字符串漏洞泄露出canary的地址,然后再使用栈溢出漏洞覆盖返回地址,因为重点是分析偏移的意义,这里我们着重分析前半部分。

    我们看到分支2,这里有一个明显的格式化字符串漏洞,就是printf函数的输出是由输入者自定义的,并且没有给出格式化字符串,所以我们可以通过给输入buf加上自定义的格式化字符串以泄露出canary的值

    观察汇编代码,我们注意到了main函数中存在着canary值的判断

    .text:000000000040094A                 mov     rax, [rbp+var_8]
    .text:000000000040094E                 xor     rax, fs:28h
    .text:0000000000400957                 jz      short locret_40095E
    .text:0000000000400959                 call    ___stack_chk_fail
    

    先是把rbp+var_8移到了rax寄存器中,然后再对rax的值进行判断,从这里可以看出canary的值被存放在rbp+var_8的位置,下面查看var_8的值

    栈结构

    -0000000000000008 var_8           dq ?
    +0000000000000000  s              db 8 dup(?)
    +0000000000000008  r              db 8 dup(?)
    +0000000000000010
    +0000000000000010 ; end of stack variables
    

    所以,canary被存放在rbp-0x8的位置

    那么canary到我们的格式化字符串的输入存放位置有多远呢?

    unsigned __int64 sub_4008EB()
    {
      char buf[136]; // [rsp+0h] [rbp-90h] BYREF
      unsigned __int64 v2; // [rsp+88h] [rbp-8h]
    
      v2 = __readfsqword(0x28u);
      memset(buf, 0, 0x80uLL);
      read(0, buf, 0x7FuLL);
      printf(buf);
      return __readfsqword(0x28u) ^ v2;
    }
    

    我们可以看到输入buf的位置在rbp-0x90的位置,所以第一个偏移的位置就找出来了,就是buf距离canary的位置:0x90-0x8 = 0x88(十六进制别看错了

    第二个偏移需要涉及到函数参数的获取方式

    由于这个程序为64位程序,所以输入输出等函数的参数获取方式是栈与寄存器结合,而字符串类的参数自然是存放在栈中的(我觉得是因为因为这种参数大小不定,寄存器可能放不下)

    其他类型函数获取参数具体方式可以看我的另一篇文章

    函数参数获取方式

    首先来看分支2中的read函数,read函数先在输入缓冲区中获取我们的输入,然后把输入保存在buf位置,然后read函数执行结束,执行printf函数,print函数首先查看格式化输出的字符串,然后严格地按照格式化字符串所指示的输出方式输出栈中的元素

    但是,printf函数千算万算没想到啊,它所信任依赖的格式化字符串是用户(某个黑心的pwn手)输入的,很快啊,一下子就输出了canary的值,所以这个偏移实际上就是printf函数的栈顶到我们本应输出的字符串(buf)的位置。为了更清晰地说明这个问题,使用图表的方式解释这个问题。

    栈帧结构:

    高地址
    | | 较早的栈帧
    |堆|
    | | 调用者rbp ——父函数(调用者)栈帧——
    |栈| 参数n
    | |
    |生| 参数1
    | | ——调用者返回地址——
    |长| 调用者rbp ——子函数(被调用者)栈帧——
    | | 保存的寄存器
    |方| 局部变量
    | |
    \ 向 /
    \/ 局部变量
    低地址 栈顶指针rsp

    在子函数调用时,执行的操作为:

    • 函数将调用参数从后向前压栈
    • 将返回地址压栈保存
    • 跳转到子函数起始地址执行
    • 子函数将父函数栈帧起始地址(rbp) 压栈
    • 将 %rbp 的值设置为当前 %rsp 的值,即将 %rbp 指向子函数栈帧的起始地址

    所以,第二种情况所说的偏移量实际上就是printf函数(子函数)栈顶到main函数(父函数)其中某一个参数的偏移量,也就是到buf的偏移量。

    这篇文章从汇编层面说明了printf函数执行时可能会出现的漏洞,同时顺带着粗略地介绍了函数调用时的栈帧结构。如果对于格式化字符串漏洞的利用方式感兴趣的话可以戳下面的链接看看我的另一篇文章。才疏学浅,文中如有错误欢迎各位大佬在评论区批评指正~~~

    格式化字符串漏洞

    展开全文
  • 1.这样定义出的字符的编码格式是操作系统的默认编码吗(我电脑的默认编码gb2312) PresetPoint_Set set = new PresetPoint_Set(); set.cameraIndexCode = indexCode.data.list[1].cameraIndexCode; set....
  • 如题,我获取了mysql数据库里的字符想知道是什么编码格式的,请问用java代码怎么实现?
  • 如题, sscanf(p,"%d|%*s",&a); 第二个参数是什么意思 |是什么作用?</p>
  • 本人将EXCEL上传到gridview中(通过button按钮上传),hou通过GridView.Rows[i].Cells[k].Text获取数值,出现输入字符格式不正确,求大神指教。
  • 1.一个wchar_t字符,例如L"这一个abc字符",是否UTF-16格式? 2.而char字符,例如"这一个abc字符",是否GBK格式? 在工程的设置里面,“使用UNICODE字符集”或者“使用多字节字符集”也并没有...
  • 如题,在$interval = new DateInterval('P2W')中2W表示两周,但前面的P是什么用法,还看到有写PT的。请提供参考链接,谢谢。
  • 什么是JSON?JSON什么的? JSON(JavaScript Object Notation, JS 对象简谱) 一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储...

    什么是JSON?JSON是干什么的?

    JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。


    JSON 的语法规则

    数组(Array)用方括号[ ]表示。
    对象(Object)用大括号{ }表示。
    名称/值对(name/value)组合成数组和对象。
    名称(name)置于双引号中,值(value)有字符串、数值、布尔值、null、对象和数组。
    并列的数据之间用逗号 , 分隔

    JSON字符串是什么?

    指的是符合json格式要求的js字符串。
    例如:

    // JSON字符串
    var jsonStr = '{"StudentID":"100","Name":"tmac","Hometown":"usa"}';
    

    JSON对象是什么?

    指符合json格式要求的js对象。
    例如:

    // JSON对象
    var jsonObj = { "StudentID": "100", "Name": "tmac", "Hometown": "usa" };
    
    展开全文
  • 知道Python中的字符串是什么吗?

    千次阅读 多人点赞 2021-03-12 13:59:37
    摘要:本文将告诉您Python中的字符串是什么,并向您简要介绍有关该概念的所有知识。 本文将介绍以下内容: 如何创建一个字符串? 如何从字符串访问字符? 格式化字符串 因此,让我们开始吧。 什么是Python中的...
    摘要:本文将告诉您Python中的字符串是什么,并向您简要介绍有关该概念的所有知识。

    本文将介绍以下内容:

    • 如何创建一个字符串?
    • 如何从字符串访问字符?
    • 格式化字符串

    因此,让我们开始吧。

    什么是Python中的字符串?

    我们许多熟悉C,C ++等编程语言的人都会得到诸如“字符串是字符的集合或字符数组”的答案。

    在Python中也是如此,我们说的是String数据类型的相同定义。字符串是序列字符的数组,并写在单引号,双引号或三引号内。另外,Python没有字符数据类型,因此当我们编写“ a”时,它将被视为长度为1的字符串。

    继续本文,了解什么是Python中的String?

    如何创建一个字符串?

    s = 'Hello'
    print(s)
    s1 = "Hello"
    print(s1)
    s2 = ''' Hello
    How is the whether today? '''
    print(s2)

    输出:

    你好
    你好
    你好
    今天如何?

    当我们在字符串中同时使用单引号和双引号以及要编写多行句子时,通常使用三引号。

    笔记

    我们需要注意的是,在使用单引号时,字符串中不应包含单引号,因为如果发生这种情况,Python将假定该行在第二个引号本身出现的情况下结束,并且不会获取所需的输出。相同的符号后应加上双引号和三引号。

    继续本文,了解什么是Python中的String?

    如何从字符串访问字符?

    假设我们要访问字符串中的一个字符,比方说最后一个字符,我们需要知道它在字符串中的位置。

    这是一个字符串以及分配的位置。因此,如果要从字符串访问'n',则必须转到第5位。

    编号或索引从0到小于字符串长度的1开始。

    这是一个python程序,可以使我们更加清楚。

    str = 'Antarctica is really cold.'
    print('str = ', str)
    #first character
    print('str[0] = ', str[0])
    #last character
    print('str[-1] = ', str[-1])
    #slicing 2nd to 5th character
    print('str[1:5] = ', str[1:5])
    #slicing 6th to 2nd last character
    print('str[5:-2] = ', str[5:-2])

    输出:

    str =南极洲真的很冷。
    str [0] = A
    str [-1] =。
    str [1:5] = ntar
    str [5:-2] = ctica确实是col

    现在,如果在索引中从左到右遵循递增顺序模式,则从右到左遵循递减顺序模式,即从-1,-2,-3等。因此,如果要访问最后一个字符,可以通过两种方式进行。

    str = 'Antarctica is really cold.'
    a = len(str)
    print('length of str ', a)
    #last character with the help of length of the string
    print('str[a] ', str[a-1])
    #last character with the help of indexing
    print('str[-1] ',str[-1])

    输出:

    str 26
    str [a]的长度。
    str [-1]。

    字符串本质上是不可变的,这意味着一旦声明了字符串,就不能更改其中的任何字符。

    s = "Hello Batman"
    print(s)
    s[2] = 'P'
    print(s)

    输出:

    你好蝙蝠侠
    回溯(最近一次通话最近):
    文件“ C:/Users/prac.py”,第3行,位于
    s [2] =' P'TypeError
    :'str'对象不支持项目分配

    流程以退出代码1完成

    但是,您可以使用del运算符删除整个字符串。

    s = "Hello Batman"
    print(s)
    del s
    print(s)

    输出:

    您好蝙蝠侠
    回溯(最近一次通话最近):
    文件“ C:/Users/prac.py”,
    打印中的第4行
    NameError:未定义名称“ s”

    流程以退出代码1完成

    如果您不希望s是“ Hello Batman”,而希望它是其他字符串,则可以将字符串整体进行更新。

    s = "Hello Batman"
    print(s)
    s = "Hello Spiderman"
    print(s)

    输出:

    你好蝙蝠侠
    你好蜘蛛侠

    继续本文,了解什么是Python中的String?

    格式化字符串:

    格式化字符串意味着可以在任意位置动态分配字符串。

    可以使用format()方法来格式化Python中的字符串,该方法是用于格式化字符串的功能非常强大的工具。String中的Format方法包含大括号{}作为占位符,可以根据位置或关键字保存参数以指定顺序。

    String1 = "{} {} {}".format('Hello', 'to', 'Batman')
    print("Default order: ")
    print(String1)
    # Positional Formatting
    String1 = "{1} {0} {2}".format('Hello', 'to', 'Batman')
    print("nPositional order: ")
    print(String1)
    # Keyword Formatting
    String1 = "{c} {b} {a}".format(a='Hello', b='to', c='Spiderman')
    print("nString in order of Keywords: ")
    print(String1)
    # Formatting of Integers
    String1 = "{0:b}".format(20)
    print("binary representation of 20 is ")
    print(String1)
    # Formatting of Floats
    String1 = "{0:e}".format(188.996)
    print("nExponent representation of 188.996 is ")
    print(String1)
    # Rounding off Integers
    String1 = "{0:.2f}".format(1 / 6)
    print("none-sixth is : ")
    print(String1)
    # String alignment
    String1 = "|{:<10}|{:^10}|{:>10}|".format('Hello', 'to', 'Tyra')
    print("nLeft, centre and right alignment with Formatting: ")
    print(String1)

    输出:

    默认顺序:
    蝙蝠侠向您问好

    位置顺序:
    致Hello Batman

    字符串按关键字顺​​序排列:
    蜘蛛侠到Hello

    20的二进制表示形式是10100

    188.996的指数表示为
    1.889960e + 02

    六分之一是:
    0.17

    左对齐,居中对齐和右对齐,格式为:
    |您好| 到| 泰拉|

    可以使用格式方法将字符串左对齐(<),右对齐(>)或居中(^)。

    {:<10} .format(“ Hello”)表示Python将为该字符串保留10个空间,并且该字符串将从左侧开始。右对齐和居中对齐也是如此。

    我希望您能很好地学习这些概念,并尝试使其更加准确。

    本文分享自华为云社区《Python中的字符串是什么:您需要知道的一切》,原文作者:Yuchuan。

     

    点击关注,第一时间了解华为云新鲜技术~

    展开全文
  • b8十进制184,书上ASCII码值中有从0到127,这个184怎么办,为什么输出“?”,网上好像讲标准ASCII 码也叫基础ASCII码,使用7 位二进制数,第1位二进制为0,而这里184二进制10111000,第一位1。 还有,我...
  • 有一字符串格式如下 { "status": "10", "result": [{ "x": 11, "y": 12 ...使用cJSONParse函数无法解析成功,且使用cJSONGetErrorPtr函数无法返回错误的字符。...但当字符串格式改为如下...请问这什么呢?
  • 如何使用dim语句对一个vb内置的字符函数定义返回值,定义的格式是什么?dim函数名as类型,这样写有什么问题?
  • [图片说明](https://img-ask.csdn.net/upload/201508/26/1440564102_220643.png)图片说明](https://img-ask.csdn.net/upload/201508/26/1440564090_535130.png)如图第一张数据库的,第二张是... 前台也年月日格式...
  • GridView中的格式字符什么会失效?(转贴) 人会不会在同一个地方跌倒两次?答案肯定的。当我终于找到原因后,隐约想起似乎曾经在很久以前遇到过同样的问题,从而也有了这个结论。 昨天,应用户的要求,将显示...
  • 格式化字符漏洞

    2019-10-23 18:02:03
    文章目录格式化字符漏洞1、什么是格式化字符例子重点 格式化字符漏洞 1、什么是格式化字符 要研究格式化字符漏洞首先我们必须得明白什么是格式化字符。 我们用c语言中常见的printf来举例 printf()...
  • 代码从一个字符中截取前面指定长度子字符,然后把尾部的空格删掉返回。 <函数测试> void testCutTailSp(){ char tmp[11],*org="abc d efgab "; memset( tmp, '\0', sizeof(tmp) ); ...
  • 因为您可以使用格式迷你语言来访问对象的属性.例如,我经常在自己的自定义类工作中使用它.假设我为每台需要处理的计算机定义了一个类.class Computer(object):def __init__(self,IP):self.IP = IP而现在我想对...
  • Spring关于使用注解@Configuration去配置FormattingConversionServiceFactoryBean来实现自定义格式字符处理无效的问题(未找到是什么原因造成的)
  • 求助!!! 今天搞C语言文件时看到这样的代码 ``` int main() ... fp = fopen(R"=====(C:\Users\DELL\Desktop\test.txt)=====", "w+");...关于R"=====()====="究竟是什么意思,有没有其他作用???
  • 1、时间格式转字符:time.format('yyyy-MM-dd hh:mm:ss')2、字符转时间格式: import moment from 'moment'; const dateFormat = 'YYYY/MM/DD'; moment('time',dateFormat)备注: 什么是时间戳? 时间戳指:...
  • 我们在读取Excel 文件时,经常会遇到时间格式是各种乱七八糟的格式:yyyy-MM-DD,yyyy/MM/DD等等,这样就不好转成时间, public static void main(String[] args) { String str = "2018/09/10"; System.out....
  • 什么是字符串格式化?将变量(对象)的值填充到字符中在字符中解析Python表达式对字符进行格式化显示左对齐、右对齐、居中对齐保留数字有效位数2.你学过的字符串格式化方式有哪些?% 字符串格式化format字符...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,150
精华内容 2,460
关键字:

格式串是什么