We note that if you accept that $\ker$ and $\newcommand\coker{\operatorname{coker}}\coker$ are functorial, the only square we need to prove commutes is the one involving the boundary map.
Let's recall how we define the boundary map $d$ in an element-free fashion.
Let $f$ and $g$ be the nonzero maps in the top row, $f'$, $g'$ the nonzero maps in the bottom row, so we have
$$
\require{AMScd}
\begin{CD}
@. A @>f>> B @>g>> C @>>> 0 \\
@. @VaVV @VbVV @VcVV @. \\
0 @>>> A' @>f'>> B' @>g'>> C' @. \\
\end{CD}
$$
Then $g$ induces an epimorphism from $\ker cg$ to $\ker c$. Then $b$ gives a map
$\ker cg$ to $B'$, and
$g'b=cg$, so $b|_{\ker cg}$ lifts to a unique map $d_0 : \ker cg\to A'$.
Then if we let $q_a : A'\to \coker a$, and consider $q_ad_0 : \ker cg \to \coker a$,
observe that $f$ lifts to $f_0 : A\to \ker cg$ by the universal property of the kernel,
and you can check that $\ker c = \coker f_0$. Now
$d_0$ was the lift of $b|_{\ker cg}$ along $f'$ to $A'$, so $d_0\circ f_0$ is
the lift of $bf=f'a$ along $f'$. Therefore $d_0\circ f_0 =a$.
Hence $q_ad_0f_0=q_aa=0$.
As a result, $q_ad_0$ extends along $g|_{\ker cg}$ to give a unique map
$d:\ker c\to \coker a$.
A summary and some diagrams:
First we enlarge the diagram like so:
$$
\require{AMScd}
\begin{CD}
@. A @>f_0 >> \ker cg @>g|_{\ker{cg}}>> \ker c @>>> 0\\
@. @| @VVV @VVV @.\\
@. A @>f>> B @>g>> C @>>> 0 \\
@. @VaVV @VbVV @VcVV @. \\
0 @>>> A' @>f'>> B' @>g'>> C' @. \\
@. @Vq_A VV @. @. \\
@. \coker a @. @. @.\\
\end{CD}
$$
Then
$d_0$ and $d$ are diagonal maps and can't be drawn, but
$d_0$ is the unique map $\ker cg\to A'$ such that
$f'd_0 = b|_{\ker cg}$, and
$d$ is the unique map $\ker c\to \coker a$ such that
$d(g|_{\ker cg}) = q_ad_0$.
Naturality:
Naturality is a result of the construction. For every new map we produce in this construction, you can check that if we had two copies of the snake diagram with a translation between them, then the appropriate square between the constructed maps in each diagram must also commute, since at every stage we construct the new map by either applying a functor, like $\ker$ or $\coker$ to a map already in our diagram, taking a composite of maps in our diagram, or extending/lifting along a kernel/cokernel, and all of these operations produce commutative squares. (Or thought of another way, all of these constructions are functorial in the original diagram in that they take a commutative diagram and enlarge it, and also send translations of the original diagram to translations of the larger diagram).
Note: I apologize for the limited diagrams, but MSE has very limited diagram drawing capabilities, and diagonal morphisms can't be drawn. You may want to draw the diagrams on paper yourself.