You'd better double check for a typo because you actually got the syntax right for the search parameter.
search('myField:myString')
filters all entries where a field with handle "myField" contains a string "myString". What you have should totally work to get the entries with a checkbox field handle "zone" and the value of the checkbox option being "pupil".
If you're sure that there's no typo and you actually have entries that match the criteria, I'd try if it helps to rebuild the search indexes (tool in the CP settings). I actually try to avoid using the search
parameter if possible, because things can go wrong with the indexes. Unfortunatelly I don't think there's other ways to filter by a checkbox field.
Other posibillity: If you don't want to paginate the entries or use other methods that are not available on custom arrays of entry models, what about filtering them with a simple conditional:
{% set entries = craft.entries %}
{% for entry in entries if entry.zone.contains('pupil') %}
{{ entry.title }}
{% endfor %}