開発→カザフスタン:税申告の100番目のフォームの通過をどのように支援したか。 300フォームの継続

*これは月ではありません。 これは宇宙ステーションです。

-オビ=ワン・ケノービ*



社会への挨拶!







1件の記事→ 200フォームを開始







続行するには...







私の顧客の問題を解決するための次のステップは、付加価値税の納税申告でした。 興味深いことに、納税者の​​事務所は300の小さなXMLフォームのみをエクスポートできました。 残りのフォームはSONOプログラムを使用してのみエクスポートされました。 そして、これらのフォームはアーカイブされています。







しかし、すべてが初めてのように単純であるとは限りません。











そして、最も興味深いのは、税務申告を提出するためのオンラインサービスをサポートする会社のプログラマーとして、これらの同じフォームを「暗号化」して...







パート1 大きなフォームを読み取る検索アルゴリズムの苦痛。

これがSONOプログラムです。 カザフスタンの税務申告書をオンラインで提出する会計士を雇用しています。











どこから始めましたか?







SONOから宣言の300フォームすべてをエクスポートしました。











そして彼はアーカイブを開こうとした。 しかし、そこにはありませんでした。











アーカイバはエラーを発行しました-「ファイルが破損しています。」 5時間かけてタールの基礎を学んだ後、私は何も理解していないことに気付きました...







愚かなグーグルでのオープンソースの研究も助けにはなりませんでした。 それから、会計フォーラムで小さな議論に出会いました。 管理者が大きなフォームを暗号化するアルゴリズムを公然とopen笑した場所。







さまざまな暗号化保護を記述することなく、ためらうことなく判明しました。 大きなフォームの「暗号化」の作成者は、ファイルの先頭にある最初の2文字「BZ」を愚かに削除することにしました。







このメガキーをファイルの先頭に挿入します











アーカイブを開きました。 そして、その内部には同じ破損したアーカイブがありました。 (同じアーカイブ内にデータを隠し、お気に入りのおもちゃマトリョーシカを見るために発明したコーダーのために)経験上、私はファイルの先頭にBZを追加することでメガクラックを繰り返しました。











そして最後にデータにアクセスできました。











アーカイブから情報を読み取る方法の問題を解決するだけで、私の人生の6時間かかりました。 「アビルデット」-私の叔父が言うように。







大きなフォームを復号化するphpの既製の関数。







if ($_POST["action"] == "getBz2") { $name = $_FILES["bz2"]["tmp_name"]; $homepage = file_get_contents($name); if (strripos($_FILES["bz2"]["name"], ".xml") === false) { $homepage = "BZ".$homepage; file_put_contents($name, $homepage); $baseDir = "/tmp/21"; exec("rm -f " .$baseDir . "/dir/*"); if (!@mkdir("$baseDir", 0777, true)) { } exec("tar -jxvf $name -C $baseDir"); exec (" rm $baseDir/*.xml -rf"); $files = glob("$baseDir/*.bz2"); $homepage = file_get_contents($files[0]); $homepage = "BZ".$homepage; file_put_contents($files[0], $homepage); exec("bunzip2 ".$files[0]); $files = glob("$baseDir/*.xml"); $homepage = file_get_contents($files[0]); } echo homepage; die(); }
      
      





もちろん、すべてを簡単に改善できますが、ここでは「クラック」の原因となるphpコードの一部のみを示します。







パート2 xml構造を読み取り、ToRで必要なデータを収集する







結果のxmlファイルの小さな視覚分析。 彼は、元々xmlとして与えられたフォームがfno formatVersion = 1であり、メガ暗号化されたフォームがfno formatVersion = 2であることを明らかにしました。



















基本的なデータ構造は完全に繰り返されました。







 function getTitle(a) { try { return frame.contentWindow.document.querySelector("form[name='form_300_00'] field[name='" + a + "']").innerHTML; } catch (ex) { return ""; } } var fno = {}; fno["dt"] = {} fno["dt"]["dt_main"] = getTitle("dt_main"); fno["dt"]["dt_regular"] = getTitle("dt_regular"); fno["dt"]["dt_additional"] = getTitle("dt_additional"); fno["dt"]["dt_notice"] = getTitle("dt_notice"); fno["dt"]["dt_final"] = getTitle("dt_final"); fno["dt"]["notice_date"] = getTitle("notice_date"); fno["dt"]["notice_number"] = getTitle("notice_number"); fno["p7"] = getFaktures(7); fno["p8"] = getFaktures(8); fno["period_year"] = getTitle("period_year"); fno["period_quarter"] = getTitle("period_quarter"); fno["submit_date"] = getTitle("submit_date"); fno["field_300_00_001_A"] = getTitle("field_300_00_001_A"); fno["field_300_00_001_B"] = getTitle("field_300_00_001_B"); fno["field_300_00_013_A"] = getTitle("field_300_00_013_A"); fno["field_300_00_013_B"] = getTitle("field_300_00_013_B"); fno["field_300_00_015"] = getTitle("field_300_00_015"); fno["field_300_00_021"] = getTitle("field_300_00_021"); fno["field_300_00_023"] = getTitle("field_300_00_023"); fno["iin"] = getTitle("iin"); fno["rnn"] = getTitle("rnn");
      
      





原則として、ドキュメントの論理構造を20分でコンパイルしました。 メガクラックがなければ、完全にフリーズします。







結果

300フォームのリスト:











フォームの読み込み:











フォームを表示:













ps顧客は喜びのために書くのを止めました。

pps興味のある人にとっては、これは「性」ではありません。

ppps誰かが彼の手で試してみたい場合、私はすぐにすべてをgithubに投げます。 現時点では、システムは最終化されていません。 したがって、私はそれを見せたくない...








All Articles