Box2D has functionality called a "Pre-Solve Event".
This is called after collision detection, but before
collision resolution. This gives you a chance to disable the contact
based on the current configuration. For example, you can implement a
one-sided platform using this callback and calling
b2Contact::SetEnabled(false). The contact will be re-enabled each time
through collision processing, so you will need to disable the contact
every time-step. The pre-solve event may be fired multiple times per
time step per contact due to continuous collision detection.
If you search the box2d user manual for "Pre-Solve" you'll find an example for implementing one-way platforms:
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
if (worldManifold.normal.y < -0.5f)
As for what collision object to create, Edge Shapes fit the bill, again from the manual:
Edge shapes are line segments. These are provided to assist in making
a free-form static environment for your game.
They are simple to create, as you would expect, they're created from two points:
// This an edge shape.
b2Vec2 v1(0.0f, 0.0f);
b2Vec2 v2(1.0f, 0.0f);
Combine those two together and you have static one-way barriers.