4.php变量覆盖.2

1.题目
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
highlight_file(__FILE__);
include "flag.php";

$_403 = "拒绝访问";
$_200 = "欢迎~~~";

if ($_SERVER["REQUEST_METHOD"] != "POST")
die("sssssssspost…");

if ( !isset($_POST["flag"]) )
die($_403);

foreach ($_GET as $key => $value)
$$key = $$value;

foreach ($_POST as $key => $value)
$$key = $value;

if ( $_POST["flag"] !== $flag )
die($_403);

echo "This is your flag : ". $flag . "\n";
die($_200);

?>

3.basic.rce.2

1.题目
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
//flag in flag
error_reporting(0);
show_source(__FILE__);
if (isset($_GET['Rem'])){
$Ram=$_GET['Rem'];
if(preg_match("/(more|less|flag|head|nl|tail|tac|cat|rm|cp|mv|\*|\{)/i", $Ram)){
die("<strong><center>总之就是非常可爱</center></strong>");
}
$a = eval($Ram);
}else{
echo "<script>alert('爬爬爬我最会爬了')</script>";
}

2.过程&知识点

preg_match函数会对字符串进行正则匹配。

https://www.php.net/manual/zh/function.preg-match.php(有点多,慢慢学吧)

正则匹配:

https://www.runoob.com/regexp/regexp-syntax.html

同时我查到了shell中使用的glob通配符

https://blog.csdn.net/qq_28189423/article/details/83720955

补充https://blog.51cto.com/14812296/2507411?source=dra

对于cat被过滤:

以下都可以作为替代:

  1. more:一页一页的显示档案内容

  2. less:与 more 类似,但是比 more 更好的是,他可以[pg dn][pg up]翻页

  3. head:查看头几行

  4. tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示

  5. tail:查看尾几行

  6. nl:显示的时候,顺便输出行号

  7. od:以二进制的方式读取档案内容(不是很懂,读出来很奇怪)

  8. sort:可以查看

  9. uniq:可以查看

  10. file -f:报错出具体内容

  11. rev:逆向输出

绕过:

  1. ca$1t:未定义变量默认空值

  2. ca‘’t :‘’空值

  3. ‘c”a”t ????’或”c’a’t fl[a]g”

  4. ca``t

  5. 似乎还有base64编码和拼接的高阶操作……:http://blog.leanote.com/post/bowu/de8babf67fd8

好像还有别的执行方式

?Rem=?><?=`ls`;

其实直接?Rem=echo%20`ls`;就行……

先结束上面的语句,<?=是echo的快捷用法,输出了`ls`,反引号括出命令执行的语句

<?=可以被禁用,是不是有点……鸡肋

大佬博客:

无字母数字webshell:

https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html

https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html

https://www.gem-love.com/websecurity/1407.html#PHP%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8C

ctfshow……

 WEB
  
 RCE

1.basic_rce

1.题目:
1
2
3
4
5
6
<?php
//拿到flag就不要乱玩了哦~
error_reporting(0);
show_source(__FILE__);
eval($_GET['a']);
?>
2.过程

eval()将语句以PHP形式执行,其中语句需要符合PHP规范。可以利用eval()执行命令执行代码。

提交a=system(“”);执行系统命令,ls列出文件,cat、tac、more、less、tail、head命令读取文件。实践操作中发现其中一些读不出来,但查看网页源码时可以看见,如:

image-20201126170216250

但是为什么呢……

tac、rev是可用的;

image-20201126170625496

image-20201126170701827

看到show_source(FILE),试了一下,?a=show_source(“f111a9.php”);也可以出答案。

image-20201126170944450

3.知识点
  • cat主要有三大功能:1.一次显示整个文件:cat filename 2.从键盘创建一个文件:cat > filename 只能创建新文件,不能编辑已有文件.3.将几个文件合并为一个文件:cat file1 file2 > file;
  • tac反序输出文件的内容,文件的最后一行显示在第一行;
  • more的功能是将文件从第一行开始,根据输出窗口的大小,适当的输出文件内容;
  • less 可以随意浏览文件,解决more只能向后翻页的问题;
  • head读取文件的前几行;
  • tail读取文件的后几行;
  • nl从第一行开始读取文件,并且显示行号;
  • show_source() 函数对文件进行语法高亮显示,highlight_file()同样可行。

详细:https://www.cnblogs.com/machangwei-8/p/9570550.html

 WEB
  
 RCE

9.回文数

题目链接:https://leetcode-cn.com/problems/palindrome-number/

1.思路

刚刚做完整数反转,回文数好像也差不多,负数一定不是回文数;整数反转以后等于其本身为回文数。

2.注意事项

题目要求一定要有返回值,return NULL。

3.代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
bool isPalindrome(long long int x){
int zf=1;
//int x;
//scanf("%d",&x);
if(x>0) zf=1;
if(x<0) {return false;}
int w=x,i=0,h=x;
while(w)
{
w/=10;
i++;
}
int sz[i+1],t=0;
long long int s=0;
for(int j=i;j>0;j--)
{
sz[j]=h%10;
h=h/10;
t=pow(10,j-1);
s=s+sz[j]*pow(10,j-1);
}
if(x==s) {return true;}
//printf("%lld",s);
return NULL;
}

是不是摸鱼了……

  

7.整数反转

题目链接:https://leetcode-cn.com/problems/reverse-integer

1.思路

记得曾经在洛谷做过,回去翻了下,自己定义了个10000000长度的数组……

先记录数组长度,根据数组长度定义数组,记录各个数对应的位数,再分别乘以10的次方实现反转

2.注意事项

​ 1.先回忆了32位的有符号数的概念(有关原码、反码、补码);

​ 2.在给s赋值时,9*10^10赋值出错,单int是不行的:

​ 整型变量int占4个字节,32位,取值范围是-2^31 - 2^31-1 ,也就是(-2147483648) - (2147483647),若溢出则会循环取值,

​ 也就是2147483648溢出后回到了最小负整数-2147483648,2147483649溢出后变成了-2147483648+1=-2147483647;

详细参考:https://zhuanlan.zhihu.com/p/98674721

而对x取绝对值时,给定数据超过了限制,即int x ,改成long long int 从根源上解决问题

​ 3.再学习学习abs(),pow(),sizeof()……

3.代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int reverse(long long int x){
int zf=1;
//int x;
//scanf("%d",&x);
if(x>0) zf=1;
if(x<0) {x=(-1)*x;zf=0;}
int w=x,i=0,h=x;
while(w)
{
w/=10;
i++;
}
int sz[i+1],t=0;
long long int s=0;
for(int j=i;j>0;j--)
{
sz[j]=h%10;
h=h/10;
t=pow(10,j-1);
s=s+sz[j]*pow(10,j-1);
}
if(zf==0) s=-s;
//printf("%lld",s);
if(s>pow(2,31)-1 || s<(-1)*pow(2,31)) return 0;
else return s;
}

  

1.两数之和

题目链接:https://leetcode-cn.com/problems/two-sum/

开始回忆几乎快忘完的c语言知识,同时学java……

1.思路

双循环遍历数组;

看题解,指针没怎么学过,哈希就更不懂了,数据结构……

2.注意事项

return数组时,leetcode指定了returnSize分配return的有效内存,不赋值就return报错

3.代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int* twoSum(int* nums, int numsSize, int target, int * returnSize){
int i=0,j=0;
static int c[2]={0};
*returnSize = 2;
for(i=0;i<numsSize;i++)
{
for(j=i+1;j<numsSize;j++)
{
if(nums[i]+nums[j]==target)
{
c[0] = i;
c[1] = j;
return &c;
break;
}
}
}
//printf("%d%d\n", i,j);
return NULL;
}

一定有返回值,需要return,不然报错……

  

:D 一言句子获取中...