Convolution and linear layers look quite different if you compare how the parameters are used in these operations, but note that you could use a matrix multiplication in a conv layer by unfolding the input and transforming the kernels appropriately (the input transformation is often called im2col in the literature).
For a 1x1 kernel, you could also view and permute the input to get the same results, as seen here:
x = torch.randn(2, 3, 24, 24)
conv = nn.Conv2d(3, 6, 1)
out_conv = conv(x)

lin = nn.Linear(3, 6)
with torch.no_grad():
    lin.weight.copy_(conv.weight.squeeze()) # remove spatial size
    lin.bias.copy_(conv.bias)
    
# permute x so that linear layer is executed on spatial dimension repeatedly
x = x.view(x.size(0), x.size(1), -1)
x = x.permute(0, 2, 1)
out_lin = lin(x)

# permute back to be able to compare results
out_lin = out_lin.permute(0, 2, 1)
out_lin = out_lin.view(out_lin.size(0), out_lin.size(1), 24, 24)

# compare
print((out_conv - out_lin).abs().max())
> tensor(4.7684e-07, grad_fn=<MaxBackward1>)

In particular these two layers are quite similar to each other.