This is probably not the most effective solution, but it should work.
N = size(M, 1);
target_ind = find(M);
offset = [-N-1, -N, -N+1, -1, 0, 1, N-1, N, N+1];
area_ind = bsxfun(@plus, offset, target_ind);
X(target_ind) = median(X(area_ind), 2);
, . , X .
I ,
target_ind area_ind :
for i = 1:size(X, 3)
chan_offset = (i - 1)*size(X, 1)*size(X, 2) % Add the number of elements in previous channels to get indices in the current channel
X(target_ind + chan_offset) = median(X(area_ind + chan_offset), 2);
end