#dokydoky

[*NIX] Privilege Model 본문

Secure Coding

[*NIX] Privilege Model

dokydoky 2017.08.09 15:25

Introduction

SUID, GUID, 특정 Supplemental Group가 설정되어 있는 바이너리라면 Code audit할 때 최소한의 권한이 설정되어 있는지 잘 확인해야 한다.
권한 설정에 오류가 있으면 임의의 코드가 실행한 바이너리의 경우 쉽게 상위 권한을 얻을 수 있게 된다.
OS의 종류와 버전에 따라 그리고 root권한의 유무에 따라 API의 동작이 다르므로 주의해야 한다.

 

User ID

Types

    Real user ID, Saved set-user-ID, Effective user ID

Functions

int setuid(uid_t uid);
 
int seteuid(uid_t euid);
  
int setreuid(uid_t ruid, uid_t euid);
  
int setresuid(uid_t ruid, uid_t euid, uid_t suid);

 

The sequence of fully drop User privileges

  • Superuser
    • use setuid() // drop all of the user ID, Saved set-user-ID, Effective user ID
  • Nonsuperuser
//case 1. setresuid() : Linux, FreeBSD, HPUX, recent Open BSD
setresuid(getuid(), getuid(), getuid());
  
//case 2. setreuid() : For OS which doesn't support setresuid()
//        - Solaris, certain version of BSDs (OpenBSD before 3.3 doesn't support)
setreuid(getuid(), getuid());
  
//case 3. setuid() twice : OpenBSD before 3.3
setuid(getuid());
setuid(getuid());

 

 

Group ID

Types

    Real group ID, Saved set-group-ID, Effective group ID, Supplemental Group IDs

Functions

int setgid(gid_t gid);
 
int setegid(gid_t egid);
  
int setregid(gid_t rgid, gid_t egid);
 
int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
  
int setgroups(int ngroups, const gid_t *gidset); // effective user ID가 0일 때만 실행가능
  
int initgroups(const char *name, gid_t basegid); // effective user ID가 0일 때만 실행가능

 

The sequence of fully drop Group privileges

  • Superuser
    // Dropping Supplemental Group Privileges
    setgroups(0, NULL)
      
    // Dropping Group Privileges
    setgid(gid)
      
    // Dropping User Privileges
    setuid(uid)
  • Nonsuperuser
    //case 1. setresgid()
    setresgid(getgid(), getgid(), getgid());
      
    //case 2. setregid() : For OS which doesn't support setresgid()
    setregid(getgid(), getgid());
      
    //case 3. setgid() twice : OpenBSD before 3.3
    setgid(getgid());
    setgid(getgid());

 

Audit Tips

Permanent dropping of privileges
  • Superuser
    • effective user ID가 0인 상태로 실행되고 있는가?(setuid, setgid는 effective user ID가 0일 상태에서만 3가지 권한이 모두 변경된다.)
    • supplemental group이 잠정적으로 안전하지 않다면 setgroups로 초기화해야 한다. 단, effective user ID가 0인 상태에서만 실행가능.
    • real, saved set, effective 모두 다 변경되었는지 확인.(saved set의 변경에 주의)
    • privileged group과 supplemental groups 초기화는 effective user ID가 변경되기 전에 수정되어야 한다.(권한문제)
  • Nonsuperuser
    • setgroups()는 effective user ID가 0인 상태에서만 실행가능
    • setuid(getuid()), setgid(getgid())를 사용할 때는 버전별로 API 실행이 다르므로 주의.
Temporary dropping of privileges
  • group permission, supplemental group permission 모두 설정되었는지 확인.
  • user permission보단 group permission을 먼저 설정해야 함.
  • 권한을 drop하기 전에 올바르게 권한을 복구한 상태에서 실행하고있는가?(권한이 낮은 상태에서 실행하면 API 호출이 실패하거나 결과가 다를 수 있다.)
  • Effective user ID를 변경함으로써 signals, debugging API, special device file에 어떤 영향을 주는지 확인.

 

Reference.

  • The art of software security assessment. 7.5.3 Privilege Model

 


'Secure Coding' 카테고리의 다른 글

[C++] Smart pointer noncompliant code cases  (0) 2017.08.09
[*NIX] Privilege Model  (0) 2017.08.09
[C++] Double free example  (0) 2017.04.07
0 Comments
댓글쓰기 폼