First of all, I have not actually tried this, but based on an understanding of how DC works you might be able to do the following ...
You would need to formally create a new cell that has an inverter function but with a new name (via a hacked Liberty file compiled to a custom DB).
You would need some familiarity with Liberty syntax, and also Library Compiler to do this.
Then your first step would be to synthesize the design, after setting both link_library and target_library to your new custom DB.
(and don't touch all cells except the NAND and the hacked INV)
The second step is the trickier one, because you would then have a gate-level netlist using the two cells, but the INV is actually a hierarchical module, even though DC thinks it is a leaf cell.
To keep DC "happy", you should write this netlist out to a Verilog file, and then "remove_design -all" or just restart DC.
You will also need to create (by hand?) a Verilog netlist for a module with your invented name describing your custom INV cell (made of NAND gate).
You would clear the target_library variable, and then use your original library as the link_library.
Then you would read in both netlists, set current_design to the top-level module, link, and "ungroup -all -flatten".
Then you would write out a netlist only made of the NAND gates.
There might be a shorter, more clever way, but I think DC's restriction is that it requires at least a minimal set of leaf cells (std-cells) to map to, which is why I am describing the need to "fake out" a custom INV cell.
If you do not have Library Compiler, then this approach will not work.
BTW, if you tried to avoid modifying the Liberty by instead re-using the original INV cell as the hierarchical NAND-based cell, then I suspect you would run into lib-cell naming-collision errors when you tried to substitute the INV leaf-cell instantiations with a hierarchical module netlist in the second step above.