Q:

Um ponteiro global pode apontar para uma variável local?

No caso abaixo, por exemplo:
int *pnum;
void main(){
  int num = 10;
  pnum = &num;
}

O que aconteceria se eu tentasse acessar o valor apontado do ponteiro fora da função main ?

A:

Vamos colocar um código real para ver o que acontece:
#include <stdio.h>
int *pnum;
void teste() {
    printf("%d\n", *pnum);
}
void teste2() {
    int num = 20;
    pnum = &num;
}
void teste3() {
    int num = 30;
    num++;
}
int main() {
    int num = 10;
    pnum = &num;
    teste();
    teste2();
    teste3();
    teste();
}

Veja funcionando no ideone. E no repl.it. Também coloquei no GitHub para referência futura.
O problema não é a variável ser global. É ela apontar para uma variável local. O código só deveria ter um ponteiro apontando para um endereço local (stack) ou no heap. O que acontece se não respeitar isto?
Códigos assim podem apontar para valores arbitrário, para endereços que não possuem dados garantidos.
Quando chamamos a função teste(), ela executa normalmente e pega o valor correto, afinal o endereço do ponteiro é uma área da pilha que está preservada. O stack frame da função Main() não desaparece quando chama outra função. Pelo contrário, um é empilhado no outro.
Note que a linguagem não garante isto. Mas é assim que costuma funcionar. O risco é seu. Se soube o que está fazendo, vai dar tudo certo.
Aí chamamos teste2() que muda o valor do ponteiro. Agora ele aponta para a variável local desta função e não mais para a função Main(). Esta variável tem outro valor. Até aí tudo bem.
Agora chamamos teste3(). Note que criamos uma variável local com novo valor. Mas não mudamos o ponteiro para apontar para esta variável. Ele vai continuar apontando para a variável local de teste2(), certo?
Mas como isto é possível se aquela variável não existe mais? Bem, o endereço de memória continua lá, está apontando pra ele. O que acontece agora?
Chamamos o teste() que imprime o valor da variável local de teste3() que nunca foi referenciado pelo ponteiro pnum. Por que isto ocorre?
Porque no fim da função teste2() o seu conteúdo é desempilhado. Não é apagado, mas fica livre para uso. Com a chamada da teste3(), é empilhado no mesmo lugar onde tinha os dados da teste2(). Por coincidência o valor da variável local de teste3() foi colocado no mesmo lugar onde estava a variável local de teste2(). Mas foi só uma coincidência. Deu sorte, podia ser pior.
Quando você vai subindo a pilha dá até para prever que valores estarão na pilha, mas quando você desce da pilha, qualquer valor que tenha lá deve ser considerado lixo e não deve ser acessado. A linguagem não impede.
Os dois motivos para existir o heap são: ter dados muito grandes que poderiam estourar a pilha ou justamente poder ter dados "vivos" criados por uma função mais alta sendo acessados por funções mais baixas em endereço "garantido".

A:

Sim, como o ponteiro aponta para o endereço da memória é possível modificar as variáveis locais através de um ponteiro global ou simplesmente passando o endereço da sua variável local para um ponteiro como parâmetro para uma função f(&ponteiro) ou para um ponteiro global int * pGlobal;, veja um exemplo abaixo:
#include <stdio.h>

int * pGlobal;

void foo(void)
{
    *pGlobal = 100;
}

int main(void)
{
    int num = 15;

    pGlobal = &num;

    printf("\n%d", *pGlobal);
    printf("\n%d", num);

    *pGlobal = 5;

    printf("\n%d", *pGlobal);
    printf("\n%d", num);

    foo();

    printf("\n%d", *pGlobal);
    printf("\n%d", num);

    return 0;
}

Acessando e modificando a variável declarada na função main:
void foo(void)
{
    *pGlobal = 100;
}

Veja funcionando no Ideone.
Veja mais sobre ponteiros aqui nesta pergunta.

