Thursday, December 6, 2018

wireshark: Viewing encrypted PSK2AES packet

In case, we capture packets encrypted with WPA/WPA2-PSK security in wireshark.  Now, to see that we can do the following procedure.

  • Go to Edit -> Preferences to open the Preferences dialog box.
  • Expand Protocols and select IEEE 802.11.
  • Select: Enable decryption
  • Edit: Decryption Keys
  • Go to WEP and WPA Decryption window
  • Key type: wpa-pwd
  • Key: <passphrase>:<ssid>
  • Example: 12345678:4366ap
  • Click 'Apply' and 'Ok' on all corresponding nested windows.






Sunday, November 11, 2018

Radius Server with Linksys WRT 300N - PT

I am trying to demonstrate the working of Radius Server on Packet Tracer 7.1.  Components I have are
  • End Devices -> Server - PT (Radius Server)
  • Wireless Devices -> WRT300N (Linksys Wireless Router)
  • End Devices -> Laptop - PT (Wireless Client
Topology
First, we have to insert Wireless adapter in 'Laptop0'.  See the post Basic Wireless with Linksys WRT 300N

Connect ethernet cable(copper straight-through) from Ethernet1 of WRT300N to FastEthernet0 of Server-PT.
  1. Click 'Connections' -> 'Copper Straight-through'
  2. Click WRT300N, select Ethernet1 from the dropdown
  3. Click on Server-PT , select FastEthernet0 from the dropdown.

IP Address Configuration

  • Wireless Router will have default IP address
  • On Server configure '192.168.0.10/24' 
    • Click 'Server' -> 'Config' tab -> 'FastEthernet0' -> 'Static' from 'IP Configuration' -> IP Address '192.168.0.10' ; Subnet Mask '255.255.255.0'
  • In Laptop, set DHCP

Aim

Establish wireless connection from laptop to WRT300N thru WPA2-AES security with the help of Radius Server

AAA Configuration in Server 

Server AAA Configuratioin
  1. Click 'Server' -> 'Services' tab -> 'AAA' section
  2. Add Linksys WRT300N as a Radius Client
    • Service 'On' -> Client Name 'actrouter' ; Client IP '192.168.0.1' (IP Address of Wireless Router) ; Secret 'actkey' ; ServerType 'Radius' ; Click 'Add' 
  3. Add a User who will connect from laptop
    •  Username 'actuser' ; Password 'actpass' ; Click 'Add'

AAA Configuration in Router

Router AAA Configuration
  1. Click 'Router' -> 'Config' tab -> 'Wireless' section
  2. SSID 'actwifi' -> Authentication 'WPA2' -> Encryption Type 'AES'
  3. Radius Server IP and Credentials
    • IP Address '192.168.0.10' ; Shared Secret 'actkey'

AAA Configuration in Laptop

Laptop AAA Configuration
  1. Click 'Laptop' -> 'Config' tab -> 'Wireless0' section
  2. SSID 'actwifi' -> Authentication 'WPA2' -> Encryption Type 'AES'
  3. Radius user credentials configuration
    • User ID 'actuser' Password 'actpass'
  4. IP Configuration is DHCP

Connection Success

Wireless Connection between Laptop and WRT300N will be visible.

Connection Testing


Open the command prompt of Laptop, and verify ping to WRT300N and Radius Server.

Basic Wireless with Linksys WRT 300N - PT

Using Cisco Packet Tracer 7.1

Setup will comprise 2 components
  1. Linksys WRT 300N wireless router (Network Devices -> Wireless Devices ->WRT300N)
  2. Laptop ( End Devices -> End Devices -> Laptop)
Laptop by default do not contain wireless card.  We have to physically configure like the following:
  1. Click on laptop -> 'physical' tab 
  2. Click and drag the ethernet module on the image, to the left panel.  A empty slot will be created
  3. Click and drag 'WPC300N' to the empty slot
Aim, is to establish connection from laptop to router thru WPA2-AES wireless encryption.

We configure on wireless router 
  1. Click router -> 'Config' tab -> 'Wireless' section
  2. SSID 'actwifi' ; Authentication 'WPA2-PSK' ; PSK Pass Phrase '12345678' ; Encryption 'AES'
Router Configuration
Now laptop configuration
  1. Click laptop ->'Config' tab -> 'Wireless' section
  2. SSID 'actwifi' ; Authentication 'WPA2-PSK' ; PSK Pass Phrase '12345678', Encryption Type 'AES'
  3. IP Configuration 'DHCP'
Move the mouse over laptop, information of wireless connection(Data rate, signal strength) and DHCP alloted IP address 192.168.0.101 can be seen.

Connection Success
To verify ping, click laptop -> 'Desktop' tab -> 'Command Prompt' -> Issue ping command.

Sunday, August 26, 2018

TCP open connection with scapy

Today, I am going to try to create TCP 3-way connection with the help of scapy and iperf.  The full wireshark capture is
TCP 3-way Connection

192.168.1.10 (client: port 40508: scapy) ------->> 192.168.1.200 (server: port 5000: iperf)

As we donot have a conventional TCP client program running on the client side.  Whenever server sends SYN-ACK packet to client, the kernel on the client responds with Reset TCP connection.  To avoid this, we should place a rule in IPTables, to drop any Reset's packets initiated from client side.  This can be done using the following command on the client side:

# iptables -A OUTPUT -p tcp --tcp-flags RST RST -s 192.168.1.10 -j DROP

On the server side, we create a server listening on port 5000, using 

# iperf -s -p 5000
------------------------------------------------------------
Server listening on TCP port 5000
TCP window size: 85.3 KByte (default)
------------------------------------------------------------

In another session, observe that the output of netstat command, its in listen state

# netstat -na | grep 5000
tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN

On the client side, we open scapy session, send a TCP SYN packet and receive the response.  sr1 implies send (ip/SYN) and wait till ONE response is received.


# scapy
INFO: Can't import python gnuplot wrapper . Won't be able to plot.
INFO: Can't import PyX. Won't be able to use psdump() or pdfdump().
INFO: Can't import python Crypto lib. Won't be able to decrypt WEP.
INFO: Can't import python Crypto lib. Disabled certificate manipulation tools
Welcome to Scapy (2.2.0)
>>>
>>> ip=IP(src="192.168.1.10",dst="192.168.1.200")
>>> SYN=TCP(sport=40508,dport=5000,flags="S",seq=0)
>>> SYNACK=sr1(ip/SYN)
Begin emission:
.......Finished to send 1 packets.
.*
Received 9 packets, got 1 answers, remaining 0 packets

Netstat on the server side, the state would have been

# netstat -na | grep 5000
tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN
tcp        0      0 192.168.1.200:5000      192.168.1.10:40508      SYN_RECV

Now, on the client, we create and send the 3rd handshake message ACK to complete the TCP connection. This has to be sent as quick as possible, because there is a chance that the server may have timed out and dropped the TCP connection.

>>> ACK=TCP(sport=40508,dport=5000,flags="A",seq=SYNACK.ack+1,ack=SYNACK.seq+1)
>>> send(ip/ACK)
.
Sent 1 packets.

Netstat shows that the TCP connection is established.

# netstat -na | grep 5000
tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN
tcp        0      0 192.168.1.200:5000      192.168.1.10:40508      ESTABLISHED

Tuesday, July 31, 2018

DHCP Broadcast - Notes

In my last post on DHCP, DHCP Offer and DHCP ACK were unicast frames.

DHCP Unicast Flag
In the Bootp Flags, the broadcast bit is set to 0(means unicast).  It means DHCP Client tells that it is expecting unicast responses from DHCP server.  So, the reply from DHCP server(DHCP Offer and DHCP ACK) will have Unicast MAC and IP Addresses. 

On a linux machine, this can be seen using command 'dhclient eth0'

Broadcast

There are cases when they will be broadcast.  From linux machine, we can use 'dhclient -B eth0' to request Broadcast responses.  Most of the times, DHCP starts from DHCP Offer, instead of Discovery.  So, by googling I found that we had to release the existing IP address for the transaction to happen from Discovery.  Like this

# dhclient -r  eth0
# dhclient -B  eth0

DHCP Broadcast
Observe that the Bootp flag here is '1'(means Broadcast flag set).  Client is asking the server to give broadcast responses.  Therefore, the DHCP Offer and ACK from the server has broadcast MAC and IP addresses.


Sunday, July 29, 2018

DHCP Notes

Dynamic Host Configuration Protocol.  Server automatically gives IP address to those machine that request it.

  • Message Exchanges (DORA), Discovery, Offer, Request, Acknowledgement.  
  • UDP Protocol - port 68 (server) - port 67 (client)
  • Wireshark decodes it as Bootp Protocol, because Bootp also uses same port numbers
  • Transaction ID same for one transaction of DHCP packets

DHCP

DHCP Discovery

  • DHCP Client ---> DHCP Server
  • Source MAC is client's MAC.  Destinatation MAC is FF:FF:FF:FF:FF:FF 
  • Source IP is 00:00:00:00 (it was not configured with any IP address yet)
  • Destination IP is FF:FF:FF:FF (not sure which one is DHCP server)
DHCP Discovery

DHCP Offer

  • DHCP Server ----> DHCP Client
  • Source MAC and Destination MAC self-explanatory
  • Source IP (Server)
  • Destination IP(Client).  
  • This packet is unicast, but client's IP address is not yet configured. Some cases, the packet will be broadcast.  This needs explanation and it will be done in the next tutorial with Scapy.
  • 'Your (client) IP address' is the IP address given by server to client
  • Rest of the fields are self-explanatory
DHCP Offer

DHCP Request

  • DHCP Client ---> DHCP Server
  • Source MAC is client's MAC.  Destinatation MAC is FF:FF:FF:FF:FF:FF 
  • Source IP is 00:00:00:00 (it was not configured with any IP address yet)
  • Destination IP is FF:FF:FF:FF 
  • The reason why destination MAC and IP are broadcast, even though the client is aware about the server IP address is:  It helps other DHCP servers in the network to be aware that the client has already got hold of another DHCP server and it can reallocate the client-offered IP address to some other machine.
  • Client requests the IP address to the server, and configures IP address on its interface
DHCP Request

DHCP Acknowledge

  • DHCP Server ---> DHCP Client
  • Client would have configured IP address by now, so Destination MAC and IP will be of Client's.
  • All the properties will be the same that of DHCP Offered packet
DHCP Ack

Sunday, July 22, 2018

DNS Notes

While browsing, we give the URL, 'www.xyz.com' something like that.  In internet, it is always converted into IP address for any further processing.  For conversion, we use DNS protocol, Domain Name System.

  • Query & Response
  • UDP protocol, 53 port
DNS Query

DNS Response

Observations
  • Transaction ID is same for both Query and Response
  • In flags, query is 0, response is 1
  • Type: Record type.  A is mapping IPv4 address and DNS name.  MX is mapping IPv4 address and Mail Exchange server.
  • Class: of a Record. belongs to 'IN' Internet name space.

Thursday, June 14, 2018

ARP Notes

I am not going to describe more in detail of the packet formatting.  ARP is the protocol primarily used to retrieve MAC address of a known IP address.  In addition to Ethernet header, following are some of the contents that we usually see (in Ethernet network)
  • Size of MAC address
  • Size of IP address
  • Option(request or reply)
  • Sender MAC address
  • Sender IP address
  • Destination MAC address
  • Destination IP address
Scenario 1

For convenience, we say PC1 is PC with IP address 192.168.1.1 and PC10 is PC with IP address 192.168.1.10

PC1 is wants to get MAC address of PC10.


After this packet reaches PC10, "PC10 will update PC1 details in its ARP cache" by looking ARP request. PC10 will reply to PC1.
PC1 will update PC10 details.  From then on, PC1 and PC10 will not ask for the MAC details of its peers.  Once information is received, till the time the MAC entries are not flushed in its ARP cache, it will use the MAC addresses.

Scenario 2

This is about gratuitous ARP.  A new machine connected to a network advertises its details.  It depends on OS implementation.  I say PC100 is the machine.


  • Dest. MAC in Ethernet header is FFFF..... It is destined for all machines.  If destined for unique machine, all machines will drop the packet and not process it.
  • It will always be ARP request
  • Source MAC in Ethernet Header = Source MAC in ARP packet
  • Source IP in ARP packet = Destination IP in ARP packet
  • Target MAC is all 0s, because it has to abide by the packet structure of ARP Request.

Sunday, May 20, 2018

Basic Exec

Today, we are trying 'exec'.  There are few variants of exec.  To start with we will concentrate on one variant 'execl'.
  1. After this function call, current process will be replaced with exec and current process will no longer exist
  2. First arg: full path of command to execute. Second arg: Name of the program. Third Arg and so on: Optional. Arguments passed to command. End of arguments specified by 'NULL'.
  3. Rest of the program after exec will be ignored as the current program no longer exists.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include <stdio.h>
#include <unistd.h>

int main()
{
 printf("PID of the process %d\n",getpid());
 printf("Sleep using exec\n");
 execl("/bin/sleep","sleep","5",NULL);
 printf("lines after exec\n");
}

Execute the program, and immediately in another terminal issue 'ps -a'


# ./a.out
PID of the process 4628
Sleep using exec

# ps -a
  PID TTY          TIME CMD
 1668 tty1     00:01:34 Xorg
 1674 tty1     00:00:00 gnome-session-b
 1767 tty1     00:00:00 gnome-keyring-d
 1775 tty1     00:01:50 gnome-shell
 1893 tty1     00:00:03 gnome-settings-
 1919 tty1     00:00:00 zeitgeist-datah
 1924 tty1     00:00:04 nautilus
 1926 tty1     00:00:00 tracker-extract
 1935 tty1     00:00:00 tracker-miner-a
 1936 tty1     00:00:00 tracker-miner-f
 1937 tty1     00:00:00 tracker-miner-u
 1960 tty1     00:00:00 gsd-printer
 3639 pts/0    00:11:38 firefox-esr
 4584 tty1     00:00:00 gvim
 4628 pts/1    00:00:00 sleep
 4630 pts/2    00:00:00 ps 

Observations are:
  •  process ID of current program 4628 and the process ID of sleep command in 'ps -a' output are the same.  sleep replaced current program
  • Line 9 of the current program is not executed.  It is ignored.

Monday, April 23, 2018

Catching SIGALRM Signal: Self-driven using alarm function

What makes SIGALRM signal something special?  It is generally used with alarm function.
It is similar to raise function, except for 2 things
  1. SIGALRM is the only signal generated out of alarm function
  2. The signal is not raised immediately.  It is raised after some delay, that is specified by user.
 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
#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void alarm_catch(int signum)
{
 printf("\tCaught the signal %d\n",signum);
}

void main()
{
 //Registering SIGALRM signal
 signal(SIGALRM,alarm_catch);

 //Raise SIGALRM signal to same process after 3 seconds
 alarm(3);

 //Timer loop for 5 seconds: Each print message denotes one second passed
 for(int i=0;i<5;i++)
 {
  printf("TIME\n");
  fflush(stdout);
  sleep(1);
 }
 
}
Steps will be like this
  1. Registering the signal 
  2. Raising alarm.(To raise SIGALRM after 3 seconds)
  3. Timer Loop for 5 seconds
After alarm function is executed, next line of code will be executed without any delay. In the background, after 3 seconds SIGALRM would have been raised.
When we execute the program


root@kali:~# ./a.out
TIME
TIME
TIME
 Caught the signal 14
TIME
TIME

 We got 'Caught the signal 14'(alarm_catch function is executed) after 3 TIME messages (3 seconds, argument of alarm).

Catching Signal, Self-driven with raise function

Till now, we were trying to send signals from one process to another.  Today, we will self-generate the signal within its own function using raise.

Here is the sample program.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include <stdio.h>
#include <signal.h>

void signal_catch(int signum)
{
 printf("\tCaught the signal %d\n",signum);
}

void main()
{
 signal(SIGINT,signal_catch);
 
 printf("Issuing SIGINT signal to itself\n"); 
 raise (SIGINT);
 printf("Exiting\n");
}

As usual, we are registering signal function 'signal_catch' for SIGINT signal.  Using raise function, we are generating signal to its own function.

When we run the program, it is observed that signal_catch function will be executed because it caught the signal SIGINT because of 'raise'.


root@kali:~# ./a.out
Issuing SIGINT signal to itself
 Caught the signal 2
Exiting


Sunday, April 22, 2018

Catching Signal, Child to Parent

Now, I am sending a signal(Ctrl+C) from Child to Parent, using 'kill' command. 'Kill' needs pid of the process & Signal to be sent.

 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
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>

// Function telling what to do when we catch CTRL+C
void catch_signal (int sig_num)
{
 printf("SIGNAL FUNCTION>> Caught the signal %d by process with PID=%d\n",sig_num,getpid());
 fflush(stdout);
}

int main()
{
 pid_t child_pid;
 int status;

 child_pid=fork();
 
 if (child_pid == 0)
 {
  //This is Child Section
  //Registering the Signal Handler
  signal(SIGINT,catch_signal);
  
  printf("CHILD>>pid=%d Ppid=%d Waiting for Ctrl+C\n",getpid(),getppid());
  fflush(stdout);
  pause();
  
  printf("CHILD>>Caught the signal\n");
 }
 else
 {
  //This is Parent Section
  printf("PARENT>>Waiting couple of seconds to make sure, child waits for SIGINT\n");
  sleep(2);
  kill(child_pid,SIGINT);
  printf("PARENT>>Sent the SIGINT signal to child with pid=%d\n",child_pid); 
  wait(&status);
 }

 return 0;
}

Steps can be defined as:
  1. Process is forked
  2. Child registers signal handler
  3. Child waits for Ctrl+C
  4. Parent sleeps.
  5. Parent sends Ctrl+C using Kill command.
  6. Parent waits for Child to complete
In step 4, if Parent did not sleep, sometimes parents will send Ctrl+C, even before Child executes 'pause'.  Then by the time Child needs Ctrl+C, parent will not be in a position to send Ctrl+C because Parent had already sent it.
When we execute the program

root@kali:/media/root/persistence# ./a.out
PARENT>>Waiting couple of seconds to make sure, child waits for SIGINT
CHILD>>pid=3722 Ppid=3721 Waiting for Ctrl+C

Child waits for Ctrl+C, as Parent is sleeping.  Within moments, the rest of the program executes


root@kali:/media/root/persistence# ./a.out
PARENT>>Waiting couple of seconds to make sure, child waits for SIGINT
CHILD>>pid=3722 Ppid=3721 Waiting for Ctrl+C
SIGNAL FUNCTION>> Caught the signal 2 by process with PID=3722
PARENT>>Sent the SIGINT signal to child with pid=3722
CHILD>>Caught the signal

Sunday, April 15, 2018

Catching Signal, with fork

Today, I will demonstrate signals, by forking a child. 

 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
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>

// Function telling what to do when we catch CTRL+C
void catch_signal (int sig_num)
{
 printf("Inside the signal function %d PID=%d\n", sig_num,getpid());
 fflush(stdout);
}

int main()
{
 pid_t child_pid;
 int status;

 // Registering the Signal Handler
 signal(SIGINT,catch_signal);

 child_pid=fork();
 
 if (child_pid == 0)
 {
  //This is Child Section
  printf("CHILD>>pid=%d Ppid=%d Waiting for Ctrl+C\n",getpid(),getppid());
  fflush(stdout);
  pause();
  printf("CHILD>>Caught the signal\n");
 }
 else
 {
  //This is Parent Section
  printf("PARENT>>pid=%d Ppid=%d Waiting for Ctrl+C\n",getpid(),getppid());
  fflush(stdout);
  pause();
  printf("PARENT>>Caught the signal\n");
  
  wait(&status);
 }

 return 0;
}

Summary of what I did:
  1.  Created a signal handling function
  2. Registered signal
  3. Forked the process
  4. Child, waits for the signal Ctrl+C
  5. parent also waits for the signal Ctrl+C
 After I executed

root@kali:/media/root/persistence# ./a.out
PARENT>>pid=2869 Ppid=2344 Waiting for Ctrl+C
CHILD>>pid=2870 Ppid=2869 Waiting for Ctrl+C

Execution 1:

When I hit Ctrl+C in the terminal, Parent and Child got terminated at the same time.

root@kali:/media/root/persistence# ./a.out
PARENT>>pid=2869 Ppid=2344 Waiting for Ctrl+C
CHILD>>pid=2870 Ppid=2869 Waiting for Ctrl+C
Inside the signal function 2 PID=2870
CHILD>>Caught the signal
Inside the signal function 2 PID=2869
PARENT>>Caught the signal

Execution 2:

From another terminal if I pass SIGINT individually to parent and child. They catch signal


root@kali:/media/root/persistence# ./a.out
PARENT>>pid=3119 Ppid=2344 Waiting for Ctrl+C
CHILD>>pid=3120 Ppid=3119 Waiting for Ctrl+C

From another terminal, I issue 'kill -s 2 3119' to the parent process. Parent executes the signal handling function.


root@kali:/media/root/persistence# ./a.out
PARENT>>pid=3119 Ppid=2344 Waiting for Ctrl+C
CHILD>>pid=3120 Ppid=3119 Waiting for Ctrl+C
Inside the signal function 2 PID=3119
PARENT>>Caught the signal
 
Then I issue 'kill -s 2 3120'


root@kali:/media/root/persistence# ./a.out
PARENT>>pid=3119 Ppid=2344 Waiting for Ctrl+C
CHILD>>pid=3120 Ppid=3119 Waiting for Ctrl+C
Inside the signal function 2 PID=3119
PARENT>>Caught the signal
Inside the signal function 2 PID=3120
CHILD>>Caught the signal

Saturday, April 14, 2018

Catching signal , Basic one

Today, I will write a basic program that will catch CTRL+C.  I will demonstrate it by sending CTRL+C from another terminal.


 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
#include <stdio.h>
#include <unistd.h>
#include <signal.h>

// Function telling what to do when we catch CTRL+C
void catch_signal (int sig_num)
{
 printf("Caught the signal %d\n", sig_num);
 fflush(stdout);
}

int main()
{
 // Registering the Signal Handler
 signal(SIGINT,catch_signal);

 printf("Waiting for the user to send CTRL+C\n");
 fflush(stdout);

 // Waiting for signal
 pause();
 printf("Finished handling the signal\n");

 return 0;
}

Steps involved in signal programming
  • Writing a Function that tells what to do when signal is caught
  • Registering the Signal, that tells what signal to catch and what corresponding function to be called
  • Waiting for the signal
I execute the program

root@kali:/media/root/persistence# ./a.out
Waiting for the user to send CTRL+C

Execution 1:
 
Now I hit Ctrl+C at this moment. The program continues

^CCaught the signal 2
Finished handling the signal

Execution 2:

In another terminal, I see the process ID and send signal '2' via kill command.


root@kali:/media/root/persistence# ps -aux | grep a.out
root      3620  0.0  0.0   4188   640 pts/0    S+   22:56   0:00 ./a.out
root      3622  0.0  0.0  12728   928 pts/1    S+   22:56   0:00 grep a.out
root@kali:/media/root/persistence# kill -s 2 3620

Program ends like this

root@kali:/media/root/persistence# ./a.out
Waiting for the user to send CTRL+C
Caught the signal 2
Finished handling the signal

How in this world, did I know the signal is 2. 'kill -l' provides the list of signals.


root@kali:/media/root/persistence# kill -l
 1) SIGHUP  2) SIGINT  3) SIGQUIT  4) SIGILL  5) SIGTRAP
 6) SIGABRT  7) SIGBUS  8) SIGFPE  9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX 

Thursday, April 12, 2018

waitpid waiting for pids to terminate

Last time, we used 'wait' to wait for any forked process to finish.  Now, using waitpid we can dictate what process to catch.   Here's the code:


 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
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

int main()
{
 pid_t child_pid1,child_pid2;
 
 printf ("This is the print before Fork\n");
 child_pid1=fork();
 
 if (child_pid1 == 0) {
  //This is Child 1
  printf("\tCHILD1 >> pid=%d----parentpid=%d\n",getpid(),getppid());
 
  printf("\tCHILD1 >> Child 1 starts sleeping\n");
  sleep(10);
  printf("\tCHILD1 >> Child 1 stops sleeping\n");
 } else {
  child_pid2=fork();
  if (child_pid2 == 0) {
   //This is Child 2
   printf("\tCHILD2 >> pid=%d----parentpid=%d\n",getpid(),getppid());

   printf("\tCHILD2 >> child 2 starts sleeping\n");
   sleep(3);
   printf("\tCHILD2 >> Child 2 stops sleeping\n");
  } else {
   //This is parent
   int status=0,ret;
   printf("Waiting for any Child to terminate\n");
   ret = waitpid(child_pid1,&status,0);
   printf("Caught first one %d with status %d\n\n",ret,status);

   printf("Waiting for any Child to terminate\n");
   ret = waitpid(child_pid2,&status,0);
   printf("Caught second one %d with status %d\n\n",ret,status);

   printf("Waiting for any Child to terminate\n");
   ret = wait(&status);
   printf("Caught third one %d\n",ret);
  }
 }
}

When the program is executed, after the following lines are print there will be a pause

root@kali:/media/root/persistence# ./a.out 
This is the print before Fork
Waiting for any Child to terminate
 CHILD1 >> pid=3196----parentpid=3195
 CHILD2 >> pid=3197----parentpid=3195
 CHILD1 >> Child 1 starts sleeping
 CHILD2 >> child 2 starts sleeping

Then the pause after the following line:

CHILD2 >> Child 2 stops sleeping

Then rest of the lines follows

 CHILD1 >> Child 1 stops sleeping
Caught first one 3205 with status 0

Waiting for any Child to terminate
Caught second one 3206 with status 0

Waiting for any Child to terminate
Caught third one -1

'Caught first one.......'. This line is executed as a result of wait_pid function call, in which we entered child_pid1 as the first argument.  I am ignoring the second and third arguments to reduce the complexity of understanding.  Even though child2 stops earlier than child1, as we mentioned specifically child_pid1 in wait_pid this happened.

The second wait_pid had child_pid2.  By the time, the program started executing this line, the second process has already been terminated.  So without any delay, things continued.

Saturday, April 7, 2018

Fork and Wait Example

Here is a little experimental programming.  Forked two processes and caught those processes.


 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
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

int main()
{
 pid_t child_pid1,child_pid2;
 
 printf ("This is the print before Fork\n");
 child_pid1=fork();
 
 if (child_pid1 == 0) {
  //This is Child 1
  printf("\tCHILD1 >> pid=%d----parentpid=%d\n",getpid(),getppid());
 
  printf("\tCHILD1 >> Child 1 is sleeping\n");
  sleep(10);
  printf("\tCHILD1 >> Child 1 wokeup and is terminated\n\n");
 } else {
  child_pid2=fork();
  if (child_pid2 == 0) {
   //This is Child 2
   printf("\tCHILD2 >> pid=%d----parentpid=%d\n",getpid(),getppid());

   printf("\tCHILD2 >> child 2 is sleeping\n");
   sleep(3);
   printf("\tCHILD2 >> Child 2 wokeup and is terminated\n\n");
  } else {
   //This is parent
   int status=0,ret;
   printf("Waiting for any Child to terminate\n");
   ret = wait(&status);
   printf("Caught first one %d\n\n",ret);

   printf("Waiting for any Child to terminate\n");
   ret = wait(&status);
   printf("Caught second one %d\n\n",ret);

   printf("Waiting for any Child to terminate\n");
   ret = wait(&status);
   printf("Caught third one %d\n",ret);
  }
 }
}

We forked two processes,
  • Child 1 will sleep for 10 secs
  • Child 2 will sleep for 3 secs
  • Child 2 will exit before Child 1
  • 2 Wait commands to catch watever child exists first
  • A wait more to see what happens if there are no more childs left
The output of the program is

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
root@kali:/media/root/persistence# ./a.out
This is the print before Fork
Waiting for any Child to terminate
 CHILD1 >> pid=2835----parentpid=2834
 CHILD1 >> Child 1 is sleeping
 CHILD2 >> pid=2836----parentpid=2834
 CHILD2 >> child 2 is sleeping
 CHILD2 >> Child 2 wokeup and is terminated

Caught first one 2836

Waiting for any Child to terminate
 CHILD1 >> Child 1 wokeup and is terminated

Caught second one 2835

Waiting for any Child to terminate
Caught third one -1

The second child, child2 (2836) will exit first.  Then the first child, child1(2385) will exit next.  The third wait, as it had no child to wait for returns -1.



Thursday, April 5, 2018

Avoiding Zombie Child Process

Refreshing your memory by picking few points from Zombie Process

once the exit status is read via the wait system call, the zombie's entry is removed from the process table and it is said to be "reaped"

I included few things in my program, and started observing.

In the child section,
  • I included sleep to verify if the child process is created.
In the parent section,
  • I am waiting to for the child to exit using ret 
  • Sleeping to verify if the child remained defunct process
 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
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

int main()
{
 pid_t child_pid;
 
 printf ("This is the print before Fork\n");
 child_pid=fork();
 
 if (child_pid == 0) {
  //This is Child
  printf("\tpid=%d\n",getpid());
  printf("\tparentpid=%d\n",getppid());
  printf("\tChild ID=%d\n",child_pid);
 
  printf("\tChild is sleeping. Verify ps for child process list\n");
  sleep(10);
  printf("\tChild wokeup and is terminated\n");
 } else {
  //This is Parent
  printf("pid=%d\n",getpid());
  printf("parentpid=%d\n",getppid());
  printf("Child ID=%d\n",child_pid);
  
  int status=0,ret;
  printf("Waiting for the Child to terminate\n");
  ret = wait(&status);
  printf("Wait is over. Return value ret=%d\n",ret);
  
  printf("Parent Sleeping.  Verify ps for child defunc status\n");
  sleep(20);
  printf("Parent Terminated\n");
 }
}

When the child is sleeping, 'ps' as usual shows parent and child process.

1
2
3
4
5
6
7
8
9
root@kali:/media/root/persistence# ./a.out 
This is the print before Fork
pid=3088
 pid=3089
 parentpid=3088
parentpid=2797
 Child ID=0
Child ID=3089
 Child is sleeping. Verify ps for child process list

1
2
3
4
5
6
root@kali:/media/root/persistence# ps -e -o pid,ppid,cmd | tail -5
 3080     2 [kworker/0:2]
 3088  2797 ./a.out
 3089  3088 ./a.out
 3090  3020 ps -e -o pid,ppid,cmd
 3091  3020 tail -5

After child process is terminated and if we look at ps. Child would have been terminated and only parent process remains.  There is no defunct process.  We avoided zombie process as wait was called to retrieve the status of process.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
root@kali:/media/root/persistence# ./a.out 
This is the print before Fork
pid=3088
 pid=3089
 parentpid=3088
parentpid=2797
 Child ID=0
Child ID=3089
 Child is sleeping. Verify ps for child process list
Waiting for the Child to terminate
 Child wokeup and is terminated
Wait is over. Return value ret=3089
Parent Sleeping.  Verify ps for child defunc status

1
2
3
4
5
6
root@kali:/media/root/persistence# ps -e -o pid,ppid,cmd | tail -5
 3043     2 [kworker/u8:3]
 3080     2 [kworker/0:2]
 3088  2797 ./a.out
 3092  3020 ps -e -o pid,ppid,cmd
 3093  3020 tail -5

At the end, here is the output of the program.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
root@kali:/media/root/persistence# ./a.out 
This is the print before Fork
pid=3088
 pid=3089
 parentpid=3088
parentpid=2797
 Child ID=0
Child ID=3089
 Child is sleeping. Verify ps for child process list
Waiting for the Child to terminate
 Child wokeup and is terminated
Wait is over. Return value ret=3089
Parent Sleeping.  Verify ps for child defunc status
Parent Terminated

Observe the return value at line 12. Wait function returns the process ID of the child that got terminated.

Sunday, April 1, 2018

Look for Zombie Child Process

After forking a process, child and parent processes will execute and die.  If Child dies first, it will become a zombie process, unless it is handled.  Right now, I am not handling anything. Just doing a small extension to my previous program.


 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
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
 pid_t child_pid;
 
 printf ("This is the print before Fork\n");
 child_pid=fork();
 
 if (child_pid == 0) {
  //This is Child
  printf("\tpid=%d\n",getpid());
  printf("\tparentpid=%d\n",getppid());
  printf("\tChild ID=%d\n",child_pid);
  
  printf("\tChild Dying\n");
 } else {
  //This is Parent
  printf("pid=%d\n",getpid());
  printf("parentpid=%d\n",getppid());
  printf("Child ID=%d\n",child_pid);
  
  sleep(20);
 }
}

Note the sleep command in line 26. When the parent is sleeping (that is still processing), child is dead.


1
2
3
4
5
6
7
8
9
root@kali:/media/root/persistence# ./a.out 
This is the print before Fork
pid=5185
parentpid=3594
Child ID=5186
 pid=5186
 parentpid=5185
 Child ID=0
 Child Dying


1
2
3
4
5
6
7
root@kali:/media/root/persistence# ps -e -o pid,ppid,command
  PID  PPID COMMAND
.......
 4761     2 [kworker/3:0]
 4769  3594 ./a.out
 4770  4769 [a.out] <defunct>
 4771  2558 ps -e -o pid,ppid,command



In the process list, we see that the child process(pid # 4770) is listed as <defunct>.  It means it is Zombie Process.

According to Wikipedia, a zombie process or defunct process is a process that has completed execution (via the exit system call) but still has an entry in the process table: it is a process in the "Terminated state". This occurs for child processes, where the entry is still needed to allow the parent process to read its child's exit status: once the exit status is read via the wait system call, the zombie's entry is removed from the process table and it is said to be "reaped".