Thursday, July 15, 2021

Continuing Linux Kernel Development - Learning about processes information

In the previous post, I added parameters to my module. In this post, I am learning more about reading information on Linux processes. 

Here is my code.

  1
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
/*
 * Learning about Linux Process Information
 * This code mereley reads various data about a process whose PID is entered as a parameter via the Loadable Kernel Module (LKM)
 * Author: Nik Alleyne
 * Author Blog: www.securitynik.com
 * Filename: processInfo.c
 */

// reference the header files to be used
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/current.h>
#include <linux/sched/signal.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <net/sock.h>
#include <linux/socket.h>
#include <linux/net.h>
#include <linux/cred.h>

static int pid_to_lookup = 0;
module_param(pid_to_lookup, int, S_IRUGO);
MODULE_PARM_DESC(pid_to_lookup, "Specify a PIDr, 2 is invalid.");


// Define the code to execute at module installation
static int __init startup(void)
	{	
		printk(KERN_INFO "[*] Entering the kernel ...\n");
				
		// Print information for current PID - basically the insmod module
		// Get current process executable name
		printk(KERN_INFO "[*] Process Name: %s \n", current->comm);

		// Get current process PID
		printk(KERN_INFO "[*] Process %s has PID: %i \n", current->comm, current->pid);

		// Get current task group ID (TGID)
		printk(KERN_INFO "[*] Process %s has TGID: %i \n", current->comm, current->tgid);

		// Getting the UID and EUID of the current process. This process is more than likely insmod
		// This comes from linux/cred.h
		const struct cred *current_process_cred = current_cred();
		printk(KERN_INFO "\n[*] Current Process UID: %d\n", current_process_cred->uid);
		printk(KERN_INFO "[*] Current Process GID: %d \n ", current_process_cred->gid);
		printk(KERN_INFO "n[*] Current Process Effectie UID: %d\n", current_process_cred->uid);
		printk(KERN_INFO "[*] Current Process Effective GID: %d \n ", current_process_cred->egid);
		printk(KERN_INFO "[*] Current Process Saved SUID: %d\n", current_process_cred->suid);
		printk(KERN_INFO "[*] Current Process SGID: %d \n ", current_process_cred->sgid);
		
		// Create a pointer to the task structure
		struct task_struct *target_process_structure;
		
		// Create another pointer to the task structure. This one is to track the threads
		struct task_struct *thread_info;

		// Print information for the PID being looked up
		target_process_structure = pid_task(find_vpid(pid_to_lookup), PIDTYPE_PID);

		if (target_process_structure)
			{
				// Info on process executing calling this Kernel module
				printk(KERN_INFO " [*] The process you specified has name %s\n", target_process_structure->comm);
				printk(KERN_INFO " [*] The %s process is in state %ld\n", target_process_structure->comm, target_process_structure->state);
				printk(KERN_INFO " [*] The %s process has the following flags %ua\n\n", target_process_structure->comm, target_process_structure->flags);
				// printk(KERN_INFO " [*] The %s process ptrace info  %d\n", target_process_structure->comm, target_process_structure->ptrace);
				
				printk(KERN_INFO "[*] ******************************* BEGINNING OF PID:%d INFORMATION **********************************\n", target_process_structure->pid);

				// Info on the process which was entered as the parameter
				printk(KERN_INFO " [*] The %s process is running on CPU %d \n", target_process_structure->comm, target_process_structure->on_cpu);
				printk(KERN_INFO " [*] The %s process current CPU %d \n", target_process_structure->comm, target_process_structure->cpu);

				printk(KERN_INFO " [*] The %s process wakee flips %u \n", target_process_structure->comm, target_process_structure->wakee_flips);
				
				printk(KERN_INFO " [*] The %s process wakee Flip Decay Timestamp  %ld \n\n", target_process_structure->comm, target_process_structure->wakee_flip_decay_ts);
			
			
				printk(KERN_INFO " [*] The %s process is recently used CPU %d \n", target_process_structure->comm, target_process_structure->recent_used_cpu);
				printk(KERN_INFO " [*] The %s process wake CPU  %d \n\n", target_process_structure->comm, target_process_structure->wake_cpu);
				printk(KERN_INFO " [*] The %s process on rq %d \n", target_process_structure->comm, target_process_structure->on_rq);
				printk(KERN_INFO " [*] The %s process Prio  %d \n", target_process_structure->comm, target_process_structure->prio);
				printk(KERN_INFO " [*] The %s process Static Prio  %d \n", target_process_structure->comm, target_process_structure->static_prio);
				printk(KERN_INFO " [*] The %s process Normal Prio  %d \n", target_process_structure->comm, target_process_structure->normal_prio);
				printk(KERN_INFO " [*] The %s process Rt Prio  %u \n", target_process_structure->comm, target_process_structure->rt_priority);


				printk(KERN_INFO " [*] The %s process btrace seq  %d \n\n", target_process_structure->comm, target_process_structure->btrace_seq);
				printk(KERN_INFO " [*] The %s process Policy  %u \n", target_process_structure->comm, target_process_structure->policy);
				printk(KERN_INFO " [*] The %s process Number of CPUs allowed  %d \n", target_process_structure->comm, target_process_structure->nr_cpus_allowed);

				printk(KERN_INFO " [*] The %s process Exit State  %d \n\n", target_process_structure->comm, target_process_structure->exit_state);
				printk(KERN_INFO " [*] The %s process Exit Code  %d \n", target_process_structure->comm, target_process_structure->exit_code);
				printk(KERN_INFO " [*] The %s process Exit Signal  %d \n", target_process_structure->comm, target_process_structure->exit_signal);
				printk(KERN_INFO " [*] The %s process Pdeath signal  %d \n", target_process_structure->comm, target_process_structure->pdeath_signal);


				printk(KERN_INFO " [*] The %s process Job CTL  %ld \n\n", target_process_structure->comm, target_process_structure->jobctl);
				printk(KERN_INFO " [*] The %s process Peronality  %d \n", target_process_structure->comm, target_process_structure->personality);


				printk(KERN_INFO " [*] The %s process Atomic flags  %ld \n", target_process_structure->comm, target_process_structure->atomic_flags);

				printk(KERN_INFO " [*] The %s process has PID %d\n", target_process_structure->comm, target_process_structure->pid);
				printk(KERN_INFO " [*] The %s process has TGID %d\n\n", target_process_structure->comm, target_process_structure->tgid);

				// Real Parent Information 
				printk(KERN_INFO " [*] The %s process Real Parent executable  %s\n", target_process_structure->comm, target_process_structure->real_parent->comm);
				printk(KERN_INFO " [*] The %s process Real Parent PID  %d\n", target_process_structure->comm, target_process_structure->real_parent->pid);
				printk(KERN_INFO " [*] The %s process Real Parent TGID  %d\n\n", target_process_structure->comm, target_process_structure->real_parent->tgid);

				// Parent Information 
				printk(KERN_INFO " [*] The %s process Parent executable  %s\n", target_process_structure->comm, target_process_structure->real_parent->comm);
				printk(KERN_INFO " [*] The %s process parent PID  %d\n", target_process_structure->comm, target_process_structure->real_parent->pid);
				printk(KERN_INFO " [*] The %s process parent TGID  %d\n", target_process_structure->comm, target_process_structure->real_parent->tgid);
			
				printk(KERN_INFO " [*] The %s process Canary value  %lu \n", target_process_structure->comm, target_process_structure->stack_canary);
				
				printk(KERN_INFO " [*] The %s process UTIME   %llu \n\n", target_process_structure->comm, target_process_structure->utime);
				printk(KERN_INFO " [*] The %s process STIME  %llu \n", target_process_structure->comm, target_process_structure->stime);

				printk(KERN_INFO " [*] The %s process Start Time %lld \n", target_process_structure->comm, target_process_structure->start_time);
				printk(KERN_INFO " [*] The %s process Start Boot Time %lld \n\n", target_process_structure->comm, target_process_structure->start_boottime);
				
				//Get information on target process permission
				//This information comes from linux/cred.h
				printk(KERN_INFO "[*] The process %s has real UID:%d \n", target_process_structure->comm, task_uid(target_process_structure).val);
				printk(KERN_INFO "[*] The process %s has effective UID:%d \n", target_process_structure->comm, task_euid(target_process_structure).val);

				// Thread Information
				// Leverages linux/sched/signal.h
				printk(KERN_INFO " [*] The %s process has %d threads \n", target_process_structure->comm, target_process_structure->signal->nr_threads);	

			
				// Enumerate the threads in the process
				// print information on the binary, PID, PPID
				for_each_thread(target_process_structure, thread_info)
					{
						printk(KERN_INFO "[*] Thread executable name:%s  :: Thread PID:%d :: Thread TGID:%d \n :: Running on CPU:%d :: Current CPU:%d", thread_info->comm, thread_info->pid, thread_info->tgid, thread_info->on_cpu, thread_info->cpu); 
					}


				// Get full path of the binary
				// relies on fs.h. This information is not available by default.
				
				// Check to see if the process memory map is null
				printk(KERN_INFO "\n");
				
				// Setup two pointers for the binary paths
				char *temporary_path;
				char *full_binary_path;

				if (target_process_structure->mm)
					{
						printk(KERN_INFO "[*] Memory map exists \n");

						// Semaphore with read bias
						down_read(&target_process_structure->mm->mmap_sem);
						
						if (target_process_structure->mm->exe_file)
							{
								printk(KERN_INFO "[*] Info found on executable \n");
								
								// allocate normal kernel ram. May sleep 
								// Below sees to allocate memory in 4096 bytes chunk
								temporary_path = kmalloc(PATH_MAX, GFP_KERNEL);
								
								if (!temporary_path)
									{
										// printk(KERN_ERR "[!] Error occurred while allocating memory \n");
										panic("[!] FAILED TO ALLOCATE MEMORY in Kerneln");
									}
								else
									{
										printk(KERN_INFO "[*] Allocated memory in %lu bytes chunk\n", ksize(temporary_path));
										printk(KERN_INFO "[*] Target Process Memory Address: %p", &target_process_structure);
										
										// Get the full binary path of the executable
										full_binary_path = d_path(&target_process_structure->mm->exe_file->f_path, temporary_path, PATH_MAX);
										printk(KERN_INFO "[*] Full binary path is: %s \n", full_binary_path);	
									}

								// Free the previously allocated memory
								kfree(temporary_path);

							}
						else
							{
								printk(KERN_INFO "[*] Looks like we have an error ... \n");
							}

						// release the memory map semaphore
						up_read(&target_process_structure->mm->mmap_sem);
					}
				else
					{
						printk(KERN_INFO "[!] WARNING. No memory map found \n");
					}
				
				printk(KERN_INFO "[*] ************************************ END OF PROCESS INFORMATION **********************************\n");
							
			}

		else
			{
				printk(KERN_ERR "[!] ERROR! PID %d is an invalid PID \n", pid_to_lookup);
				return -EINVAL;
			}

		return 0;
	}


// Define the code to execute at module uninstall time
static void __exit exiting(void)
	{
		printk(KERN_INFO "[*] See ya! ...\n");
	}


module_init(startup);
module_exit(exiting);


MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Nik Alleyne - www.securitynik.com");
MODULE_DESCRIPTION("In this code, I am learning about processes \n");
MODULE_VERSION("0.1a");

/* 
 * References:
 * https://elixir.bootlin.com/linux/v5.5.6/source/include/linux/sched.h
 * https://elixir.bootlin.com/linux/latest/source/include/linux/pid.h
 * https://stackoverflow.com/questions/21259672/kernel-right-way-to-check-if-process-is-running-in-c
 * https://elixir.bootlin.com/linux/v5.5.6/source/include/linux/sched.h
 * https://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/Errors/unix_system_errors.html
 * https://www.man7.org/linux/man-pages/man3/errno.3.html
 * https://elixir.bootlin.com/linux/latest/source/include/linux/sched/signal.h
 * https://0xax.gitbooks.io/linux-insides/content/SyncPrim/linux-sync-3.html
 * https://0xax.gitbooks.io/linux-insides/content/SyncPrim/linux-sync-5.html
 * https://www.kernel.org/doc/html/latest/core-api/printk-formats.html
 */

Now that we have the code, here is my "Makefile":

1
2
3
4
5
6
7
obj-m += processInfo.o

all:
	make --directory=/lib/modules/$(shell uname --kernel-release)/build/ M=$(PWD) modules

clean:
	make --directory=/lib/modules/$(shell uname --kernel-release)/build/    M=$(PWD) clean

Let's execute "make all". Honestly, as you can see below, there are a number of warnings. However, all the necessary output file were created and I choose not to spend more time figuring out the warnings as I ran out of time learning this. I had a SANS SEC504 class to teach in a few days. Here is what I got.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
kali@securitynik:~/rootkits/processInfo$ make all
make --directory=/lib/modules/5.5.0-kali2-amd64/build/ M=/home/kali/rootkits/processInfo modules
make[1]: Entering directory '/usr/src/linux-headers-5.5.0-kali2-amd64'
  CC [M]  /home/kali/rootkits/processInfo/processInfo.o
/home/kali/rootkits/processInfo/processInfo.c: In function ‘startup’:
/home/kali/rootkits/processInfo/processInfo.c:44:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
   44 |   const struct cred *current_process_cred = current_cred();
      |   ^~~~~
In file included from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/printk.h:7,
                 from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/kernel.h:15,
                 from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/list.h:9,
                 from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/module.h:12,
                 from /home/kali/rootkits/processInfo/processInfo.c:11:
/usr/src/linux-headers-5.5.0-kali2-common/include/linux/kern_levels.h:5:18: warning: format ‘%d’ expects argument of type int’, but argument 2 has type kuid_t {aka const struct <anonymous>’} [-Wformat=]
    5 | #define KERN_SOH "\001"  /* ASCII Start Of Header */
      |                  ^~~~~~
/usr/src/linux-headers-5.5.0-kali2-common/include/linux/kern_levels.h:14:19: note: in expansion of macro ‘KERN_SOH’
   14 | #define KERN_INFO KERN_SOH "6" /* informational */
      |                   ^~~~~~~~
/home/kali/rootkits/processInfo/processInfo.c:45:10: note: in expansion of macro ‘KERN_INFO’
   45 |   printk(KERN_INFO "\n[*] Current Process UID: %d\n", current_process_cred->uid);
      |          ^~~~~~~~~
/home/kali/rootkits/processInfo/processInfo.c:45:49: note: format string is defined here
   45 |   printk(KERN_INFO "\n[*] Current Process UID: %d\n", current_process_cred->uid);
      |                                                ~^
      |                                                 |
      |                                                 int
In file included from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/printk.h:7,
                 from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/kernel.h:15,
                 from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/list.h:9,
                 from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/module.h:12,
                 from /home/kali/rootkits/processInfo/processInfo.c:11:
/usr/src/linux-headers-5.5.0-kali2-common/include/linux/kern_levels.h:5:18: warning: format ‘%d’ expects argument of type int’, but argument 2 has type kgid_t {aka const struct <anonymous>’} [-Wformat=]
    5 | #define KERN_SOH "\001"  /* ASCII Start Of Header */
      |                  ^~~~~~
/usr/src/linux-headers-5.5.0-kali2-common/include/linux/kern_levels.h:14:19: note: in expansion of macro ‘KERN_SOH’
   14 | #define KERN_INFO KERN_SOH "6" /* informational */
      |                   ^~~~~~~~
/home/kali/rootkits/processInfo/processInfo.c:46:10: note: in expansion of macro ‘KERN_INFO’
   46 |   printk(KERN_INFO "[*] Current Process GID: %d \n ", current_process_cred->gid);
      |          ^~~~~~~~~
/home/kali/rootkits/processInfo/processInfo.c:46:47: note: format string is defined here
   46 |   printk(KERN_INFO "[*] Current Process GID: %d \n ", current_process_cred->gid);
      |                                              ~^
      |                                               |
      |                                               int
In file included from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/printk.h:7,
                 from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/kernel.h:15,
                 from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/list.h:9,
                 from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/module.h:12,
                 from /home/kali/rootkits/processInfo/processInfo.c:11:
/usr/src/linux-headers-5.5.0-kali2-common/include/linux/kern_levels.h:5:18: warning: format ‘%d’ expects argument of type int’, but argument 2 has type kuid_t {aka const struct <anonymous>’} [-Wformat=]
    5 | #define KERN_SOH "\001"  /* ASCII Start Of Header */
      |                  ^~~~~~
/usr/src/linux-headers-5.5.0-kali2-common/include/linux/kern_levels.h:14:19: note: in expansion of macro ‘KERN_SOH’
   14 | #define KERN_INFO KERN_SOH "6" /* informational */
      |                   ^~~~~~~~
/home/kali/rootkits/processInfo/processInfo.c:47:10: note: in expansion of macro ‘KERN_INFO’
   47 |   printk(KERN_INFO "n[*] Current Process Effectie UID: %d\n", current_process_cred->uid);
      |          ^~~~~~~~~
/home/kali/rootkits/processInfo/processInfo.c:47:57: note: format string is defined here
   47 |   printk(KERN_INFO "n[*] Current Process Effectie UID: %d\n", current_process_cred->uid);
      |                                                        ~^
      |                                                         |
      |                                                         int
In file included from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/printk.h:7,
                 from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/kernel.h:15,
                 from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/list.h:9,
                 from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/module.h:12,
                 from /home/kali/rootkits/processInfo/processInfo.c:11:
/usr/src/linux-headers-5.5.0-kali2-common/include/linux/kern_levels.h:5:18: warning: format ‘%d’ expects argument of type int’, but argument 2 has type kgid_t {aka const struct <anonymous>’} [-Wformat=]
    5 | #define KERN_SOH "\001"  /* ASCII Start Of Header */
      |                  ^~~~~~
/usr/src/linux-headers-5.5.0-kali2-common/include/linux/kern_levels.h:14:19: note: in expansion of macro ‘KERN_SOH’
   14 | #define KERN_INFO KERN_SOH "6" /* informational */
      |                   ^~~~~~~~
/home/kali/rootkits/processInfo/processInfo.c:48:10: note: in expansion of macro ‘KERN_INFO’
   48 |   printk(KERN_INFO "[*] Current Process Effective GID: %d \n ", current_process_cred->egid);
      |          ^~~~~~~~~
/home/kali/rootkits/processInfo/processInfo.c:48:57: note: format string is defined here
   48 |   printk(KERN_INFO "[*] Current Process Effective GID: %d \n ", current_process_cred->egid);
      |                                                        ~^
      |                                                         |
      |                                                         int
In file included from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/printk.h:7,
                 from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/kernel.h:15,
                 from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/list.h:9,
                 from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/module.h:12,
                 from /home/kali/rootkits/processInfo/processInfo.c:11:
/usr/src/linux-headers-5.5.0-kali2-common/include/linux/kern_levels.h:5:18: warning: format ‘%d’ expects argument of type int’, but argument 2 has type kuid_t {aka const struct <anonymous>’} [-Wformat=]
    5 | #define KERN_SOH "\001"  /* ASCII Start Of Header */
      |                  ^~~~~~
/usr/src/linux-headers-5.5.0-kali2-common/include/linux/kern_levels.h:14:19: note: in expansion of macro ‘KERN_SOH’
   14 | #define KERN_INFO KERN_SOH "6" /* informational */
      |                   ^~~~~~~~
/home/kali/rootkits/processInfo/processInfo.c:49:10: note: in expansion of macro ‘KERN_INFO’
   49 |   printk(KERN_INFO "[*] Current Process Saved SUID: %d\n", current_process_cred->suid);
      |          ^~~~~~~~~
/home/kali/rootkits/processInfo/processInfo.c:49:54: note: format string is defined here
   49 |   printk(KERN_INFO "[*] Current Process Saved SUID: %d\n", current_process_cred->suid);
      |                                                     ~^
      |                                                      |
      |                                                      int
In file included from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/printk.h:7,
                 from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/kernel.h:15,
                 from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/list.h:9,
                 from /usr/src/linux-headers-5.5.0-kali2-common/include/linux/module.h:12,
                 from /home/kali/rootkits/processInfo/processInfo.c:11:
/usr/src/linux-headers-5.5.0-kali2-common/include/linux/kern_levels.h:5:18: warning: format ‘%d’ expects argument of type int’, but argument 2 has type kgid_t {aka const struct <anonymous>’} [-Wformat=]
    5 | #define KERN_SOH "\001"  /* ASCII Start Of Header */
      |                  ^~~~~~
/usr/src/linux-headers-5.5.0-kali2-common/include/linux/kern_levels.h:14:19: note: in expansion of macro ‘KERN_SOH’
   14 | #define KERN_INFO KERN_SOH "6" /* informational */
      |                   ^~~~~~~~
/home/kali/rootkits/processInfo/processInfo.c:50:10: note: in expansion of macro ‘KERN_INFO’
   50 |   printk(KERN_INFO "[*] Current Process SGID: %d \n ", current_process_cred->sgid);
      |          ^~~~~~~~~
/home/kali/rootkits/processInfo/processInfo.c:50:48: note: format string is defined here
   50 |   printk(KERN_INFO "[*] Current Process SGID: %d \n ", current_process_cred->sgid);
      |                                               ~^
      |                                                |
      |                                                int
/home/kali/rootkits/processInfo/processInfo.c:53:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
   53 |   struct task_struct *target_process_structure;
      |   ^~~~~~
/home/kali/rootkits/processInfo/processInfo.c:151:5: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
  151 |     char *temporary_path;
      |     ^~~~
  Building modules, stage 2.
  MODPOST 1 modules
  CC [M]  /home/kali/rootkits/processInfo/processInfo.mod.o
  LD [M]  /home/kali/rootkits/processInfo/processInfo.ko
make[1]: Leaving directory '/usr/src/linux-headers-5.5.0-kali2-amd64'

However, even with the errors, here is what we got from the make process.

1
2
3
kali@securitynik:~/rootkits/processInfo$ ls
Makefile       Module.symvers  processInfo.c.ORIG          processInfo.ko   processInfo.mod.c  processInfo.o
modules.order  processInfo.c   processInfo.c.WITH_THREADS  processInfo.mod  processInfo.mod.o

Learning about the module before installing it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
kali@securitynik:~/rootkits/processInfo$ sudo modinfo processInfo.ko
filename:       /home/kali/rootkits/processInfo/processInfo.ko
version:        0.1a
description:    In this code, I am learning about processes 

author:         Nik Alleyne - www.securitynik.com
license:        GPL v2
srcversion:     87C84D6F8E9BEF120883007
depends:        
retpoline:      Y
name:           processInfo
vermagic:       5.5.0-kali2-amd64 SMP mod_unload modversions 
parm:           pid_to_lookup:Specify a PIDr, 2 is invalid. (int)

Let's now remove the clutter from my "dmesg" using "dmesg --clear".

1
kali@securitynik:~/rootkits/processInfo$ sudo dmesg --clear

Let's now take a process to learn about. Specifically, let's look at the "qterminal" process.

Here is what is returned when we execute "ps -eLf | grep qterm"

1
2
3
4
5
6
7
8
9
kali@securitynik:~/rootkits/processInfo$ ps -eLf | grep qterm
kali        1402       1    1402  1    7 Jul17 ?        00:02:06 /usr/bin/qterminal
kali        1402       1    1406  0    7 Jul17 ?        00:00:16 /usr/bin/qterminal
kali        1402       1    1423  0    7 Jul17 ?        00:00:00 /usr/bin/qterminal
kali        1402       1    1451  0    7 Jul17 ?        00:00:00 /usr/bin/qterminal
kali        1402       1    1452  0    7 Jul17 ?        00:00:00 /usr/bin/qterminal
kali        1402       1    1453  0    7 Jul17 ?        00:00:00 /usr/bin/qterminal
kali        1402       1    1454  0    7 Jul17 ?        00:00:00 /usr/bin/qterminal
kali       18118    1543   18118  0    1 00:32 pts/1    00:00:00 grep qterm

Using PID "1402", let's insert this module into the kernel.

1
kali@securitynik:~/rootkits/processInfo$ sudo insmod processInfo.ko pid_to_lookup=1402

We can confirm the module installed successfully, by using "lsmod".

1
2
3
4
5
6
7
kali@securitynik:~/rootkits/processInfo$ lsmod | more
Module                  Size  Used by
processInfo            16384  0
fuse                  139264  3
vboxvideo              45056  0
rfkill                 28672  2
vboxsf                 94208  1
....

Now that we have all the information above, let's see what dmesg reports for the module we inserted.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
kali@securitynik:~/rootkits/processInfo$ sudo dmesg --ctime 
[Sat Jul 18 00:35:57 2020] [*] See ya! ...
[Sat Jul 18 00:36:01 2020] [*] Entering the kernel ...
[Sat Jul 18 00:36:01 2020] [*] Process Name: insmod 
[Sat Jul 18 00:36:01 2020] [*] Process insmod has PID: 18139 
[Sat Jul 18 00:36:01 2020] [*] Process insmod has TGID: 18139 
[Sat Jul 18 00:36:01 2020] 
                           [*] Current Process UID: 0
[Sat Jul 18 00:36:01 2020] [*] Current Process GID: 0 
                            
[Sat Jul 18 00:36:01 2020] n[*] Current Process Effectie UID: 0
[Sat Jul 18 00:36:01 2020] [*] Current Process Effective GID: 0 
                            
[Sat Jul 18 00:36:01 2020] [*] Current Process Saved SUID: 0
[Sat Jul 18 00:36:01 2020] [*] Current Process SGID: 0 
                            
[Sat Jul 18 00:36:01 2020]  [*] The process you specified has name qterminal
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process is in state 1
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process has the following flags 4194304a

[Sat Jul 18 00:36:01 2020] [*] ******************************* BEGINNING OF PID:1402 INFORMATION **********************************
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process is running on CPU 0 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process current CPU 1 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process wakee flips 13 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process wakee Flip Decay Timestamp  4297021013 

[Sat Jul 18 00:36:01 2020]  [*] The qterminal process is recently used CPU 0 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process wake CPU  1 

[Sat Jul 18 00:36:01 2020]  [*] The qterminal process on rq 0 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Prio  120 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Static Prio  120 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Normal Prio  120 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Rt Prio  0 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process btrace seq  0 

[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Policy  0 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Number of CPUs allowed  2 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Exit State  0 

[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Exit Code  0 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Exit Signal  17 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Pdeath signal  0 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Job CTL  0 

[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Peronality  0 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Atomic flags  0 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process has PID 1402
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process has TGID 1402

[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Real Parent executable  systemd
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Real Parent PID  1
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Real Parent TGID  1

[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Parent executable  systemd
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process parent PID  1
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process parent TGID  1
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Canary value  1452616746712831488 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process UTIME   48780000000 

[Sat Jul 18 00:36:01 2020]  [*] The qterminal process STIME  39144000000 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Start Time 1460655914727 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process Start Boot Time 1460655914834 

[Sat Jul 18 00:36:01 2020] [*] The process qterminal has real UID:1000 
[Sat Jul 18 00:36:01 2020] [*] The process qterminal has effective UID:1000 
[Sat Jul 18 00:36:01 2020]  [*] The qterminal process has 7 threads 
[Sat Jul 18 00:36:01 2020] [*] Thread executable name:qterminal  :: Thread PID:1402 :: Thread TGID:1402 
                            :: Running on CPU:0 :: Current CPU:1
[Sat Jul 18 00:36:01 2020] [*] Thread executable name:QXcbEventQueue  :: Thread PID:1406 :: Thread TGID:1402 
                            :: Running on CPU:0 :: Current CPU:1
[Sat Jul 18 00:36:01 2020] [*] Thread executable name:QDBusConnection  :: Thread PID:1423 :: Thread TGID:1402 
                            :: Running on CPU:0 :: Current CPU:0
[Sat Jul 18 00:36:01 2020] [*] Thread executable name:llvmpipe-0  :: Thread PID:1451 :: Thread TGID:1402 
                            :: Running on CPU:0 :: Current CPU:1
[Sat Jul 18 00:36:01 2020] [*] Thread executable name:llvmpipe-1  :: Thread PID:1452 :: Thread TGID:1402 
                            :: Running on CPU:0 :: Current CPU:1
[Sat Jul 18 00:36:01 2020] [*] Thread executable name:qterminal  :: Thread PID:1453 :: Thread TGID:1402 
                            :: Running on CPU:0 :: Current CPU:1
[Sat Jul 18 00:36:01 2020] [*] Thread executable name:qterminal  :: Thread PID:1454 :: Thread TGID:1402 
                            :: Running on CPU:0 :: Current CPU:1

[Sat Jul 18 00:36:01 2020] [*] Memory map exists 
[Sat Jul 18 00:36:01 2020] [*] Info found on executable 
[Sat Jul 18 00:36:01 2020] [*] Allocated memory in 4096 bytes chunk
[Sat Jul 18 00:36:01 2020] [*] Target Process Memory Address: 000000004dc12ef2
[Sat Jul 18 00:36:01 2020] [*] Full binary path is: /usr/bin/qterminal 
[Sat Jul 18 00:36:01 2020] [*] ************************************ END OF PROCESS INFORMATION **********************************
kali@securitynik:~/rootkits/processInfo$ 

That's it for this post. My code is in no way perfect. Especially as can be seen from the compilation. However, I learned a lot more than I knew before about Linux processes.