PHP - Curl & Captchas II

        De volta com o assunto de manipular os captchas com o Curl. Lembram que no primeiro POST eu havia falado que se não fosse possivel burlar o captcha ao menos poderiamos copia-lo e valida-lo em nosso sistema? Então mostrei como era possivel copia-lo e valida-lo em nosso sistema, e agora quero mostrar como é possivel burlar o captcha.
        Certamente isso não é possivel em 100% dos casos, talvez em 20 ou 30%. Tudo depende de como o sistema para geração de captcha funciona.
O exemplo que usaremos hoje é no site da Secretaria da Fazenda do Estado do Rio Grande do Sul, veja o link aqui. O governo do estado dispoe de uma ficha de registro de contribuintes (pessoa juridica) que é consultada por CNPJ ou inscrição estadual.
        Agora que ja sabemos para que serve e o que faz, vamos ao codigo. Observe bem o que o sistema do governo faz:
        Tela 1 - Voce deve digitar o CNPJ / IE para acessar a ficha.
        Tela 2 - Voce deve digitar os caracteres do captcha.
        Tela 3 - Mostra a ficha do contribuinte do CNPJ / IE em questão.

        Legal! Mas vamos nos aprofundar um pouquinho mais e ver quem são os responsaveis que isso tudo aconteça. Vamos por partes!

Tela 1.
- Vejam com atenção os inputs a serem enviados via post no form:
        SEQ = 1
        LOCAL = SINTEGRA
        cgcmf = (cnpj digitado pelo usuario)
        cgcte = (ie digitado pelo usuario)
- Essas informações são enviadas via post para “http://sintegra.sefaz.rs.gov.br/sef_root/inf/SEF_entrada_sintegra_completa_1.asp?Menu=Nao”.

Tela 2.
- É gerada pelo link acima.
- Veja que interessante a propriedade scr da imagem, “../../includeNovo/GeraImagemVerificacao.asp”, não é uma imagem.
- Envia via post as seguintes variaveis:
MsgUsuario = (os caracteres do captcha digitado pelo usuatio)
btOK= Avançar
- Essas informações são enviadas via post para “http://sintegra.sefaz.rs.gov.br/sef_root/inf/SEF_entrada_sintegra_completa_3.asp?origem=&amb=&consulta=Direta&Menu=Nao&dtDataConsulta=”.

Tela 3.
- É gerada pelo link acima.
- Não tem nemhuma ação.

Dica
        Quando vamos usar CURL em uma pagina que vai fazer autenticação de qualquer especie, sempre armazene os cookies de seção usando CURLOPT_COOKIEJAR. Nunca sabemos quando o sistema vai precisar ler ou gravar esse tipo de cookies.

        Agora que já está tudo explicado vamos aos codigos. Vai ser mais facil explicar como fazer os macetes com o codigo ja na tela.
Vamos fazer tudo em um mesmo arquivo todo o codigo junto. Salve-o como “curl.php”.
Lembram da função “recebe_imagem” que usamos no post anterior? Vamos usa-la novamente. Aí vai a função.

  1.         function recebe_imagem($url, $arquivo, $cookief="", $cookiej="") {
  2. $ch = curl_init ($url);
  3. curl_setopt($ch, CURLOPT_HEADER, 0);
  4. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  5.                 if(!empty($cookief)) {
  6.         curl_setopt($ch, CURLOPT_COOKIEFILE, $cookief);
  7.         }
  8.                 if(!empty($cookiej)) {
  9.         curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiej);
  10.         }
  11. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  12. curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
  13. $data=curl_exec($ch);
  14. curl_close ($ch);
  15. $fp = fopen($arquivo,'w');
  16. fwrite($fp, $data);
  17. fclose($fp);
  18. return $arquivo;
  19. }

Vamos usar tambem uma outra função simples de apoio.

  1.         function between($beg, $end, $str, $i=0, $p="S") {
  2. $a = explode($beg, $str, 2);
  3. $b = explode($end, $a[1]);
  4. $return = $p == "S" ? $beg . $b[$i] . $end : $b[$i];
  5. return $return;
  6. }

20-25. Entenderam? ela serve simplesmente para pegar o conteudo de uma string entre dois delimitadores. Voces vão ver.

Agora vamos criar uma outra função que só mostra o formulario.

  1.         function ConsultaSintegraForm() {
  2. echo "<form method='POST' action='curl2.php'>";
  3. echo "Digite o CNPJ";
  4. echo "<br />";
  5. echo "<input type='text' name='cnpj'/>";
  6. echo "<br />";
  7. echo "OU digite a inscrição estadual";
  8. echo "<br />";
  9. echo "<input type='text' name='ie'/>";
  10. echo "<br />";
  11. echo "<br />";
  12. echo "<input type='submit'/>";
  13. echo "</form>";
  14. echo "<br />";
  15. echo "Repare que não tem o captcha para digitar! Vamos pular ele? Será!?";
  16. }

26-41. Sem explicação para isso.

Lembram que na explicação “Tela1″ no começo do post vimos que eram necessario 4 inputs? SEQ, LOCAL, cgcmf e cgcte? Mas os dois primeiros nunca mudam, então neste formulario só queremos o conteudo dinamico.

Agora vamos ao monstro! Fiz uma função que faz a consulta. Vou coloca-la por partes com fins de didaticos.

  1.         function ConsultaSintegra($cnpj, $ie) {
  2. $post="SEQ=1&LOCAL=SINTEGRA&cgcmf=$cnpj&cgcte=$ie";
  3. $ch = curl_init("http://sintegra.sefaz.rs.gov.br/sef_root/inf/SEF_entrada_sintegra_completa_1.asp?Menu=Nao");
  4. curl_setopt($ch, CURLOPT_POST, 1);
  5. curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
  6. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  7. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  8. curl_setopt($ch, CURLOPT_COOKIEJAR, "sintegra.txt");
  9. $output = curl_exec($ch);
  10. curl_close($ch);

42. A função tem dois parametros $cnpj e $ie.
43. Criamos uma variavel com os valores dos 4 inputs necessarios.
44. Inicia uma seção CURL para a url passada por parametro.
45. Avisa ao CURL que vamos enviar dados via post.
46. Diz para o CURL onde estão os dados que vamos enviar.
47. Pede para o CURL salvar o retorno em uma variavel.
48. Avisa ao CURL que pode seguir qualquer redirecionamento.
49. Salva os cookies de seção no arquivo “sintegra.txt”.
50. Executa a seção CURL e guarda o retorno em $output.
51. Finaliza a seção CURL.

Até aqui beleza. Ja tinhamos visto praticamente a mesma coisa no post anterior. Agora o negócio esquenta!

  1. $ch = curl_init("http://sintegra.sefaz.rs.gov.br/Include/GeraImagemVerificacao.asp");curl_setopt($ch, CURLOPT_COOKIEFILE, "sintegra.txt");
  2. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  3. $senha=curl_exec($ch);
  4. curl_close ($ch);

52. Inicia uma seção CURL para a url passada por parametro.
53. Le o cookie de seção que gravamos anteriormente (linha 50).
54. Pede para o CURL salvar o retorno em uma variavel.
55. Encerra a seção CURL.

Por que fizemos isso? O script “GeraImagemVerificacao.asp” só serve para uma coisa, para verificar se os cookies de seção estão gravados com os devidos valores e provavelmente deve conferir se existe a variavel “cgcmf” ou “cgcte” que enviamos via post anteriormente. Após ele fazer essas verificações o “GeraImagemVerificacao.asp” redireciona para outro script. Mas observe que nós não pedimos para o CURL seguir os redirecionamentos com a opção “CURLOPT_FOLLOWLOCATION”. O redirecionamento é para o script “webcod.cgi”, veja um exemplo da url completa do redirecionamento: “http://www.sefaz.rs.gov.br/cgi-bin/webcod.cgi?figura=876r”. O que tem de interessante aí? O codigo do captcha! huahauahuahuahua! Agora então temos em uma variavel o codigo do captcha, só temos que cortar algumas partes para pega-la.

Observação:
O script “GeraImagemVerificacao.asp” é responsavel pelas verificações dos cookies de seção. Se tudo estiver ok ele vai gravar um outro cookie de seção com os valores do captcha.
O script “webcod.cgi” simplesmente é responsavel por gerar a imagem do captcha com os valores que ele recebe por parametro em “figura”.

  1. $senha=explode("?", $senha);
  2. $senha=explode('"', $senha[1]);
  3. $senha=explode('=', $senha[0]);
  4. $senha=$senha[1];

56-59. Cortamos tudo até ficarmos só com o captcha.

Agora vamos acessar o script “GeraImagemVerificacao.asp” a fim de que ele salve os cookies de seção. Vamos usar para isso a função “recebe_imagem”.

  1. recebe_imagem("http://sintegra.sefaz.rs.gov.br/Include/GeraImagemVerificacao.asp",
  2.                       "ImgSintegra.png",
  3.                       "sintegra.txt",
  4.                       "Imgsintegra.txt");

Certo? E agora? Agora ja temos a faca e o queijo na mão, é só cortar e mandar ver. Então finalmente o fim da função.

  1. $post="MsgUsuario=".$senha."&btOK= Avançar ";
  2. $ch = curl_init("http://sintegra.sefaz.rs.gov.br/sef_root/inf/SEF_entrada_sintegra_completa_3.asp?origem=&amb=&consulta=Direta&Menu=Nao&dtDataConsulta=");
  3. curl_setopt($ch, CURLOPT_POST, 1);
  4. curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
  5. curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
  6. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  7. curl_setopt($ch, CURLOPT_COOKIEFILE, "Imgsintegra.txt");
  8. curl_setopt($ch, CURLOPT_COOKIEJAR, "sintegra.txt");
  9. $output = curl_exec($ch);
  10. curl_close ($ch);
  11. echo $output;
  12. }

64. Criamos uma variavel com o valor do captcha e mais uma variavel.
65. Inicia uma seção CURL para a url passada por parametro.
66. Avisa ao CURL que vamos enviar dados via post.
67. Diz para o CURL onde estão os dados que vamos enviar.
68. Pede para o CURL salvar o retorno em uma variavel.
69. Avisa ao CURL que pode seguir qualquer redirecionamento.
70. Le o cookie de seção salvo pela função “recebe_imagem”.
71. Salva o cookie de seção no arquivo “sintegra.txt”.
72. Executa a seção CURL e guarda o retorno em $output.
73. Finaliza a seção CURL.
74. Mostra o resultado.
75. Termina a função.

É para dar certo! Vamos tornar o script usavel.

  1.        if(isset($_POST['cnpj']) OR isset($_POST['ie'])) {
  2. ConsultaSintegra($_POST['cnpj'], $_POST['ie']);
  3. }
  4.        else {
  5. ConsultaSintegraForm();
  6. }

Pronto, salve tudo entre as tags do php e acesse-o, use este cnpj para testar 05385071000173. Deu certo? Uhuuuu! legal né?!

até a próxima,

Posted in PHP | Tagged , , , , | 10 Comments
  • Publicidade