There are probably existing data structures for this problem, but I am not familiar with them. Instead, I will just create something with the tools I am familiar with.
Assume that the ranges are stored in arrays $A$ and $B$ so that $A[i] = a_i$ and $B[i] = b_i$ and that the ranges are sorted by their starting points. Given a query range $[c, d]$, we can binary search array $A$ to find the interval $A[sp, ep]$ of ranges starting in $[c, d]$.
To solve the counting version of the problem, we store array $B$ as a wavelet tree. We can then report the number of endpoints $b_i \le d$ in interval $B[sp, ep]$ in $O(\log n)$ time.
If we also want to list the ranges contained in $[c, d]$, we can do that in $O(\log n)$ time per range by using the wavelet tree. We can get the time down to $O(1)$ / range with a range minimum query data structure over array $B$. We find the smallest value $b_i$ in $B[sp, ep]$, check whether $b_i \le d$, and then continue recursively to $B[sp, i-1]$ and $B[i+1, ep]$.
The solution based on wavelet trees assumes that the endpoints are integers. If they are not, we can simply map them into integers by binary searching the sorted array of endpoints.
Example. We have seven ranges: $[2, 6]$, $[3, 4]$, $[3, 5]$, $[4, 8]$, $[5, 6]$, $[6, 7]$, and $[8, 9]$. The arrays are therefore $A = (2, 3, 3, 4, 5, 6, 8)$ and $B = (6, 4, 5, 8, 6, 7, 9)$.
Assume that the query range is $[c, d] = [3, 6]$, which contains three ranges: $[3, 4]$, $[3, 5]$, and $[5, 6]$. By binary searching array $A$, we find that the starting points of the ranges starting in $[3, 6]$ are in the interval $A[2, 6] = (3, 3, 4, 5, 6)$. The corresponding interval of endpoints is $B[2, 6] = (4, 5, 8, 6, 7)$.
The root of the wavelet tree partitions array $B$ into "small" and "large" values and stores the partitioning as a bitvector. Its left and right subtrees are wavelet trees for the subsequences of "small" and "large" values, respectively. If we consider values $\le 5$ "small", the bitvector at the root is $V = (1, 0, 0, 1, 1, 1, 1)$, and the "small" and "large" subsequences are $S = (4, 5)$ and $L = (6, 8, 6, 7, 9)$, respectively.
Bitvector $V$ supports $rank(i, b)$ ("how many $b$s are there in prefix $V[1, i]$") queries in constant time.
We want to count the number of values $\le 6$ in $B[2, 6]$. As $6$ is a "large" value, we first determine the number of "small" values in the interval as
$rank(6, 0) - rank(2 - 1, 0) = 2 - 0 = 2$.
Then we determine the number of "large" values $\le 6$ in $B[2, 6]$ recursively by going into the right subtree. Interval $B[2, 6]$ in the root corresponds to interval
$L[rank(2 - 1, 1) + 1, rank(6, 1)] = L[2, 4] = (8, 6, 7)$
in the right subtree, and the number of values $\le 6$ in $L[2, 4]$ is also the number of "large" values $\le 6$ in $B[2, 6]$. The recursion eventually stops, reporting one such value. Hence the number of values $\le 6$ in $B[2, 6]$ is $2 + 1 = 3$.