pwn刷题记录
NSS-[CISCN 2023 初赛]funcanary【canary】NSSCTF | 在线CTF平台下载附件,直接去checksec文件,查看文件二进制保护机制再通过file命令查看文件的信息ida64打开,首先查看main函数void __fastcall __noreturn main(__int64 a1, char **a2, char **a3) { __pid_t v3; // [rsp+Ch] [rbp-4h] sub_1243(a1, a2, a3); while ( 1 ) { v3 = fork(); if ( v3 0 ) break; if ( v3 ) { wait(0LL); } else { puts("welcome"); sub_128A(); puts("have fun"); } } puts("fork error"); exit(0); }fork函数:fork()用于创建一个子进程,我们在shell下执行一个命令其实也是通过fork()实现的,fork()是Linux下最基本的一个系统调用。fork()最大的特点就是一次调用,两次返回,两次返回主要是区分父子进程,因为fork()之后将出现两个进程,所以有两个返回值,父进程返回子进程ID,子进程返回0。通过复制的方式创建一个进程,被创建的进程称为子进程,调用进程称为父进程,复制的子进程是从父进程fork()调用后面的语句开始执行的。这也就是说fork()函数,将调用自己前的复制了下来,再创建了一个子进程。子进程和父进程在开始执行时是一模一样的,但是它们的执行状态可以独立进行改变。进程ID:进程ID(PID)是操作系统分配给每个进程的唯一标识符。在同一时刻,每个运行中的进程都有一个唯一的PID。当一个进程被创建时,操作系统会为其分配一个唯一的PID。PID 通常是一个正整数,系统会在进程终止后回收其PID,并可能在未来为新的进程重新分配该PID。通过shift+f12,我们可以看到一个特殊的字符串,这或许是一个后门在main函数中,看到了一个fork函数,和一个sub_128A()函数因为有fork函数,这个值得我们好好利用。f前文提到fork函数将复制出一个子进程,包括但不限于代码段、数据段、堆和栈。也就是说子进程的最初状态与父进程完全一致,如此便可以知道:子父进程的canary完全相同。当程序存在fork函数并触发canary时,__ stack_chk_fail函数只能关闭fork函数所建立的进程,不会让主进程退出,所以当存在大量调用fork函数时,我们可以利用它来一字节一字节的泄露。查看一下sub_128A,调用了read函数,又存在地址0x28,这是经典的金丝雀v2的值通过__readfsqword(0x28u)读取,这是从线程信息块(TIB)中读取堆叠
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2423907.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!