Doesn't sound too complicated. You can define the iterator outside. You can also use typedefs. Something like this would fit i think. Note that it would be way cleaner if that MagicIterator would be not a free template, but a member of Item, typedefed in Container maybe. As it's now, there is a cyclic reference in it, which make it necassary to write some ugly workaround code.
namespace detail {
    template<typename T, typename U>
    struct constify;
    template<typename T, typename U>
    struct constify<T*, U*> {
        typedef T * type;
    };
    template<typename T, typename U>
    struct constify<T*, U const*> {
        typedef T const * type;
    };
}
template<typename DstType, 
         typename Container,
         typename InputIterator>
struct MagicIterator;
class Container
{
private:
    struct Item
    {
        Object* pObject;
    };
    std::list<Item> m_items;
public:
    // required by every Container for the iterator
    typedef std::list<Item> iterator;
    typedef std::list<Item> const_iterator;
    // convenience declarations
    typedef MagicIterator< IInterface*, Container, iterator > 
        item_iterator;
    typedef MagicIterator< IInterface*, Container, const_iterator > 
        const_item_iterator;
    item_iterator Begin();
    item_iterator End();
};
template<typename DstType, 
         typename Container = Container,
         typename InputIterator = typename Container::iterator>
struct MagicIterator : 
    // pick either const T or T, depending on whether it's a const_iterator.
    std::iterator<std::input_iterator_tag, 
                  typename detail::constify<
                           DstType, 
                           typename InputIterator::value_type*>::type> {
    typedef std::iterator<std::input_iterator_tag, 
                 typename detail::constify<
                          DstType, 
                          typename InputIterator::value_type*>::type> base;
    MagicIterator():wrapped() { }
    explicit MagicIterator(InputIterator const& it):wrapped(it) { }
    MagicIterator(MagicIterator const& that):wrapped(that.wrapped) { }
    typename base::value_type operator*() {
        return (*wrapped).pObject->GetInterface();
    }
    MagicIterator& operator++() {
        ++wrapped;
        return *this;
    }
    MagicIterator operator++(int) {
        MagicIterator it(*this);
        wrapped++;
        return it;
    }
    bool operator==(MagicIterator const& it) const {
        return it.wrapped == wrapped;
    }
    bool operator!=(MagicIterator const& it) const {
        return !(*this == it);
    }
    InputIterator wrapped;
};
// now that the iterator adepter is defined, we can define Begin and End
inline Container::item_iterator Container::Begin() {
    return item_iterator(m_items.begin());
}
inline Container::item_iterator Container::End() {
    return item_iterator(m_items.end());
}
Now, start using it:
for(MagicIterator<IInterface*> it = c.Begin(); it != c.End(); ++it) {
    // ...
}
You can also use a iterator mixin provided by boost, which works like the input version of boost::function_output_iterator. It calls your iterator's operator() which then returns the appropriate value, doing what we do above in our operator* in principle. You find it in random/detail/iterator_mixin.hpp. That would probably result in fewer code. But it also requires to wrack up our neck to ensure the friend-stuff because Item is private and the iterator isn't defined inside Item. Anyway, good luck :)