It is not to difficult but as often it goes faster by hand than by programming and testing and use it once only.
You can Import the notebook as a text object
text= Import[ file.nb];
Then you can determine the position of "Section" in the text
sections = Position[ txt, "Section"]
yielding e.g.
{{1, 1, 1, 1, 2, 1, 1, 1, 2}, {1, 1, 1, 1, 3, 1, 1, 1, 2}}
now you can read off the first section cell by dropping the last two indices in the position list. Set the section name as a variable to the content
ToExpression[ txt[[##]] & @@ sections ] = txt[[##]] & @@ Drop[sections[[1]] , -2]
Cell["Lists", "Section",
CellChangeTimes -> {{3.86767*10^9, 3.86767*10^9}},
ExpressionUUID -> "b1a1211e-35fe-4014-b8a6-32ec6b1fc429"], Cell[
CellGroupData[{ .... bla bla
For each section isolate its subsections and so forth. Make lists of the object classes, sort them and export the rearranged notebook. It succeds unfortunately only if it is accepted by loading. Its essential to use the original wrapping part.