Geometry.Explode to get the surfaces from the solid geometry.
Then get the Z the normal at parameter 0.5,0.5 for each surface with a Surface.NormalAtParameter. This is the ‘facing direction’ of each surface.
Pull the Z component of each with a Vector.Z node. This tells us the vertical component of the facing direction. Something with a value of 1 is facing perfectly up - that surface was level. Something with a value of 0 has no slope to it - that surface is vertical and plumb. Something with a value of -1 is perfectly down - that surface is also level.
Then check if that Z value is less than -0.1. This will give us a clue on any surface which is ‘partially facing down’, meaning it is in some way defining the bottom of the stair.
Use that boolean value to filter the original list of surfaces so you only have stuff which faces down.
Take the ‘in’ results into a PolySurface.ByJoinedSurfaces node and disable all other geometry preview to confirm you have the right surfaces. If you caught stuff like riser surfaces decrease the value of -0.1 until it is good for your design. If you wind up without the underside of the run then you have gone too far.
Pull the perimeter curves of the polysurface this list of curves should be the outline drawn above.