I've used them "custom" attributes for validation (ie. marking a field to be validated with my own "credit card validation") and custom LinqToLucene analyzers I've written (ie. specifying which analyzer to use on a given field).
The validation code, for example, would look something like this:
public class Customer
{
[CreditCardValidator]
string creditCardNumber;
[AddressValidator]
string addressLineOne
}
When the object above is validated, each field is validated with the appropriate validator thanks to the "custom" attribute.
In the LinqToLucene stuff I've written custom attributes are nice because they allow you to find (through reflection) specific fields at run time. For example, if you have a customer object, you may be interested in getting all the properties that have been marked as "index me": a custom attribute lets you do this easily since it exposes meta-data about the object in a manner that is easy to query.