I know that the DHCP is used to assign an IP address to the client and hence the only possible way to establish the connection is to listen on a specific port. But is there any specific reason behind choosing 67 and 68?
DHCP is based on the earlier BOOTP protocol which uses well known port numbers for both server and client instead of an ephemeral port. The server and the client communicate via broadcast and the server broadcasts the offered IP address to the client on UDP port 68. The use of a well known port on the client's side is introduced to tackle the problem associated with this broadcast, which we will describe below.
Let's assume that host A is using the BOOTP client on ephemeral port 1883, and host B (which is on the same network) is using MQTT client on the same port. Now when the BOOTP server sends a broadcast reply message with the broadcast IP address 255.255.255.255 and destination port no. 1883, then host A will accept the correct message on its DHCP client on the application layer. But, the MQTT client which is running on the application layer of host B will get an incorrect message. The use of an well known port (in our case 68) prevents the use of the same two destination port numbers and hence it prohibits other protocols from using the same port which is already in use by another protocol. In simple words, it prevents an application from getting a message from a completely different protocol.
For more details I would recommend you to go through the RFC 2131.
The answer is weirder than you think.
Have you ever wondered about the port numbers for early standard TCP services? 21 for FTP, 23 for TELNET, 25 for SMTP? Why are they all odd? How could ssh get 22 decades after telnet using 23?
Apparently the earliest iterations (before the seventies) of the TCP protocol was half-duplex, so bidirectional traffic needed two port numbers. Odd port numbers were reserved for the server side, even numbers were reserved for the client side.
BOOTP (the ancestor of DHCP) was conceived in the same era, and used the same concept: odd number for the serverside listening, even number for the clientside listening.
So how did SSH get 22? After decades of the de-facto standard of using odd numbers for server-side TCP services, it was still unusual to get an even numbered port for a service. However, by 1995, when ssh was first introduced, there was no longer any technical reason to not assign an even number, and noone was even afraid to anymore.