[佛系更新……]prctl() in CTF


[佛系更新……]prctl() in CTF

賽題里經常見到prctl(),每次都查資料,每次都忘,這次決定把每次的見到的記錄一下。

詳細見prctl(2) — Linux manual page

函數聲明
 #include <sys/prctl.h>

 int prctl(int option, unsigned long arg2, unsigned long arg3,
           unsigned long arg4, unsigned long arg5);
描述

prctl - operations on a process or thread

prctl()用來對進程就行操作。

prctl() is called with a first argument describing what to do (with values defined in <linux/prctl.h>), and further arguments with a significance depending on the first one.

使用過的幾個參數:

prctl()函數的第一個參數就是來描述想要做的事情。在linux/prctl.h里定義的很多可選參數。

這里選幾個見過的來描述好了:

PR_SET_NO_NEW_PRIVS
PR_SET_NO_NEW_PRIVS (since Linux 3.5)
      Set the calling thread's no_new_privs attribute to the value
      in arg2.  With no_new_privs set to 1, execve(2) promises not
      to grant privileges to do anything that could not have been
      done without the execve(2) call (for example, rendering the
      set-user-ID and set-group-ID mode bits, and file capabilities
      non-functional).  Once set, the no_new_privs attribute cannot
      be unset.  The setting of this attribute is inherited by chil‐
      dren created by fork(2) and clone(2), and preserved across
      execve(2).

      Since Linux 4.10, the value of a thread's no_new_privs
      attribute can be viewed via the NoNewPrivs field in the
      /proc/[pid]/status file.

      For more information, see the kernel source file Documenta‐
      tion/userspace-api/no_new_privs.rst (or Documenta‐
      tion/prctl/no_new_privs.txt before Linux 4.13).  See also
      seccomp(2).

這個參數會很常見:prctl(38, 1LL, 0LL, 0LL, 0LL);

//[include/linux/prctl.h](https://code.woboq.org/userspace/include/linux/prctl.h.html)
#define PR_SET_NO_NEW_PRIVS	38

簡單來說,就是當第一個參數是PR_SET_NO_NEW_PRIVS的時候,第二個參數就是no_new_privs,然后當其值為1時,我們就沒辦法使用execve(),這個設置還會繼承到子進程。

PR_SET_SECCOMP
#define PR_SET_SECCOMP	22

PR_SET_SECCOMP (since Linux 2.6.23)
   Set the secure computing (seccomp) mode for the calling  thread,
   to limit the available system calls.  The more recent seccomp(2)
   system  call  provides  a  superset  of  the  functionality   of
   PR_SET_SECCOMP.

   The  seccomp  mode is selected via arg2.  (The seccomp constants
   are defined in <linux/seccomp.h>.)

   With arg2 set to SECCOMP_MODE_STRICT, the only system calls that
   the  thread is permitted to make are read(2), write(2), _exit(2)
   (but not exit_group(2)), and sigreturn(2).  Other  system  calls
   result  in  the  delivery  of  a  SIGKILL signal.  Strict secure
   computing mode is useful for number-crunching applications  that
   may  need  to  execute  untrusted byte code, perhaps obtained by
   reading from a pipe or socket.  This operation is available only
   if the kernel is configured with CONFIG_SECCOMP enabled.

   With  arg2  set  to  SECCOMP_MODE_FILTER  (since Linux 3.5), the
   system calls allowed are defined by  a  pointer  to  a  Berkeley
   Packet  Filter  passed  in  arg3.  This argument is a pointer to
   struct sock_fprog; it can be designed to filter arbitrary system
   calls and system call arguments.  This mode is available only if
   the kernel is configured with CONFIG_SECCOMP_FILTER enabled.

   If SECCOMP_MODE_FILTER filters permit fork(2), then the  seccomp
   mode  is  inherited by children created by fork(2); if execve(2)
   is  permitted,  then  the  seccomp  mode  is  preserved   across
   execve(2).  If the filters permit prctl() calls, then additional
   filters can be added; they are run in order until the first non-
   allow result is seen.

   For   further   information,   see   the   kernel   source  file
   Documentation/prctl/seccomp_filter.txt.

碰到了一道題里是這么寫的:

prctl(22, 2LL, &unk_202070);

/* Valid values for seccomp.mode and prctl(PR_SET_SECCOMP, <mode>) */
#define SECCOMP_MODE_DISABLED	0 /* seccomp is not in use. */
#define SECCOMP_MODE_STRICT	1 /* uses hard-coded filter. */
# define SECCOMP_MODE_FILTER	2 /* uses user-supplied filter. */

補充一下:就是如果arg2SECCOMP_MODE_STRICT,則只允許調用read,write,_exit,sigreturn這幾個系統調用。如果arg2SECCOMP_MODE_FILTER,就是BPF過濾,其中對syscall的限制通過arg3BPF(Berkeley Packet Filter)的相關結構體定義:

/*
 *	Try and keep these values and structures similar to BSD, especially
 *	the BPF code definitions which need to match so you can share filters
 */
struct sock_fprog {	/* Required for SO_ATTACH_FILTER. */
	unsigned short		len;	/* Number of filter blocks */
	struct sock_filter *filter;
};

struct sock_filter {	/* Filter block */
	__u16	code;   /* Actual filter code */
	__u8	jt;	/* Jump true */
	__u8	jf;	/* Jump false */
	__u32	k;      /* Generic multiuse field */
};

至於這個結構體,在程序里也看不懂,直接export出來,使用seccomp-tools就可以了。

附上使用方法:

filter結構體的數據export出來然后:

seccomp-tools disasm export_result

Reference

seccomp學習筆記

一道 CTF 題目學習 prctl 函數的沙箱過濾規則


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM