This example is off the top of my head and isn’t heavily tested but you should get the idea
exten => _nxxxxxx,1,NoOP()
same => n,ExecIf($[${DB_EXISTS(blacklist/${EXTEN})} = 0]?Set(DB(blacklist/${EXTEN})=1))
same => n,GotoIf($[${DB(blacklist/${EXTEN})} < 5]?INC:FAIL)
same => n(INC),Set(DB(blacklist/${EXTEN})=${MATH(${DB(blacklist/${EXTEN})}+1)})
same => n(DIAL),NoOP()
same => n,Dial(SIP/TRUNK/${EXTEN})
same => n,Hangup()
same => n(FAIL),Playtones(congestion)
same => n,Congestion(8)
same => n,Hangup()
Then just do a dbdeltree on the blacklist tree every night at midnight so you start fresh.